Keras 2D ввод в 2D вывод

Во-первых, я прочитал вопросы это и это с похожими названиями, но до сих пор не имею ответа.

Я хочу построить прямую сеть для предсказания последовательности. (Я понимаю, что для этой задачи больше подходят RNN, но у меня есть свои причины). Последовательности имеют длину 128, и каждый элемент представляет собой вектор с двумя записями, поэтому каждая партия должна иметь форму (batch_size, 128, 2), а цель - следующий шаг в последовательности, поэтому целевой тензор должен иметь форму (batch_size, 1, 2).

Сетевая архитектура примерно такая:

    model = Sequential()
    model.add(Dense(50, batch_input_shape=(None, 128, 2), kernel_initializer = "he_normal" ,activation = "relu"))
    model.add(Dense(20, kernel_initializer = "he_normal", activation = "relu"))
    model.add(Dense(5, kernel_initializer = "he_normal", activation = "relu"))
    model.add(Dense(2))

Но при тренировке получаю следующую ошибку:

ValueError: Error when checking target: expected dense_4 to have shape (128, 2) but got array with shape (1, 2)

Я пробовал такие варианты, как:

model.add(Dense(50, input_shape=(128, 2), kernel_initializer = "he_normal" ,activation = "relu"))

но получите ту же ошибку.

Я не знаю задачи, но есть несколько способов организовать nns с прямой связью с (128,2) на входе и (1,2) на выходе. Может быть, вы можете объяснить, почему вы думаете, что это последовательность из 128 векторов с двумя векторами одновременно, а не последовательность из 2 с 128 векторами одновременно?

Mehdi 06.10.2018 19:41

Поскольку это временные ряды из 128 шагов (каждый шаг представляет собой вектор с двумя элементами) каждый, и я хотел бы сохранить временную связь

H.Rappeport 06.10.2018 19:51

Кажется, вы ищете обертку для TimeDistributed, но ваш ответ меня смущает. Если есть 128 шагов по времени и 2 вектора каждый раз, какова размерность векторов? а где в вашей сети вы хотите свернуть временное измерение в 1 шаг? эти два предприятия составляют друг друга? или их нужно хранить отдельно?

Mehdi 06.10.2018 19:56

@Mehdi Спасибо, что упомянули TimeDistributed, я не был знаком с этой оболочкой. Возможно, моя формулировка была проблематичной, я имел в виду, что каждая последовательность имеет форму [[x1_1, x1_2], [x2_1, x1_2], [x2_1, x1_2], ... 124 шага ..., [x128_1, x128_2]]. а x_1 и x_2 независимы.

H.Rappeport 06.10.2018 20:26

@Mehdi @ H.Rappeport Просто примечание: как я уже упоминал в своем ответе, начиная с На последнюю ось нанесен плотный слой., нет никакой разницы между TimeDistributed(Dense(...)) и Dense(...).

today 06.10.2018 21:27
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
5
3 419
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если вы посмотрите на вывод model.summary(), вы увидите, в чем проблема:

Layer (type)                 Output Shape              Param #   
=================================================================
dense_13 (Dense)             (None, 128, 50)           150       
_________________________________________________________________
dense_14 (Dense)             (None, 128, 20)           1020      
_________________________________________________________________
dense_15 (Dense)             (None, 128, 5)            105       
_________________________________________________________________
dense_16 (Dense)             (None, 128, 2)            12        
=================================================================
Total params: 1,287
Trainable params: 1,287
Non-trainable params: 0
_________________________________________________________________

Как видите, модель выводит (None, 128,2), а не (None, 1, 2) (или (None, 2)), как вы ожидали. Итак, вы можете знать или не знать, что Плотный слой нанесен на последнюю ось входного массива., и в результате, как вы видите выше, ось времени и измерение сохраняются до конца.

Как решить эту проблему? Вы упомянули, что не хотите использовать слой RNN, поэтому у вас есть два варианта: вам нужно либо использовать слой Flatten где-нибудь в модели, либо вы также можете использовать несколько слоев Conv1D + Pooling1D или даже слой GlobalPooling. Например (это просто для демонстрации, вы можете сделать это по-другому):

с использованием слоя Flatten

model = models.Sequential()
model.add(Dense(50, batch_input_shape=(None, 128, 2), kernel_initializer = "he_normal" ,activation = "relu"))
model.add(Dense(20, kernel_initializer = "he_normal", activation = "relu"))
model.add(Dense(5, kernel_initializer = "he_normal", activation = "relu"))
model.add(Flatten())
model.add(Dense(2))

model.summary()

Краткое описание модели:

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_17 (Dense)             (None, 128, 50)           150       
_________________________________________________________________
dense_18 (Dense)             (None, 128, 20)           1020      
_________________________________________________________________
dense_19 (Dense)             (None, 128, 5)            105       
_________________________________________________________________
flatten_1 (Flatten)          (None, 640)               0         
_________________________________________________________________
dense_20 (Dense)             (None, 2)                 1282      
=================================================================
Total params: 2,557
Trainable params: 2,557
Non-trainable params: 0
_________________________________________________________________

с использованием слоя GlobalAveragePooling1D

model = models.Sequential()
model.add(Dense(50, batch_input_shape=(None, 128, 2), kernel_initializer = "he_normal" ,activation = "relu"))
model.add(Dense(20, kernel_initializer = "he_normal", activation = "relu"))
model.add(GlobalAveragePooling1D())
model.add(Dense(5, kernel_initializer = "he_normal", activation = "relu"))
model.add(Dense(2))

model.summary()

Краткое описание модели:

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_21 (Dense)             (None, 128, 50)           150       
_________________________________________________________________
dense_22 (Dense)             (None, 128, 20)           1020      
_________________________________________________________________
global_average_pooling1d_2 ( (None, 20)                0         
_________________________________________________________________
dense_23 (Dense)             (None, 5)                 105       
_________________________________________________________________
dense_24 (Dense)             (None, 2)                 12        
=================================================================
Total params: 1,287
Trainable params: 1,287
Non-trainable params: 0
_________________________________________________________________

Обратите внимание, что в обоих случаях, описанных выше, вам необходимо изменить форму массива меток (т. Е. Целей) на (n_samples, 2) (или вы можете захотеть использовать слой Reshape в конце).

Спасибо. Последующий вопрос (который, возможно, заслуживает или не заслуживает отдельного вопроса): каков эффект расположения сплющенного слоя? Будет ли какая-то разница, если он будет размещен перед первым или последним слоем?

H.Rappeport 06.10.2018 20:29

@ Х.Раппорт Конечно, есть. Это меняет связи. Как я уже упоминал в своем ответе, слой Dense применяется к последней оси и весам общие (т.е. применяются одинаковые веса). Чтобы прояснить это, взгляните на второй плотный слой в сводке моделей выше. Вы видите, что он имеет 1020 параметров: 50 параметров на каждую из этих единиц (50 * 20 = 1000), которая связана с каждой строкой (т.е. 50 элементов) на предыдущем уровне, плюс один параметр смещения на единицу (20). Теперь поместите слой Flatten перед этим слоем: количество параметров будет 128 * 50 * 20 + 20. Абсолютно другой!

today 06.10.2018 21:23

Другие вопросы по теме