【发布时间】:2021-06-03 19:26:06
【问题描述】:
我的模型只从二元类中预测一个类。该模型使用 Keras Video Frame Generator 获取视频输入,并为每个视频获取 350 帧。该模型必须采用 350 帧的输入序列并使用 BLSTM 输出二进制类。输入形状为 (350, 112, 75, 3)。由于 OOM 错误,批量大小为 2。我不知道这可能是问题还是代码有问题,但模型似乎什么也没学到。这是代码:
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, BatchNormalization, MaxPool2D, GlobalMaxPool2D
def build_convnet(shape=(112, 75, 2)):
momentum = .9
model = Sequential()
model.add(Conv2D(64, (3,3), input_shape=shape, padding='same', activation='relu'))
model.add(Conv2D(64, (3,3), padding='same', activation='relu'))
model.add(BatchNormalization(momentum=momentum))
model.add(MaxPool2D())
model.add(Conv2D(128, (3,3), padding='same', activation='relu'))
model.add(Conv2D(128, (3,3), padding='same', activation='relu'))
model.add(BatchNormalization(momentum=momentum))
model.add(MaxPool2D())
model.add(Conv2D(256, (3,3), padding='same', activation='relu'))
model.add(Conv2D(256, (3,3), padding='same', activation='relu'))
model.add(BatchNormalization(momentum=momentum))
model.add(MaxPool2D())
model.add(Conv2D(512, (3,3), padding='same', activation='relu'))
model.add(Conv2D(512, (3,3), padding='same', activation='relu'))
model.add(BatchNormalization(momentum=momentum))
# flatten...
model.add(GlobalMaxPool2D())
return model
from tensorflow.keras.layers import LSTM, Bidirectional
from tensorflow.keras.layers import TimeDistributed, Dense, Dropout
def action_model(shape=(350, 112, 75, 3), nbout=2):
# Create our convnet with (112, 75, 3) input shape
convnet = build_convnet(shape[1:])
# then create our final model
model = Sequential()
# add the convnet with (350, 112, 75, 3) shape
model.add(TimeDistributed(convnet, input_shape=shape))
model.add(Bidirectional(LSTM(units = 512, return_sequences = True, input_shape = (NBFRAME, 112*75*3))))
model.add(Dropout(0.5))
# Adding a second LSTM layer and Dropout layer
model.add(Bidirectional(LSTM(units = 512, return_sequences = True)))
model.add(Dropout(0.5))
# Adding a third LSTM layer and Dropout layer
model.add(Bidirectional(LSTM(units = 512)))
model.add(Dropout(0.5))
model.add(Dense(nbout, activation='softmax'))
model.summary()
return model
这是模型摘要。
【问题讨论】:
-
您是否基于视频(不是基于帧)对数据进行了混洗? (假设 350 帧的每个视频都映射到两个类别之一)。不洗牌,训练就会有偏差。
-
我检查并打印生成器中的视频索引是随机顺序
-
好的,你会检查学习曲线吗?它是否很早就饱和了(并且损失完全停止减少)?如果是,那么您的模型可能面临
Dying ReLU问题。尝试采用较小的学习率和/或使用一些专门的权重初始化技术,例如He initialization。 tensorflow.org/api_docs/python/tf/keras/initializers/HeUniform。您也可以尝试ReLU的其他变体,例如Leakly ReLU。 -
我尝试使用较小的学习率和 Leakly ReLU:在训练过程中,该模型在训练集和验证集上似乎都更好(70-80% 的准确度),但在测试集上的准确度为 52%。跨度>
-
很高兴知道您的问题已解决。但是您现在面临的问题与问题的问题不同。你最好用代码提出一个新问题,最重要的是用你生成的所有图。但是现在我建议你验证一个事实——训练数据(至少是验证数据)是否能很好地代表测试数据。为了验证它,你可以问自己一个小问题——如果有人将测试数据与训练数据混在一起,你能把它们分开吗?如果可以,那么您的训练数据不好。但如果你不能,那么你的训练数据就可以了。
标签: machine-learning neural-network conv-neural-network tf.keras image-classification