【问题标题】:Embedded-RNN with Keras - Issue with Concatenate带有 Keras 的嵌入式 RNN - 连接问题
【发布时间】:2018-05-27 18:55:34
【问题描述】:

对于音频分类,我想尝试一种嵌入式 RNN。基于 MFCC 或 30 秒样本的 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 in compatible with layer cu_dnnlstm_13: expected ndim=3, found ndim=2

第二件事,有没有办法为第一层训练具有相同“cell”的模型。例如在图像上,我想在 cell state 方面有 red cells = blue cells = yellow cells = green cells。这是因为我想要给定声音的时不变输出。 0 秒时的特定声音在 10 秒时应具有相同的输出。但就像现在一样,输出会根据每个Cell State而有所不同。

如果这在 Keras 中是不可能的,有没有办法用 tensorflow 做到这一点?

非常感谢您的支持,

尼古拉斯

【问题讨论】:

    标签: machine-learning neural-network keras recurrent-neural-network


    【解决方案1】:

    关于您的错误,您似乎想要堆叠您的张量(沿新维度连接/堆叠张量),而不是连接它们(沿现有维度连接张量)。

    使用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]
    

    【讨论】:

    • 太棒了 :) 非常感谢!此外,共享 LSTM 将微调的参数数量从 30 x 15104 减少到只有 15104(我没有事先考虑过)。
    猜你喜欢
    • 2019-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-19
    • 1970-01-01
    • 2012-02-11
    • 1970-01-01
    • 2018-03-21
    相关资源
    最近更新 更多