带 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]
对于音频分类,我想尝试一种嵌入式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]