Keras 2D вход в 2D выход - PullRequest
       21

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

0 голосов
/ 06 октября 2018

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

Я хочу построить сеть прямой связидля прогнозирования последовательности.(Я понимаю, что RNN больше подходят для этой задачи, но у меня есть свои причины).Последовательности имеют длину 128, и каждый элемент представляет собой вектор с 2 записями, поэтому каждая партия должна иметь форму (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"))

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

1 Ответ

0 голосов
/ 06 октября 2018

Если вы посмотрите на вывод 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 layer

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 layer

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 в конце).

...