Keras CNN-LSTM: ошибка при создании y_train - PullRequest
0 голосов
/ 29 октября 2019

Я впервые задаю вопрос здесь (это значит, что мне действительно нужна помощь) и прошу прощения за мой плохой английский. Я хочу создать слой cnn-lstm для классификации видео в Keras, но у меня проблема с созданием y_train. Я опишу мою проблему после этого. У меня есть набор данных видео (1 видео имеет 10 кадров), и я преобразовал видео в изображения. Сначала я разделил набор данных на xtrain, xtest, ytrain и ytest (20% тест, 80% поезд) и сделал это.

X_train, X_test = img_data[:trainco], img_data[trainco:]
y_train, y_test = y[:trainco], y[trainco:]

Форма X_train: (2280, 64, 64, 1) -> У меня 2280 изображений, высота 64x64, высота x, 1 канал

форма y_train: (2280, 26) -> 26 классов

И затем я должен изменить их, прежде чем войти в процесс cnn-lstm,* примечание: я делаю то же самое с x_test и y_test

time_steps = 10 (because I have 10 frames per video)

X_train = X_train.reshape(int(X_train.shape[0] / time_steps), time_steps, X_train.shape[1], X_train.shape[2], X_train.shape[3])
y_train = y_train.reshape(int(y_train.shape[0] / time_steps), time_steps, y_train.shape[1])

Форма X_train: (228, 10, 64, 64, 1), форма y_train: (228, 10, 26)

И тогда это моя модель:

model = Sequential()
model.add(TimeDistributed(Conv2D(32, (3, 3), strides=(2, 2), activation='relu', padding='same'), input_shape=X_train.shape[1:]))
model.add(TimeDistributed(MaxPooling2D((2, 2), strides=(2, 2))))
model.add(TimeDistributed(Conv2D(32, (3, 3), padding='same', activation='relu')))
model.add(TimeDistributed(MaxPooling2D((2, 2), strides=(2, 2))))
model.add(TimeDistributed(Flatten()))
model.add(LSTM(256, return_sequences=False, input_shape=(64, 64)))
model.add(Dense(128))
model.add(Dense(64))
model.add(Dense(num_classes, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=["accuracy"])
checkpoint = ModelCheckpoint(fname, monitor='acc', verbose=1, save_best_only=True, mode='max', save_weights_only=True)
hist = model.fit(X_train, y_train, batch_size=num_batch, nb_epoch=num_epoch, verbose=1, validation_data=(X_test, y_test), callbacks=[checkpoint])

Но я получил ошибку, которая гласит:

ValueError: Error when checking target: expected dense_3 to have 2 dimensions, but got array with shape (228, 10, 26)

Как будто сказано, что ожидается 2 измерения. Я изменил код на

y_train = y_train.reshape(int(y_train.shape[0] / time_steps), y_train.shape[1])

И снова получил ошибку, которая говорит

ValueError: cannot reshape array of size 59280 into shape (228,26)

И затем я снова изменил код на

y_train = y_train.reshape(y_train.shape[0], y_train.shape[1])

И явсе еще есть ошибка

ValueError: Input arrays should have the same number of samples as target arrays. Found 228 input samples and 2280 target samples.

Что мне делать? Я знаю проблему, но не знаю, как ее решить. Пожалуйста, помогите мне.

1 Ответ

0 голосов
/ 29 октября 2019

Я воссоздал слегка упрощенную версию вашей ситуации, чтобы воспроизвести проблему. По сути, кажется, что слой LSTM выводит только один результат для всей последовательности временных шагов, тем самым уменьшая размерность с 3 до 2 в выходных данных. Если вы запустите мою программу ниже, я добавлю модель.summary (), которая предоставляет подробную информацию об архитектуре.

from keras import Sequential
from keras.layers import TimeDistributed, Dense, Conv2D, MaxPooling2D, Flatten, LSTM
import numpy as np

X_train = np.random.random((228, 10, 64, 64, 1))
y_train = np.random.randint(2, size=(228, 10, 26))
num_classes = 26

# Create the model
model = Sequential()
model.add(TimeDistributed(Conv2D(32, (3, 3), strides=(2, 2), activation='relu', padding='same'), input_shape=X_train.shape[1:]))
model.add(TimeDistributed(MaxPooling2D((2, 2), strides=(2, 2))))
model.add(TimeDistributed(Conv2D(32, (3, 3), padding='same', activation='relu')))
model.add(TimeDistributed(MaxPooling2D((2, 2), strides=(2, 2))))
model.add(TimeDistributed(Flatten(),name='Flatten'))
model.add(LSTM(256, return_sequences=False, input_shape=(64, 64)))
model.add(Dense(128))
model.add(Dense(64))
model.add(Dense(num_classes, activation='softmax', name='FinalDense'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=["accuracy"])

#
model.summary()
# hist = model.fit(X_train, y_train, epochs=1)

Я думаю, вам нужно решить, хотите ли вы уменьшить размерностьДанные y_train (target) должны соответствовать модели или изменить модель. Надеюсь, это поможет.

...