如何修复'ValueError:输入张量必须具有等级 4'?

Posted

技术标签:

【中文标题】如何修复\'ValueError:输入张量必须具有等级 4\'?【英文标题】:How to fix the 'ValueError: input tensor must have rank 4'?如何修复'ValueError:输入张量必须具有等级 4'? 【发布时间】:2019-12-19 10:26:12 【问题描述】:

目前我正在尝试将 CNN 与 LSTM 模型结合起来进行视频分类,但在 Google 和 *** 上进行搜索后,我无法找到解决问题的方法

下面是整个代码:

#Importing libraries 
from keras.preprocessing.image import ImageDataGenerator 
from keras.models import Sequential 
from keras.layers import Conv2D, MaxPooling2D, LSTM, TimeDistributed
from keras.layers import Activation, Dropout, Flatten, Dense 
from keras import backend as K

#Shape of the image, based on 1920x1080
img_width, img_height = 224, 135

#Location of the frames split in a train and test folder
train_data_dir = './train'
validation_data_dir = './test'

#Data information
nb_train_samples = 46822
nb_validation_samples = 8994
timesteps = 1
epochs = 10
batch_size = 30

input_shape = (img_width, img_height, 3)

model = Sequential()
# define CNN model
model.add(TimeDistributed(Conv2D(132, (3, 3), input_shape=input_shape, activation='relu')))
model.add(TimeDistributed(MaxPooling2D(pool_size = (2, 2))))
model.add(TimeDistributed(Flatten()))
# define LSTM model
model.add(LSTM(132, return_sequences=True))
model.add(LSTM(132, return_sequences=True))
model.add(LSTM(132, return_sequences=True))
model.add(LSTM(132, return_sequences=True))
model.add(Dense(3, activation='softmax'))

model.build(input_shape)

model.summary()

model.compile(loss ='categorical_crossentropy', optimizer ='rmsprop', metrics =['accuracy']) 

model.fit_generator(train_generator, steps_per_epoch = nb_train_samples // batch_size, epochs = epochs, validation_data = validation_generator, validation_steps = nb_validation_samples // batch_size)

train_datagen = ImageDataGenerator(rescale = 1. / 255, shear_range = 0.2, zoom_range = 0.2, horizontal_flip = True) 

test_datagen = ImageDataGenerator(rescale = 1. / 255) 

train_generator = train_datagen.flow_from_directory(train_data_dir, target_size =(img_width, img_height), batch_size = batch_size, class_mode ='categorical') 

validation_generator = test_datagen.flow_from_directory(validation_data_dir, target_size =(img_width, img_height), batch_size = batch_size, class_mode ='categorical')  

运行时出现的错误是:

回溯(最近一次通话最后一次): 文件“CNNLSTM.py”,第 36 行,在 model.build(input_shape) ...... ValueError: 输入张量必须有 4 级

我已添加 model.build(input_shape) 以避免此错误:

ValueError:此模型尚未构建。首先通过调用 build() 或使用一些数据调用 fit() 来构建模型。或者在第一层指定 input_shape 或 batch_input_shape 进行自动构建。

但正如在代码中可见的那样,我在模型的第一行应用了 input_shape

希望这里有人能指出我做错了什么。

【问题讨论】:

【参考方案1】:

您应该考虑三点:

    您提到您正在进行视频分类。因此,模型的输入是一组图像/帧。所以输入的形状(即一个样本的形状)是:

    input_shape = (n_frames, img_width, img_height, 3)
    

    模型的第一层是 TimeDistributed 包装器,它包装了 Conv2D 层。因此,您必须为此层设置input_shape 参数:

    model.add(TimeDistributed(Conv2D(132, (3, 3), activation='relu'), input_shape=input_shape))
    

    build 方法需要批量形状作为参数,而不是单个输入样本的形状。因此,你应该写:

    model.build((None,) + input_shape)
    

    但是,如果您解决了第 2 点,那么您根本不需要调用 build 方法。

【讨论】:

感谢您的回复,这提供了解决方案!但是在进一步的步骤中,我又遇到了另一个错误,回到谷歌搜索;)【参考方案2】:

正如您在错误消息 model.build 中看到的,需要 4D 张量作为输入,而您的输入形状是 input_shape = (img_width, img_height, 3) 3D。 Tensorflow 通常期望输入具有以下形状:(N, H, W, C),其中 N 是批量大小,H 和 W 分别是高度和宽度,C 是通道数。如果您只有一张图像,您可以将输入形状更改为input_shape = (1, img_width, img_height, 3),但通常处理批量图像更有效。

【讨论】:

感谢您的回复,似乎此选项也有效,但“今天”提供的答案首先应用并提供了解决方案。

以上是关于如何修复'ValueError:输入张量必须具有等级 4'?的主要内容,如果未能解决你的问题,请参考以下文章

ValueError:无法为具有形状“(?,784)”的张量“x:0”提供形状(784,)的值

ValueError:模型的输出张量必须是TensorFlow`Layer`的输出

ValueError:无法为具有形状“(?,1)”的张量“Placeholder_1:0”提供形状(6165、5)的值

ValueError:无法为具有形状“(?,4)”的张量“Placeholder_36:0”提供形状(4,)的值

如何修复 Logits 和 Labels 必须具有相同的形状?

ValueError:在使用 tf.image.crop_to_bounding_box 时,张量转换为具有 dtype float32 的张量请求 dtype int32