jcg*_*aca 5 conv-neural-network keras tensorflow recurrent-neural-network
我正在尝试将 CNN-LSTM 网络与 Keras 结合使用来分析视频。我读到了它并遇到了TimeDistributed函数和一些示例。
实际上,我尝试了下面描述的网络,它实际上由卷积层和池化层以及后面的循环层和密集层组成。
model = Sequential()
model.add(TimeDistributed(Conv2D(2, (2,2), activation= 'relu' ), input_shape=(None, IMG_SIZE, IMG_SIZE, 3)))
model.add(TimeDistributed(MaxPooling2D(pool_size=(2, 2))))
model.add(TimeDistributed(Flatten()))
model.add(LSTM(50))
model.add(Dense(50, activation = 'softmax'))
model.compile(loss = 'categorical_crossentropy' , optimizer = 'adam' , metrics = ['acc'])
Run Code Online (Sandbox Code Playgroud)
我没有正确测试该模型,因为我的数据集太小。然而,在训练过程中,网络在 4-5 个 epoch 内达到了0.98 的准确度(也许是过度拟合,但这还不是问题,因为我希望稍后能得到合适的数据集)。
然后,我了解了如何使用预训练的卷积网络(MobileNet、ResNet 或 Inception)作为 LSTM 网络的特征提取器,因此我使用以下代码:
inputs = Input(shape = (frames, IMG_SIZE, IMG_SIZE, 3))
cnn_base = InceptionV3(include_top = False, weights='imagenet', input_shape = (IMG_SIZE, IMG_SIZE, 3))
cnn_out = GlobalAveragePooling2D()(cnn_base.output)
cnn = Model(inputs=cnn_base.input, outputs=cnn_out)
encoded_frames = TimeDistributed(cnn)(inputs)
encoded_sequence = LSTM(256)(encoded_frames)
hidden_layer = Dense(1024, activation="relu")(encoded_sequence)
outputs = Dense(50, activation="softmax")(hidden_layer)
model = Model([inputs], outputs)
Run Code Online (Sandbox Code Playgroud)
在这种情况下,训练模型时,它总是显示准确度 ~0.02(这是基线的 1/50)。
由于第一个模型至少学到了任何东西,我想知道在第二种情况下网络的构建方式是否存在任何错误。
有人遇到过这种情况吗?有什么建议吗?
谢谢。
小智 1
原因是您的数据量非常少,并且需要重新训练完整的 Inception V3 权重。您必须使用更多的数据来训练模型,或者通过超参数调整使用更多的纪元来训练模型。您可以在此处找到有关超参数训练的更多信息。
理想的方法是冻结基本模型并base_model.trainable = False仅训练在 Inception V3 层之上添加的新层。
或者
解冻基础模型的顶层(Inception V3 层)并将底层设置为不可训练。您可以按如下方式进行操作 -
# Let's take a look to see how many layers are in the base model
print("Number of layers in the base model: ", len(base_model.layers))
# Fine-tune from this layer onwards
fine_tune_at = 100
# Freeze all the layers before the `fine_tune_at` layer
for layer in base_model.layers[:fine_tune_at]:
layer.trainable = False
Run Code Online (Sandbox Code Playgroud)