我目前在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图层获得正确的输入形状?
-
可能使用Model.add(重塑(?,?,?))?
-
重塑我的输入数据,以某种方式有3个维度?
我已经尝试将输入形状更改为“强制”第三维,并在第一个Dense图层和第一个Conv1D图层之间重新塑造,但这似乎不起作用 .
我意识到这里有很多关于Conv1D网络输入形状的问题,但请注意,我不希望卷积滤波器跨越多个样本,只能跨越频率值 .
提前致谢 .
更新:遵循daniels建议我能够编译模型并开始训练(尽管我的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)
我在错误的维度上进行卷积吗?如果是这样,我怎么能改变它?或者我误解了卷积层是如何工作的?
1 回答
方法1 - 保持密集层的长度
这对于自动编码器来说不是很有用,因为它不会真正压缩你的数据,因为4096的长度仍然存在 .
这应该是自动工作,但似乎你有一个旧的keras版本 .
正如您所做的那样,在第一次卷积之前将其重塑为
(4096,1)
.那么
Dense
层应该可以正常工作 . 如果没有,请使用TimeDistributed(Dense(...))
考虑在回合中使用
padding='same'
以便于使用 .最后一层应该是
Conv1D(1,...)
而不是Dense
. 最后重塑(4096,)
.方法2 - 不要保持长度
在第一个转化之后,您应该重塑它以删除3D尺寸,但请注意您:
Channels :512
长度:
如果使用
padding='same'
:4096其他:4094
然后你应该重塑到
(4096*512,)
,这是相当大的,并将显着增加模型中可训练的参数的数量 .在下一个转发之前,再次转到
(64,1)
,然后转到(64*512,)
(如果不使用填充则为62) .你可以探索这些的混合 . 永远记住,如果使用最近的keras版本,转换将作为
(batch, length, channels)
工作,而denses将作为(batch, ...whatever..., units)
工作 . 如果不是,你必须妥善处理这个...whatever...
.