代码之家  ›  专栏  ›  技术社区  ›  Nicolas M.

嵌入式RNN与KERS-问题与连接

  •  -1
  • Nicolas M.  · 技术社区  · 6 年前

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

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

    enter image description here

    在下面的代码中,我有一个关于concatenate维度的问题。输入 iX 为(无,30,84),输出为(无,32)。在轴0上连接之后,我想要一个(无,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不兼容。

    值错误:输入0与层cu_dnnlstm_13不兼容:预期的ndim=3,找到的ndim=2

    第二件事,有没有一种方法来训练一个同样的模型? 细胞 “第一层。例如,在图像上,我希望 红细胞=蓝细胞=黄细胞=绿细胞 在…方面 单元格状态 . 这是因为我想要一个给定声音的时不变输出。0秒时的特定声音在10秒时的相同声音时应具有相同的输出。但现在的情况是,基于 单元格状态 .

    如果这在喀拉斯不可能,有什么方法可以用TensorFlow来实现吗?

    非常感谢您的支持,

    尼古拉斯

    1 回复  |  直到 6 年前
        1
  •  1
  •   benjaminplanche    6 年前

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

    使用 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()
    

    我不太清楚你的意思。问题…为您的第一次分享体重 CuDNNLSTM 分层(见 Shared Layers )?

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

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