Python 用Conv1D替换密集自动编码器中的一层

Python 用Conv1D替换密集自动编码器中的一层,python,machine-learning,keras,Python,Machine Learning,Keras,我目前在keras中有一个完全连接的自动编码器,如下所示: model.add(Dense(4096, input_shape=(4096,), activation='relu')) model.add(Dense(512, activation='relu')) model.add(Dense(64, activation='relu')) model.add(Dense(512, activation='relu')) model.add(Dense(4096, activation='r

我目前在keras中有一个完全连接的自动编码器,如下所示:

model.add(Dense(4096, input_shape=(4096,), activation='relu'))
model.add(Dense(512, activation='relu'))
model.add(Dense(64, activation='relu'))
model.add(Dense(512, activation='relu'))
model.add(Dense(4096, activation='relu'))
model = Sequential()
model.add(Dense(4096, input_shape=(4096,), activation='relu'))
model.add(Conv1D(512,3, activation='relu'))
model.add(Dense(64, activation='relu'))
model.add(Conv1D(512,3, activation='relu'))
model.add(Dense(4096, activation='relu'))
数据由时间序列数据组成,这些数据通过FFT转换为频域

我的训练数据的形状如下:(8000,4096),其中我有8000个样本,4096个样本代表频率。这个模型很好用

我试图实现的是用Conv1d替换两个有512个单元的密集层,看看这是否会改善我的结果,类似这样:

model.add(Dense(4096, input_shape=(4096,), activation='relu'))
model.add(Dense(512, activation='relu'))
model.add(Dense(64, activation='relu'))
model.add(Dense(512, activation='relu'))
model.add(Dense(4096, activation='relu'))
model = Sequential()
model.add(Dense(4096, input_shape=(4096,), activation='relu'))
model.add(Conv1D(512,3, activation='relu'))
model.add(Dense(64, activation='relu'))
model.add(Conv1D(512,3, activation='relu'))
model.add(Dense(4096, activation='relu'))
现在,这不起作用,因为Conv1D希望我的数据有3个维度:

Input 0 is incompatible with layer conv1d_12: expected ndim=3, found ndim=2
如何确保Conv1d层获得正确的输入形状

  • 使用模型。是否可能添加(重塑(?,?)
  • 以某种方式将我的输入数据重塑为三维
  • 我曾尝试将输入形状更改为“强制”第三维度,并在第一个密集层和第一个Conv1D层之间进行重塑,但这似乎不起作用

    我意识到这里有很多关于Conv1D网络输入形状的问题,但请注意,我不希望卷积滤波器跨越多个样本,只跨越频率值

    提前谢谢

    更新:按照daniels的建议,我能够编译模型并开始训练(尽管我的GPU对我大喊大叫)

    但是,我希望我的Conv1d层具有以下输出形状:

    conv1d_71 (Conv1D)           (None, 512, 1)
    
    我是在错误的维度上做卷积吗?如果是这样,我该如何改变这种情况?或者我是否误解了卷积层的工作原理?

    方法1-在密集层中保持长度 这对于自动编码器来说不是很有用,因为它不会真正压缩数据,因为4096的长度仍然存在

    这应该是自动工作,但似乎你有一个旧的keras版本

    正如您所做的那样,在第一次卷积之前,像
    (4096,1)
    一样对其进行重塑。
    然后,
    密集的
    层应该可以正常工作。如果没有,请使用
    时间分布(密集(…)

    考虑在卷积中使用
    padding='same'
    ,以方便使用

    最后一层应该是类似于
    Conv1D(1,…)
    的层,而不是
    密集的层。
    最后用
    (4096,)
    进行重塑

    方法2-不要保持长度 在第一次转换后,您应该对其进行重塑以删除三维尺寸标注,但请注意:

    • 频道:512
    • 长度:
      • 如果使用
        padding='same'
        :4096
      • 其他:4094
    然后您应该重新调整为
    (4096*512,)
    ,这相当大,将显著增加模型中可训练参数的数量

    在下一次转换之前,再次转换为
    (64,1)
    ,然后再转换为
    (64*512),
    (如果不使用填充,则转换为62)


    您可以探索这些方法的组合。始终记住,如果使用最新的keras版本,CONV将作为
    (批次、长度、通道)
    ,DENSE将作为
    (批次,…任何…,单位)
    。如果没有,你必须正确地处理这个
    …不管什么…

    将你的输入重塑为3D:
    模型。添加(重塑(重塑(输入形状=(4096,),目标形状=(4096,1))
    谢谢Primusa,但是你在这里显示的cod不会给出2D输出吗?e、 g目标形状必须是(4096,1,)或可能是(4096,1,1)?不管怎样,我试着让你知道Keras推断第一维度为批量大小,你真的在重塑(批量大小,4096,1)@Primusa啊,我明白了,那么这是有意义的。您会在哪里添加此方法?在第一次conv1d之前,我尝试了重塑,但随后致密层出现了尺寸误差,我似乎不允许在第一次conv1d之后改变形状。(数组的新大小必须相同)第一层,这就是为什么要指定input_形状。在输出过程中,您可能需要将其重新调整为2D输入Hank’s,以获得您的完整答案Daniel。我现在正试着把我的头绕在这上面,对我来说,好像我在错误的轴上应用了卷积滤波器。我可能误解了卷积网络的工作原理,我将用一些额外的信息更新我原来的问题。