Как соединить две модели LSTM в Керасе - PullRequest
1 голос
/ 26 июня 2019

Я хочу создать модель с двумя слоями LSTM с помощью Keras.Однако следующий код генерирует ошибку:

from keras.models import Sequential
from keras.layers import LSTM, Dropout, Activation
from keras.callbacks import ModelCheckpoint
from keras.utils import to_categorical

model = Sequential()
model.add(LSTM(5, activation="softmax"))
model.add(LSTM(5, activation="softmax"))

model.compile(loss='categorical_crossentropy', 
              optimizer='adam', 
              metrics=['categorical_accuracy'])

# These values are to be predicted.
directions = [-2, -1, 0, 1, 2]

# Sample data. We have three time steps, one 
# feature per timestep, and one resulting value.
data = [[[[1], [2], [3]], -1], 
        [[[3], [2], [1]], 2], 
        [[[4], [5], [7]], 1],
        [[[1], [-1], [10]], -2]]

X = []
y_ = []

# Now we take 10000 samples from the data above.
for i in np.random.choice(len(data), 10000):
    X.append(data[i][0])
    y_.append(data[i][1])

X = np.array(X)
y_ = np.array(y_)
y = to_categorical(y_ + 2, num_classes=5)

model.fit(X, y, 
          epochs=3,
          validation_data=(X, y))
print(model.summary())

loss, acc = model.evaluate(X, y)

print("Loss: {:.2f}".format(loss))
print("Accuracy: {:.2f}%".format(acc*100))

Я получаю следующую ошибку:

ValueError: Input 0 is incompatible with layer lstm_10: expected ndim=3, found ndim=2

Полный возврат трассировки:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-35-58fa9218c3f3> in <module>
     31 model.fit(X, y, 
     32           epochs=3,
---> 33           validation_data=(X, y))
     34 print(model.summary())
     35 

C:\Anaconda3\lib\site-packages\keras\engine\training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, **kwargs)
    950             sample_weight=sample_weight,
    951             class_weight=class_weight,
--> 952             batch_size=batch_size)
    953         # Prepare validation data.
    954         do_validation = False

C:\Anaconda3\lib\site-packages\keras\engine\training.py in _standardize_user_data(self, x, y, sample_weight, class_weight, check_array_lengths, batch_size)
    675             # to match the value shapes.
    676             if not self.inputs:
--> 677                 self._set_inputs(x)
    678 
    679         if y is not None:

C:\Anaconda3\lib\site-packages\keras\engine\training.py in _set_inputs(self, inputs, outputs, training)
    587                 assert len(inputs) == 1
    588                 inputs = inputs[0]
--> 589             self.build(input_shape=(None,) + inputs.shape[1:])
    590             return
    591 

C:\Anaconda3\lib\site-packages\keras\engine\sequential.py in build(self, input_shape)
    219             self.inputs = [x]
    220             for layer in self._layers:
--> 221                 x = layer(x)
    222             self.outputs = [x]
    223             self._build_input_shape = input_shape

C:\Anaconda3\lib\site-packages\keras\layers\recurrent.py in __call__(self, inputs, initial_state, constants, **kwargs)
    530 
    531         if initial_state is None and constants is None:
--> 532             return super(RNN, self).__call__(inputs, **kwargs)
    533 
    534         # If any of `initial_state` or `constants` are specified and are Keras

C:\Anaconda3\lib\site-packages\keras\engine\base_layer.py in __call__(self, inputs, **kwargs)
    412                 # Raise exceptions in case the input is not compatible
    413                 # with the input_spec specified in the layer constructor.
--> 414                 self.assert_input_compatibility(inputs)
    415 
    416                 # Collect input shapes to build layer.

C:\Anaconda3\lib\site-packages\keras\engine\base_layer.py in assert_input_compatibility(self, inputs)
    309                                      self.name + ': expected ndim=' +
    310                                      str(spec.ndim) + ', found ndim=' +
--> 311                                      str(K.ndim(x)))
    312             if spec.max_ndim is not None:
    313                 ndim = K.ndim(x)

ValueError: Input 0 is incompatible with layer lstm_10: expected ndim=3, found ndim=2

Кажется, чтоРазмеры выходных данных первого слоя LSTM (предположительно, dim = 2) не совпадают с требуемыми входными размерами второго слоя LSTM (dim = 3 для пакета, временных шагов, элементов).

Какие ошибкимне кажется, что добавление слоев LSTM вместе, как я это сделал, похоже, работает здесь, например: https://adventuresinmachinelearning.com/keras-lstm-tutorial/

Модель работает, когда я удаляю второй слой LSTM.

1 Ответ

3 голосов
/ 26 июня 2019

По умолчанию LSTM возвращает свой окончательный результат только после последнего элемента последовательности.Если вы хотите соединить два воедино, то вам нужно передать выходные данные после каждого элемента последовательности от первого LSTM ко второму.например,

model = Sequential()
model.add(LSTM(5, return_sequences=True))
model.add(LSTM(5, activation="softmax"))

См. документы для получения подробной информации о том, как работает return_sequence https://keras.io/layers/recurrent/

...