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 模型进行序列到序列分类