请参阅以下用于创建LSTM网络的代码:
NumberofClasses=8
model = Sequential()
model.add(LSTM(256,dropout=0.2,input_shape=(32,
512),return_sequences=False))
model.add(Dense(1024, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(NumberofClasses, activation='softmax'))
print(model.summary())
sgd = SGD(lr=0.00005, decay = 1e-6, momentum=0.9, nesterov=True)
model.compile(optimizer=sgd, loss='categorical_crossentropy', metrics=
['accuracy'])
callbacks = [EarlyStopping(monitor='val_loss', patience=10, verbose=1),
ModelCheckpoint('video_1_LSTM_1_1024.h5', monitor='val_loss',
save_best_only=True, verbose=1 ) ]
nb_epoch = 500
model.fit(train_data,train_labels,validation_data,validation_labels,batch_size,nb_epoch,callbacks,shuffle=False,verbose=1)
在上面的代码中,我正在使用Keras python库创建一个LSTM,我的数据有131个视频的样本,这些视频属于8个不同的类。我为每个视频设置了一个32帧的帧序列(因此每个视频具有32帧,因此131个视频生成了4192帧)。我从VGG16的预训练模型中为每个帧提取了特征。我通过将每个提取的特征添加到数组中来创建火车数据集。它生成了4192,512维度的最终数组。相应的train_labels为八个类的每一个保留一个热编码,尺寸为4192,8。但是,由于LSTM需要(样本,时间戳和特征)格式的输入形状,并且在我的情况下,每个视频都具有32帧序列,因此我将训练后的数据重塑为[131,32,512]并应用了相同的重塑到train_labels。但是,当我运行此程序时,出现以下错误:
ValueError: Error when checking target: expected dense_2 to have 2 dimensions, but got
array with shape (131, 32, 8)
如果我不重塑train_labels并将其保留为(4192,8),则错误是:
ValueError: Input arrays should have the same number of samples as target
arrays. Found 131 input samples and 4192 target samples.
请注意,由于我的每个视频都具有32帧序列长度,因此我将此重塑[131,32,512]应用于训练数据,将(131、32、8)应用于相应的标签。对于解决此问题的任何评论或建议,我将不胜感激
答案 0 :(得分:0)
在视频分类中,整个视频通常只有一个标签,这意味着在您的情况下,标签的形状应为(131, 8)
。
如果您将标签标记为(131, 32, 8)
,则意味着您有131个样本,每个样本具有32个时间步长,每个时间步长有8个类别,因此在这种情况下,每个时间步长都有一个标签,而并非视频分类。一个模型可以做到这一点,但是您需要对LSTM进行一些更改才能使其起作用。
如果要对每个时间步进行分类,则应在LSTM中使用return_sequences=True
,例如:
model = Sequential()
model.add(LSTM(256,dropout=0.2,input_shape=(32,
512),return_sequences=True))
model.add(Dense(1024, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(NumberofClasses, activation='softmax'))
您可以检查模型的输出形状如何通过model.summary()