конвертировать лазанью в код Keras (CNN -> LSTM) - PullRequest
0 голосов
/ 04 ноября 2018

Я хотел бы преобразовать этот код лазаньи:

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 голосов
/ 07 ноября 2018

Решение

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)

Пояснения

Я поместил здесь документы Лазаньи и Кераса, чтобы вы могли делать перекрестные ссылки:

Лазанья

Повторяющиеся слои можно использовать аналогично слоям с прямой связью, кроме ожидается, что входная форма будет (batch_size, sequence_length, num_inputs)

Keras

Форма ввода

3D тензор с формой (batch_size, timesteps, input_dim).


По сути, API-интерфейс такой же, но Lasagne, вероятно, действительно меняет форму для вас (мне нужно проверить исходный код позже). Вот почему вы получили эту ошибку:

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

, поскольку тензорная форма после Conv2D составляет (?, 64, 20, 113) из ndim=4

Поэтому решение состоит в том, чтобы изменить его на (?, 20, 7232).

Редактировать

Подтверждено с помощью исходного кода лазаньи , он поможет вам:

num_inputs = np.prod(input_shape[2:])

Таким образом, правильная форма тензора в качестве входных данных для LSTM равна (?, 20, 64 * 113) = (?, 20, 7232)


Примечание

Permute избыточен здесь, в Керасе, так как вы все равно должны изменить свою форму. Причина, по которой я поместил это здесь, состоит в том, чтобы иметь «полный перевод» от лазаньи к керасу, и он делает то, что DimshuffleLaye делает в лазаньи.

DimshuffleLaye, тем не менее, необходимо в Lasagne, по причине, которую я упомянул в Edit , новое измерение, созданное Lasagne LSTM, является результатом умножения «последних двух» измерений.

...