【问题标题】:ConvLSTM Error: expected lambda_7_input to have 5 dimensions, but got array with shape (50, 66, 200, 3)ConvLSTM 错误:预期 lambda_7_input 有 5 个维度,但得到了形状为 (50, 66, 200, 3) 的数组
【发布时间】:2020-03-14 05:28:26
【问题描述】:

我做了一个 ConvLSTM 层,但由于尺寸问题,它不起作用。

INPUT_SHAPE = (None, IMAGE_HEIGHT, IMAGE_WIDTH, IMAGE_CHANNELS)

这是我的意见

model = Sequential()
model.add(Lambda(lambda x: x/127.5-1.0, input_shape=INPUT_SHAPE))

model.add(ConvLSTM2D(24, (5, 5), activation='relu', padding='same', return_sequences=True))
model.add(BatchNormalization())

model.add(ConvLSTM2D(36, (5, 5), activation='relu', return_sequences=True))
model.add(BatchNormalization())

model.add(ConvLSTM2D(48, (5, 5), activation='relu',return_sequences=True)) 
model.add(BatchNormalization())

model.add(ConvLSTM2D(64, (3, 3), activation='relu',return_sequences=True)) 
model.add(BatchNormalization())

model.add(ConvLSTM2D(64, (3, 3), activation='relu',return_sequences=True)) 
model.add(BatchNormalization())

model.add(TimeDistributed(Flatten()))
model.add(Dropout(0.5))
model.add(TimeDistributed(Dense(100, activation='relu')))
model.add(BatchNormalization())
model.add(Dropout(0.5))
model.add(TimeDistributed(Dense(50, activation='relu')))
model.add(BatchNormalization())
model.add(Dropout(0.5))
model.add(TimeDistributed(Dense(20, activation='relu')))
model.add(BatchNormalization())
model.add(Dropout(0.5))
model.add(Dense(2))

model.summary()

这是网络模型。

history = model.fit_generator(batcher(data_dir, X_train, y_train, batch_size, True),
                    samples_per_epoch,
                    nb_epoch,
                    max_q_size=1,
                    validation_data=batcher(data_dir, X_valid, y_valid, batch_size, False),
                    nb_val_samples=len(X_valid),
                    callbacks=[checkpoint],
                    verbose=1)

它是适合的生成器。

但我收到一条错误消息。

ValueError:检查输入时出错:预期 lambda_7_input 有 5 个维度,但得到的数组形状为 (50, 66, 200, 3)

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
lambda_7 (Lambda)            (None, None, 66, 200, 3)  0         
_________________________________________________________________
conv_lst_m2d_29 (ConvLSTM2D) (None, None, 66, 200, 24) 64896     
_________________________________________________________________
batch_normalization_27 (Batc (None, None, 66, 200, 24) 96        
_________________________________________________________________
conv_lst_m2d_30 (ConvLSTM2D) (None, None, 62, 196, 36) 216144    
_________________________________________________________________
batch_normalization_28 (Batc (None, None, 62, 196, 36) 144       
_________________________________________________________________
conv_lst_m2d_31 (ConvLSTM2D) (None, None, 58, 192, 48) 403392    
_________________________________________________________________
batch_normalization_29 (Batc (None, None, 58, 192, 48) 192       
_________________________________________________________________
conv_lst_m2d_32 (ConvLSTM2D) (None, None, 56, 190, 64) 258304    
_________________________________________________________________
batch_normalization_30 (Batc (None, None, 56, 190, 64) 256       
_________________________________________________________________
conv_lst_m2d_33 (ConvLSTM2D) (None, None, 54, 188, 64) 295168    
_________________________________________________________________
batch_normalization_31 (Batc (None, None, 54, 188, 64) 256       
_________________________________________________________________
time_distributed_6 (TimeDist (None, None, 649728)      0         
_________________________________________________________________
dropout_6 (Dropout)          (None, None, 649728)      0         
_________________________________________________________________
time_distributed_7 (TimeDist (None, None, 100)         64972900  
_________________________________________________________________
batch_normalization_32 (Batc (None, None, 100)         400       
_________________________________________________________________
dropout_7 (Dropout)          (None, None, 100)         0         
_________________________________________________________________
time_distributed_8 (TimeDist (None, None, 50)          5050      
_________________________________________________________________
batch_normalization_33 (Batc (None, None, 50)          200       
_________________________________________________________________
dropout_8 (Dropout)          (None, None, 50)          0         
_________________________________________________________________
time_distributed_9 (TimeDist (None, None, 20)          1020      
_________________________________________________________________
batch_normalization_34 (Batc (None, None, 20)          80        
_________________________________________________________________
dropout_9 (Dropout)          (None, None, 20)          0         
_________________________________________________________________
dense_8 (Dense)              (None, None, 2)           42        
=================================================================
Total params: 66,218,540
Trainable params: 66,217,728
Non-trainable params: 812

【问题讨论】:

  • 您的x_trainy_train 的形状是什么?此外,在层输出形状中包含多个 None 通常不是一个好主意。
  • @thushv89 抱歉回答迟了。 print(X_train.shape) 和 print(y_traint.shape) 的结果是 (10908,) 和 (10908,2)。我确实在 Input 上写了批量大小,但得到了相同的错误消息
  • 这不是您要指定的批量大小,而是时间步数(即第二个无)。另外,您的X_train 有两个功能?但是,你为什么要使用 ConvLSTM?这是二维时间序列数据(如视频)
  • @thushv89 X_train 是具有 10908 个样本的单个图像。我试图制作预测模型(速度、转向角)。所以它有2个输出。但是对于速度预测,我需要 rnn 才能知道物体是更近还是更远。 Cnn 还不够
  • 那么X_train 是一张包含 10908 个样本的图片?你能详细说明吗? “图像中的样本”是什么意思?如果您能提供更多详细信息,那就更好了。

标签: python conv-neural-network recurrent-neural-network


【解决方案1】:

好吧,有几件事你必须了解。

定义模型。

所以,您的模型基本上应该有 5 个维度的输入。那些是,

  • 批量维度 -(keras 自动添加,所以不要添加)
  • 时间维度 - 您的系列中的时间步数
  • 图片高度
  • 图像宽度
  • 图像通道

这就是以下模型所采用的内容。如果您查看模型摘要,输出形状中只有一个 None 值(即批次维度),因为它应该是

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Lambda, ConvLSTM2D, BatchNormalization, TimeDistributed, Dropout, Dense, Flatten

IMAGE_HEIGHT = 66
IMAGE_WIDTH = 200
IMAGE_CHANNELS = 3
TIME_STEPS = 25
INPUT_SHAPE = (TIME_STEPS, IMAGE_HEIGHT, IMAGE_WIDTH, IMAGE_CHANNELS)

model = Sequential()
model.add(Lambda(lambda x: x/127.5-1.0, input_shape=INPUT_SHAPE))

model.add(ConvLSTM2D(24, (5, 5), activation='relu', padding='same', return_sequences=True))
model.add(BatchNormalization())

model.add(ConvLSTM2D(36, (5, 5), activation='relu', return_sequences=True))
model.add(BatchNormalization())

model.add(ConvLSTM2D(48, (5, 5), activation='relu',return_sequences=True)) 
model.add(BatchNormalization())

model.add(ConvLSTM2D(64, (3, 3), activation='relu',return_sequences=True)) 
model.add(BatchNormalization())

model.add(ConvLSTM2D(64, (3, 3), activation='relu',return_sequences=True)) 
model.add(BatchNormalization())

model.add(TimeDistributed(Flatten()))
model.add(Dropout(0.5))
model.add(TimeDistributed(Dense(100, activation='relu')))
model.add(BatchNormalization())
model.add(Dropout(0.5))
model.add(TimeDistributed(Dense(50, activation='relu')))
model.add(BatchNormalization())
model.add(Dropout(0.5))
model.add(TimeDistributed(Dense(20, activation='relu')))
model.add(BatchNormalization())
model.add(Dropout(0.5))
model.add(Dense(2))

model.compile(loss='mse', optimizer='adam', metrics=['mse'])
model.summary()

处理数据

您的数据一开始的格式如下。

  • 输入 -(10908,高度,宽度,通道)
  • 输出 - (10908, 2)

但问题是您无法将其原样提供给模型,因为模型需要 5 维输入。有两种选择。

  • 选项 1:通过添加新轴(即np.expand_dims)使您的输入为(1、10908、高度、宽度、通道)。但这存在三个问题。

    • 与模型一起,这么大的张量可能不适合内存。即便如此,训练也需要很长时间。
    • LSTM 记不住那么久
    • 您的模型可能会严重过度拟合,因为它只有一个数据点
  • 选项 2:这是更好的选项。您将数据分成块。因此,您将 10908 分解为 25 块(假设)。您可以尝试其他值,例如 50/100。我不建议超过一百,因为这是图像数据(由于内存/计算问题)。但这意味着要牺牲一些最后的图像,因为您需要第一个轴(即 10908)可以被您选择的时间步数整除。

换句话说,您的模型不是以 50 个块为单位进行学习,而是尝试记住完整的长流,这通常可以更好地概括。这也很有意义。您不需要记住之前所做的一切来决定最后n 帧的转向角度和速度。

PS:你也可以聪明一点,帮助模型更好地泛化。也就是说,您的批量大小为 50,TIME_STEPS 为 25。

  • 您随机采样一个连续的块(例如 50*25)
  • 将此重塑为(50、25、高度、宽度、通道)
  • 将其用作数据批次

这样,你在不同的时期有不同的块,这比在一个完整的集合上进行重塑要好,这将导致在不同的时期看到相同的块。

import numpy as np

x_train = x_train[:10900, :, :, :]
y_train = y_train[:10900, :]

x_train = x_train.reshape(-1,TIME_STEPS, IMAGE_HEIGHT, IMAGE_WIDTH, 3)
y_train = y_train.reshape(-1, TIME_STEPS, 2)

print(x_train.shape)
print(y_train.shape)

拟合模型

完成了所有艰苦的工作,您现在可以训练您的模型了。

history = model.fit(x_train, y_train)

我用fit 替换了你的fit_generator,因为我觉得很懒,但它仍然明白了这一点。

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2020-01-13
    • 1970-01-01
    • 2019-09-04
    • 1970-01-01
    • 2020-06-09
    • 2020-01-30
    • 1970-01-01
    • 1970-01-01
    • 2020-06-18
    相关资源
    最近更新 更多