#python #tensorflow #keras #lstm #conv-neural-network
#python #тензорный поток #keras #lstm #conv-neural-network
Вопрос:
Я новичок в ml / ai и пытаюсь создать cnn lstm, но у меня проблемы с формой lstm. Я пропускаю изображения 48 x 48 в оттенках серого с размером пакета 10, используя ImageDataGenerator. Это двоичная классификация (либо a, либо b). Сами изображения являются кадрами видео, которое я пытаюсь просмотреть, чтобы оно лучше понимало последовательность кадров, поскольку это относится к прогнозированию всего видео. cnn сам по себе работает, но когда я добавляю lstm, я получаю ошибку.
Вот мой код:
cnn = Sequential()
num_timesteps = 2
# 1st conv layer
cnn.add(Conv2D(64,(3,3), padding='same', input_shape=(48, 48, 1)))
cnn.add(BatchNormalization())
cnn.add(Activation('relu'))
cnn.add(MaxPooling2D(pool_size=(2, 2)))
cnn.add(Dropout(0.5))
# 2nd conv layer
cnn.add(Conv2D(128,(5,5), padding='same'))
cnn.add(BatchNormalization())
cnn.add(Activation('relu'))
cnn.add(MaxPooling2D(pool_size=(2, 2)))
cnn.add(Dropout(0.5))
# 3rd conv layer
cnn.add(Conv2D(512,(3,3), padding='same'))
cnn.add(BatchNormalization())
cnn.add(Activation('relu'))
cnn.add(MaxPooling2D(pool_size=(2, 2)))
cnn.add(Dropout(0.5))
# 4th conv layer
cnn.add(Conv2D(512,(3,3), padding='same'))
cnn.add(BatchNormalization())
cnn.add(Activation('relu'))
cnn.add(MaxPooling2D(pool_size=(2, 2)))
cnn.add(Dropout(0.5))
# flatten
cnn.add(Flatten())
# fully connected 1
cnn.add(Dense(256))
cnn.add(BatchNormalization())
cnn.add(Activation('relu'))
cnn.add(Dropout(0.5))
#fully connected 2
cnn.add(Dense(512))
cnn.add(BatchNormalization())
cnn.add(Activation('relu'))
cnn.add(Dropout(0.5))
model = Sequential()
model.add(TimeDistributed(cnn, input_shape=(None, 48, 48, 1)))
model.add(LSTM(num_timesteps))
model.add(Dropout(0.2))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['acc'])
Ошибка, возникающая при запуске model.fit
, заключается в :
Ошибка значения: ошибка при проверке ввода: ожидаемый time_distributed_56_input должен иметь 5 измерений, но получен массив с формой (10, 48, 48, 1)
Я попытался добавить количество временных шагов к измерениям, но, похоже, это не работает.
Я не уверен, что я делаю неправильно
Любая помощь была бы высоко оценена!
Ответ №1:
Вы можете поместить слой изменения формы и после этого изменить форму ввода:
model.add(Reshape((1, 48, 48, 1)))
model.add(TimeDistributed(cnn, input_shape=(1, 48, 48, 1)))
Полный рабочий пример:
import os
os.environ['CUDA_VISIBLE_DEVICES'] = '-1'
from tensorflow.keras import Sequential
from tensorflow.keras.layers import *
import numpy as np
cnn = Sequential()
num_timesteps = 2
# 1st conv layer
cnn.add(Conv2D(8,(3,3), padding='same', input_shape=(48, 48, 1)))
cnn.add(BatchNormalization())
cnn.add(Activation('relu'))
cnn.add(MaxPooling2D(pool_size=(2, 2)))
cnn.add(Dropout(0.5))
# 2nd conv layer
cnn.add(Conv2D(8,(5,5), padding='same'))
cnn.add(BatchNormalization())
cnn.add(Activation('relu'))
cnn.add(MaxPooling2D(pool_size=(2, 2)))
cnn.add(Dropout(0.5))
# 3rd conv layer
cnn.add(Conv2D(8,(3,3), padding='same'))
cnn.add(BatchNormalization())
cnn.add(Activation('relu'))
cnn.add(MaxPooling2D(pool_size=(2, 2)))
cnn.add(Dropout(0.5))
# 4th conv layer
cnn.add(Conv2D(8,(3,3), padding='same'))
cnn.add(BatchNormalization())
cnn.add(Activation('relu'))
cnn.add(MaxPooling2D(pool_size=(2, 2)))
cnn.add(Dropout(0.5))
# flatten
cnn.add(Flatten())
# fully connected 1
cnn.add(Dense(8))
cnn.add(BatchNormalization())
cnn.add(Activation('relu'))
cnn.add(Dropout(0.5))
#fully connected 2
cnn.add(Dense(8))
cnn.add(BatchNormalization())
cnn.add(Activation('relu'))
cnn.add(Dropout(0.5))
model = Sequential()
model.add(Reshape((1, 48, 48, 1)))
model.add(TimeDistributed(cnn, input_shape=(1, 48, 48, 1)))
model.add(LSTM(num_timesteps))
model.add(Dropout(0.2))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['acc'])
model.fit(np.random.rand(100, 48, 48, 1), np.random.rand(100))