我目前在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'))
数据由定时器序列数据组成,这些数据通过FFT转换为频域。
我的训练数据具有以下形状:(8000,4096),其中我有8000个样本,而4096个样本代表频率。这个模型工作正常。
我想要实现的是用Conv1d替换具有512个单位的两个密集层,以查看这是否可以改善我的结果,像这样:
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图层获得正确的输入形状?
我尝试将输入形状更改为“强制”第三维,然后在第一个Dense层和第一个Conv1D层之间重塑形状,但这似乎不起作用。
我意识到这里有很多关于Conv1D网络输入形状的问题,但是请注意,我不希望卷积滤波器跨越多个样本,而只是跨越频率值。
谢谢。
更新:在丹尼尔斯的建议下,我能够编译模型并开始训练(尽管我的GPU在向我尖叫)
Layer (type) Output Shape Param #
=================================================================
dense_132 (Dense) (None, 4096) 16781312
_________________________________________________________________
reshape_85 (Reshape) (None, 4096, 1) 0
_________________________________________________________________
conv1d_71 (Conv1D) (None, 4096, 512) 2048
_________________________________________________________________
reshape_86 (Reshape) (None, 2097152) 0
_________________________________________________________________
dense_133 (Dense) (None, 64) 134217792
_________________________________________________________________
reshape_87 (Reshape) (None, 64, 1) 0
_________________________________________________________________
conv1d_72 (Conv1D) (None, 64, 512) 2048
_________________________________________________________________
reshape_88 (Reshape) (None, 32768) 0
_________________________________________________________________
dense_134 (Dense) (None, 4096) 134221824
=================================================================
Total params: 285,225,024
Trainable params: 285,225,024
Non-trainable params: 0
_________________________________________________________________
但是,我希望我的Conv1d图层具有以下输出形状:
conv1d_71 (Conv1D) (None, 512, 1)
我是在错误尺寸上进行卷积吗?如果是这样,我该如何更改呢?还是我误解了卷积层的工作原理?
答案 0 :(得分:1)
这对于作为自动编码器来说不是很有用,因为它不会真正压缩数据,因为长度仍然为4096。
这应该是自动运行的,但是您似乎有一个旧的keras版本。
与您一样,在第一次卷积之前将其重塑为(4096,1)
。
然后Dense
层应该可以正常工作。如果没有,请使用TimeDistributed(Dense(...))
为简便起见,请考虑在卷积中使用padding='same'
。
最后一层应类似于Conv1D(1,...)
,而不是Dense
。
最后用(4096,)
重塑。
第一次转换后,您应该对其进行重塑以删除3D尺寸,但是请注意,您已经:
padding='same'
:4096 然后,您应该将其重塑为(4096*512,)
,这相当大,并且将大大增加模型中可训练参数的数量。
在下一次转换之前,再次到达(64,1)
,然后到(64*512,)
(如果不使用填充则为62)。
您可以探索其中的混合。始终记住,如果使用最新的keras版本,则conv会像(batch, length, channels)
一样工作,dens会像(batch, ...whatever..., units)
一样工作。否则,您必须正确处理此...whatever...
。