Изменить форму при определении нового лямбда-слоя в Керасе - PullRequest
1 голос
/ 11 июля 2019

Я пытался реализовать слой умножения в Керасе и получал несколько ошибок, связанных с Reshape. Хотя все они решены сейчас, я все еще сомневаюсь, почему это работает. Итак, вот фрагмент кода, который я реализовал:

out2 = Dense(540, kernel_initializer='glorot_normal', activation='linear')(out2)
out2 = LeakyReLU(alpha=.2)(out2)
out2 = Reshape((9, 4, 15))(out2)
out2 = Lambda(lambda x: K.dot(K.permute_dimensions(x, (0, 2, 1, 3)), K.permute_dimensions(x, (0, 2, 3, 1))), output_shape=(4,9,9))(out2)
out2 = Dense(324, kernel_initializer='glorot_normal', activation='linear')(out2)
# K.dot should be of size (-1, 4, 9, 9), so I set output 324, and later on, reshape the ata
out2 = LeakyReLU(alpha=.2)(out2)
out2 = Reshape((-1, 4, 9, 9))(out2)
out2 = Permute((0, 2, 3, 1))(out2)

Теперь все работает нормально. Но я сделал 3 вещи, которые меня не устраивают:

  1. Раньше у меня было out2 = Reshape((-1, 9, 4, 15))(out2) вместо out2 = Reshape((9, 4, 15))(out2), и у меня была ошибка

    ValueError: Dimension must be 5 but is 4 for 'lambda_1/transpose' (op: 'Transpose') with input shapes: [?,?,9,4,15], [4].

Очевидно, я не принимал во внимание размер пакета.

  1. Теперь я попытался исправить строку out2 = Reshape((-1, 4, 9, 9))(out2) в out2 = Reshape((4, 9, 9))(out2), используя ту же концепцию, но затем выдает ошибку

    ValueError: total size of new array must be unchanged

Я не понимаю несоответствия.

  1. Наконец, мне было интересно, если удаление output_shape=(4,9,9) сделает что-то неправильное с кодом.

1 Ответ

1 голос
/ 11 июля 2019

Что касается проблем с размером пакета, Keras автоматически его обрабатывает.Это просто конвекция, что слои представляют функцию, которая будет применена к партии, и задача Keras - применить такую ​​функцию к каждой партии, которой питается модель.Поэтому, в основном, вы должны игнорировать размер пакета при определении слоев.

Кроме того, слой Dense работает не так, как вы ожидаете.Он применяется к последнему измерению его ввода.Если вы хотите обрабатывать ваши данные с этого момента как обычный MLP, вы можете использовать Flatten() до Dense, как если бы вы использовали CNN, который заканчивается обычными полностью связанными слоями (конечно, вы можете изменить их после).

Подводя итог, вы можете сделать что-то вроде:

out2 = Dense(540, kernel_initializer='glorot_normal', activation='linear')(out2)
out2 = LeakyReLU(alpha=.2)(out2)
out2 = Reshape((9, 4, 15))(out2)
out2 = Lambda(lambda x: K.dot(K.permute_dimensions(x, (0, 2, 1, 3)), K.permute_dimensions(x, (0, 2, 3, 1))), output_shape=(4,9,9))(out2)
out2 = Flatten()(out2)
out2 = Dense(324, kernel_initializer='glorot_normal', activation='linear')(out2)
out2 = LeakyReLU(alpha=.2)(out2)
out2 = Reshape((4, 9, 9))(out2)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...