迁移学习中不冻结层的后果是什么?

数据挖掘 机器学习 深度学习 喀拉斯 张量流 迁移学习
2021-10-14 04:58:47

我正在尝试微调来自Kaggle 内核的一些代码。该模型使用预训练的 VGG16 权重(通过“imagenet”)进行迁移学习。但是,我注意到没有keras 博客中推荐的层冻结层。一种方法是冻结所有 VGG16 层,并在编译期间仅使用代码中的最后 4 层,例如:

for layer in model.layers[:-5]:
    layer.trainable = False

假设,这将使用顶层的 imagenet 权重并仅训练最后 5 层。不冻结 VGG16 层有什么后果?

from keras.models import Sequential, Model, load_model
from keras import applications
from keras import optimizers
from keras.layers import Dropout, Flatten, Dense

img_rows, img_cols, img_channel = 224, 224, 3

base_model = applications.VGG16(weights='imagenet', include_top=False, input_shape=(img_rows, img_cols, img_channel))

add_model = Sequential()
add_model.add(Flatten(input_shape=base_model.output_shape[1:]))
add_model.add(Dense(256, activation='relu'))
add_model.add(Dense(1, activation='sigmoid'))

model = Model(inputs=base_model.input, outputs=add_model(base_model.output))
model.compile(loss='binary_crossentropy', optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),
              metrics=['accuracy'])

model.summary()
3个回答

我认为主要后果如下:

  • 计算时间:如果冻结除最后 5 层以外的所有层,则只需要反向传播梯度并更新最后 5 层的权重。与反向传播和更新网络所有层的权重相比,这意味着计算时间的巨大减少。出于这个原因,如果您解冻所有网络,与仅更新最后一层权重相比,这将允许您查看更少的 epoch 数据。
  • 准确性:当然,通过不更新大部分网络的权重,您只是在特征空间的一个子集中进行优化。如果您的数据集与 imagenet 数据集的任何子集相似,这应该无关紧要,但是,如果它与 imagenet 非常不同,那么冻结将意味着准确性降低。如果您有足够的计算时间,解冻所有内容将使您可以在整个特征空间中进行优化,从而找到更好的最优值。

最后,我认为重点是检查您的图像是否与 imagenet 中的图像具有可比性。在这种情况下,我不会解冻很多层。否则,解冻一切,但准备等待很长的训练时间。

它可以节省计算时间的原因是您的网络已经能够从数据集中提取通用特征。网络不必学习从头开始提取通用特征。

神经网络通过逐步抽象和转换信息来工作。在初始层中,提取的特征非常通用,并且独立于特定任务。后面的层针对特定任务进行了更多调整。因此,通过冻结初始阶段,您可以获得一个已经可以提取有意义的一般特征的网络。您将解冻最后几个阶段(或只是新的未经训练的层),这将针对您的特定任务进行调整。

此外,如果您的模型中有任何新的/未经训练的层,我不建议解冻所有层。这些未经训练的层在前几个 epoc 中将具有较大的梯度,并且您的模型将像由随机(而非预训练)权重初始化一样进行训练。

不冻结预训练层的结果将是破坏它们在未来训练轮次中包含的信息。

请参阅TensorFlow的迁移学习和微调指南