我试图冻结免费训练的VGG16的图层(下面的'conv_base'),并在它们上面添加新图层以进行特征提取 . 我希望在(ret1)/之后(ret2)拟合模型之前从'conv_base'获得相同的预测结果,但事实并非如此 . 这是检查体重冻结的错误方法吗?
加载VGG16并设置为无法处理
conv_base = applications.VGG16(weights='imagenet', include_top=False, input_shape=[150, 150, 3])
conv_base.trainable = False
模型拟合前的
结果
ret1 = conv_base.predict(np.ones([1, 150, 150, 3]))
在VGG16顶部添加图层并编译模型
model = models.Sequential()
model .add(conv_base)
model .add(layers.Flatten())
model .add(layers.Dense(10, activation='relu'))
model .add(layers.Dense(1, activation='sigmoid'))
m.compile('rmsprop', 'binary_crossentropy', ['accuracy'])
适合模型
m.fit_generator(train_generator, 100, validation_data=validation_generator, validation_steps=50)
模型拟合后
结果
ret2 = conv_base.predict(np.ones([1, 150, 150, 3]))
希望这是真的,但事实并非如此 .
np.equal(ret1, ret2)
2 回答
这是一个有趣的案例 . 为什么会发生这样的事情是由以下因素引起的:
You cannot freeze a whole model after compilation and it's not freezed if it's not compiled
如果设置标志
model.trainable=False
,则在编译keras
时将所有图层设置为不可训练 . 如果在编译后设置此标志 - 那么它根本不会影响您的模型 . 相同 - 如果您在编译之前设置此标志,然后您将重用模型的一部分来编译另一个 - 它不会影响您重复使用的图层 . 所以model.trainable=False
仅在您按以下顺序应用时才有效:在任何其他情况下,它将无法按预期工作 .
您必须单独冻结图层(在编译之前):
如果这不起作用,您应该使用新的顺序模型来冻结图层 .