【发布时间】:2017-09-30 11:19:47
【问题描述】:
我正在使用来自keras.applications 的预训练 InceptionV3 模型在 Keras 中使用迁移学习实现卷积神经网络,如下所示
#Transfer learning with Inception V3
base_model = applications.InceptionV3(weights='imagenet', include_top=False, input_shape=(299, 299, 3))
## set model architechture
x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(1024, activation='relu')(x)
predictions = Dense(y_train.shape[1], activation='softmax')(x)
model = Model(input=base_model.input, output=predictions)
for layer in base_model.layers:
layer.trainable = False
model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
model.summary()
我正在关注一篇博文,其中说模型必须在冻结基础模型后训练几个 epoch。我已经对模型进行了 5 个 epoch 的训练,结果我的 acc 为 0.47。在那之后acc没有太大改善。然后我停止了训练,像这样解冻了一些层,并冻结了前 2 个卷积层。
for layer in model.layers[:172]:
layer.trainable = False
for layer in model.layers[172:]:
layer.trainable = True
并使用学习率较低的 SGD 编译。
当 acc 没有太大改善且层冻结正确时,我停止训练模型的方法是正确的吗?我应该训练更长时间吗?
如何知道冻结层的正确时间停止训练?
【问题讨论】:
-
如果您使用的是固定图像大小,则不需要 GlobalAveragePooling。该层大大减少了 Dense 层的变量数量。使用 Flatten 而不是池化可能更容易找到更好的 acc 值。 (缺点是您以后将无法使用不同尺寸的图像)。
-
如果您确实打算稍后使用可变大小的图像,那么
GlobalMaxPooling2D可能会更好一些。由于卷积网络通过检测某些特征的存在来工作,因此 MaxPooling 将符合“最大值 = 最可信的存在指标”的想法。而平均池化将汇总存在(高)和不存在(低)值,并始终产生“某种存在”的结果。 -
如果您注意到
Flatten模型比任何GlobalPooling模型工作得更好,您可以尝试在池化之前添加Conv2D(1024,activation='relu')。 (这将在最大池化之前为每个所需的类创建一个特征图。但如果最后一个初始层还没有 1024 个或更多过滤器,它可能就没那么有用了)。 -
好的。我会试一试的。
-
我应该在 base_model 层冻结的情况下训练多长时间。?直到 acc 保持不变。?或者我应该稍微过度适合它。?