带 Keras 的嵌入式 RNN - 连接问题

Embedded-RNN with Keras - Issue with Concatenate

对于音频分类,我想尝试一种嵌入式RNN。基于 30 秒样本的 MFCC 或 FFT,我想为每个 1s 子样本创建第一个输出,然后使用 30 个输出将其发送到另一个 RNN 以获得最终预测。这个想法是通过将问题分成多个部分来解决梯度消失问题(也欢迎您对这个想法提出意见,它来自我在 Wavenet 上看到的可视化)。

这是模型的表示,每个级别只有 4 个时间步长和 1 层 LSTM:

在下面的代码中,我对 Concatenate 的维度有疑问。输入 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 30

input_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 format
f = concatenate(first_layer, axis=0)   # Functional API version

o1 = 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

第二,有没有一种方法可以训练第一层具有相同“cell”的模型。例如在图像上,我希望 红色细胞 = 蓝色细胞 = 黄色细胞 = 绿色细胞 根据 细胞状态 。这是因为我想要给定声音的时间不变输出。 0 秒时的特定声音在 10 秒时应具有相同声音的相同输出。但就像现在一样,输出将根据每个 Cell State.

而不同

如果这在 Keras 中不可行,是否有使用 tensorflow 实现的方法?

非常感谢您的支持,

尼古拉斯

关于你的错误,你似乎想堆叠你的张量(concatenating/stacking张量沿着一个新的维度),而不是连接 它们(沿现有维度连接张量)。

使用K.stack()

import keras.backend as K
from keras.models import Model
from keras.layers import Lambda, Input, CuDNNLSTM, Dense
import numpy as np

# Demonstrating K.stack() on simple tensors:
list_l = [K.variable(np.random.rand(32)) for i in range(30)]
f = K.stack(list_l, axis=0)
print(f)
# > Tensor("stack:0", shape=(30, 32), dtype=float32)

# Actual usage, in your model:
input_layer = [Input(shape=(30, 84)) for n in range(30)]
first_layer = [CuDNNLSTM(units=32, return_sequences=False)(i) for i in input_layer]
f = Lambda(lambda tensors: K.stack(tensors, axis=1))(first_layer)
print(f)
# > Tensor("lambda_1/stack:0", shape=(?, 30, 32), dtype=float32)

o1 = CuDNNLSTM(units=32, return_sequences=False)(f)
outputs = Dense(16, activation='softmax') (o1)
model = Model(inputs=input_layer, outputs=outputs)
model.summary()

我不太清楚你在 sup 中的意思。问题...也许您的第一个 CuDNNLSTM 层的权重共享(请参阅 Shared Layers 上的文档)?

如果是这样,您可以将第一层定义为:

cudnn_lstm_first = CuDNNLSTM(units=32, return_sequences=False)
first_layer = [cudnn_lstm_first(i) for i in input_layer]