Ошибка значения: ошибка при проверке ввода: ожидаемый time_distributed_55_input должен иметь 5 измерений, но получен массив с формой (10, 48, 48, 1)

#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))