为了进行音频分类,我想尝试一种嵌入式RNN。基于30秒样本的MFCC或FFT,我希望为每1秒的子样本创建一个初步输出,然后将这30个输出发送到另一个RNN以获得最终预测。这样做的目的是通过将问题分成多部分来对抗梯度消失问题(关于这个想法我也很欢迎您的意见,这个想法来自我看到的Wavenet的可视化)。
这是仅有4个时间步和每层一个LSTM层的模型的表示:
在下面的代码中,我遇到了连接操作的维度问题。输入iX
是(None, 30, 84),输出是(None, 32)。在轴0上连接后,我希望得到(None, 30, 32)的形状。
i1 = Input((30, 84))l1 = CuDNNLSTM(units=32, return_sequences=False) (i1)i2 = Input((30, 84))l2 = CuDNNLSTM(units=32, return_sequences=False) (i2)i3 = Input((30, 84))l3 = CuDNNLSTM(units=32, return_sequences=False) (i3)i4 = Input((30, 84))l4 = CuDNNLSTM(units=32, return_sequences=False) (i4)i5 = Input((30, 84))l5 = CuDNNLSTM(units=32, return_sequences=False) (i5)i6 = Input((30, 84))l6 = CuDNNLSTM(units=32, return_sequences=False) (i6)i7 = Input((30, 84))l7 = CuDNNLSTM(units=32, return_sequences=False) (i7)i8 = Input((30, 84))l8 = CuDNNLSTM(units=32, return_sequences=False) (i8)i9 = Input((30, 84))l9 = CuDNNLSTM(units=32, return_sequences=False) (i9)i10 = Input((30, 84))l10 = CuDNNLSTM(units=32, return_sequences=False) (i10)i11 = Input((30, 84))l11 = CuDNNLSTM(units=32, return_sequences=False) (i11)i12 = Input((30, 84))l12 = CuDNNLSTM(units=32, return_sequences=False) (i12)# ... up to 30input_layer = [i1, i2, i3, i4, i5, i6 ,i7, i8, i9, i10, i11, i12]first_layer = [l1, l2, l3, l4, l5, l6 ,l7, l8, l9, l10, l11, l12]# f = Concatenate(axis=0)(first_layer) # Sequential formatf = concatenate(first_layer, axis=0) # Functional API versiono1 = CuDNNLSTM(units=32, return_sequences=False) (f)outputs = Dense(16, activation='softmax') (o1)model = Model(inputs=input_layer, outputs=outputs)model.summary()
错误是合理的,因为(None, 32)的形状与LSTM不兼容。
ValueError: Input 0 is incompatible with layer cu_dnnlstm_13: expected ndim=3, found ndim=2
第二件事,是否有办法使用相同的“单元”来训练第一层的模型。例如,在图像上,我希望在单元状态方面,红色单元 = 蓝色单元 = 黄色单元 = 绿色单元。这是因为我希望对于给定的声音输出是时间不变的。特定声音在0秒时的输出应该与在10秒时相同的声音输出相同。但现在的情况是,输出会根据每个单元状态而有所不同。
如果在Keras中无法实现这一点,那么是否有办法使用tensorflow来实现呢?
非常感谢您的支持,
Nicolas
回答:
关于您的错误,看起来您想要堆叠您的张量(沿着新维度堆叠/连接张量),而不是连接它们(沿着现有维度连接张量)。
使用K.stack()
:
我不是很清楚您在补充问题中所指的意思… 可能是您的第一个CuDNNLSTM
层共享权重(请参阅关于共享层的文档)?
如果是的话,您可以这样定义您的第一层:
cudnn_lstm_first = CuDNNLSTM(units=32, return_sequences=False)first_layer = [cudnn_lstm_first(i) for i in input_layer]