首页 文章

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

提问于
浏览
0

我目前在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

    方法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... .

相关问题