Keras CNN-LSTM:制作 y_train 时出错

Posted

技术标签:

【中文标题】Keras CNN-LSTM:制作 y_train 时出错【英文标题】:Keras CNN-LSTM : Error while making y_train 【发布时间】:2020-02-24 20:42:28 【问题描述】:

这是我第一次在这里问问题(这意味着我真的需要帮助),很抱歉我的英语不好。我想在 Keras 中为视频分类制作一个 cnn-lstm 层,但我在制作 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 shape : (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】:

我重新创建了一个稍微简化的版本来重现问题。基本上,LSTM 层似乎只为整个时间步序列输出一个结果,从而将输出中的维度从 3 减少到 2。如果你在下面运行我的程序,我已经添加了提供架构细节的 model.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(目标)数据的维度以与模型保持一致,还是要更改模型。我希望这会有所帮助。

【讨论】:

感谢您的回答。是的,我完全知道我应该将维度从 3 减少到 2。但是就像我在上面的问题中描述的那样,我已经减少了维度,但是还有另一个错误。我不知道如何减少尺寸的正确方法? 当你减少目标的维度时,你必须保持样本数量与输入 x 数据相同(我认为是 228)。这就是为什么您会收到另一个错误。您可能需要选择当前目标的最后一个时间步长值来进行缩减。我相信像 y_target_new = np.squeeze(y_train[:,-1,:]) 或类似的东西。我希望这会有所帮助。 天哪!太感谢了! :D 顺便说一句,你能告诉我 np.squeeze(y_train[:,-1,:]) 做什么吗?如果我打印形状,它只打印 (228, 26)。再次感谢您:D

以上是关于Keras CNN-LSTM:制作 y_train 时出错的主要内容,如果未能解决你的问题,请参考以下文章

在 keras 中使用 CNN-LSTM 模型进行序列到序列分类

CNN-LSTM图像分类

如何为 LSTM keras 重塑 X_train 和 y_train

keras数据集读取

keras中二元分类的类不平衡

Conv1D 层 Keras 的 input_shape