将千层面转换为Keras代码(CNN-> LSTM)

时间:2018-11-04 19:48:57

标签: python keras lstm lasagne

我想转换这个千层面代码:

et = {}
net['input'] = lasagne.layers.InputLayer((100, 1, 24, 113))
net['conv1/5x1'] = lasagne.layers.Conv2DLayer(net['input'], 64, (5, 1))
net['shuff'] = lasagne.layers.DimshuffleLayer(net['conv1/5x1'], (0, 2, 1, 3))
net['lstm1'] = lasagne.layers.LSTMLayer(net['shuff'], 128)
在Keras代码中为

。目前,我想到了这个:

multi_input = Input(shape=(1, 24, 113), name='multi_input')
y = Conv2D(64, (5, 1), activation='relu', data_format='channels_first')(multi_input)
y = LSTM(128)(y)

但是我得到了错误:Input 0 is incompatible with layer lstm_1: expected ndim=3, found ndim=4

1 个答案:

答案 0 :(得分:1)

解决方案

from keras.layers import Input, Conv2D, LSTM, Permute, Reshape

multi_input = Input(shape=(1, 24, 113), name='multi_input')
print(multi_input.shape)  # (?, 1, 24, 113)

y = Conv2D(64, (5, 1), activation='relu', data_format='channels_first')(multi_input)
print(y.shape)  # (?, 64, 20, 113)

y = Permute((2, 1, 3))(y)
print(y.shape)  # (?, 20, 64, 113)

# This line is what you missed
# ==================================================================
y = Reshape((int(y.shape[1]), int(y.shape[2]) * int(y.shape[3])))(y)
# ==================================================================
print(y.shape)  # (?, 20, 7232)

y = LSTM(128)(y)
print(y.shape)  # (?, 128)

说明

我将千层面和Keras的文档放在此处,以便您可以交叉引用:

library

  

除了前馈层外,其他层都可以类似地使用   输入形状应为(batch_size, sequence_length, num_inputs)

Lasagne

  

输入形状

     

形状为(batch_size, timesteps, input_dim)的3D张量。


基本上,API是相同的,但是Lasagne可能会为您重塑形状(我稍后需要检查源代码)。这就是为什么出现此错误的原因:

Input 0 is incompatible with layer lstm_1: expected ndim=3, found ndim=4

,因为Conv2D之后的张量形状为(?, 64, 20, 113)的{​​{1}}

因此,解决方案是将其重塑为ndim=4

编辑

与千层面Keras确认,它可以为您解决问题:

(?, 20, 7232)

因此,作为LSTM输入的正确张量形状为num_inputs = np.prod(input_shape[2:]) = (?, 20, 64 * 113)


注意

(?, 20, 7232)在Keras中是多余的,因为无论如何您都必须重塑形状。我将其放置在这里的原因是要从“千层面”到“凯拉斯”进行“完整翻译”,它的作用与Permute在千层面中的作用相同。

但是,由于我在 Edit 中提到的原因,在Lasagne中需要

DimshuffleLaye,而Lasagne LSTM创建的新尺寸来自“最后两个”尺寸的乘积。