将烤宽面条转换为 Keras 代码(CNN -> LSTM)
convert Lasagne to Keras code (CNN -> LSTM)
我想转换这个烤宽面条代码:
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
解决方案
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)
解释
我把Lasagne和Keras的文档放在这里,大家可以对照一下:
Recurrent layers can be used similarly to feed-forward layers except
that the input shape is expected to be (batch_size, sequence_length, num_inputs)
Input shape
3D tensor with shape (batch_size, timesteps, input_dim)
.
基本上API是一样的,但是Lasagne可能会为你整形(我需要稍后查看源代码)。这就是您收到此错误的原因:
Input 0 is incompatible with layer lstm_1: expected ndim=3, found ndim=4
,因为Conv2D
之后的张量形状是ndim=4
的(?, 64, 20, 113)
因此,解决方案是将其重塑为(?, 20, 7232)
。
编辑
确认千层面source code,它对你有用:
num_inputs = np.prod(input_shape[2:])
所以作为 LSTM 输入的正确张量形状是 (?, 20, 64 * 113)
= (?, 20, 7232)
备注
Permute
在 Keras 中是多余的,因为无论如何你都必须重塑。我把它放在这里的原因是从 Lasagne 到 Keras 有一个 "full translation",它做 DimshuffleLaye
在 Lasagne 做的事情。
DimshuffleLaye
然而在 Lasagne 中是需要的,因为我在 Edit 中提到的原因,Lasagne LSTM 创建的新维度来自 [=62= 的乘积] 尺寸。
我想转换这个烤宽面条代码:
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
解决方案
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)
解释
我把Lasagne和Keras的文档放在这里,大家可以对照一下:
Recurrent layers can be used similarly to feed-forward layers except that the input shape is expected to be
(batch_size, sequence_length, num_inputs)
Input shape
3D tensor with shape
(batch_size, timesteps, input_dim)
.
基本上API是一样的,但是Lasagne可能会为你整形(我需要稍后查看源代码)。这就是您收到此错误的原因:
Input 0 is incompatible with layer lstm_1: expected ndim=3, found ndim=4
,因为Conv2D
之后的张量形状是ndim=4
的(?, 64, 20, 113)
因此,解决方案是将其重塑为(?, 20, 7232)
。
编辑
确认千层面source code,它对你有用:
num_inputs = np.prod(input_shape[2:])
所以作为 LSTM 输入的正确张量形状是 (?, 20, 64 * 113)
= (?, 20, 7232)
备注
Permute
在 Keras 中是多余的,因为无论如何你都必须重塑。我把它放在这里的原因是从 Lasagne 到 Keras 有一个 "full translation",它做 DimshuffleLaye
在 Lasagne 做的事情。
DimshuffleLaye
然而在 Lasagne 中是需要的,因为我在 Edit 中提到的原因,Lasagne LSTM 创建的新维度来自 [=62= 的乘积] 尺寸。