我正在使用Keras 2.1.6进行转移学习,并使用两种非常着名的标准方法。这些都在Chollet的书的第5章和https://github.com/fchollet/deep-learning-with-python-notebooks/blob/master/5.3-using-a-pretrained-convnet.ipynb中详细详述
这两种方式是概括性的:
A)从conv_base缓存表示,然后分别在FC上训练。 这被认为是快速但不允许在Keras中进行数据增加。
B)使用FC扩展conv_base模型并冻结conv_base权重,并端到端训练。这对于在CPU上训练来说是昂贵的,但是将允许更大的灵活性,特别是增加数据增加。
对于我的特定数据集并使用MobileNet(而不是VGG),我尝试了两种方式。方法(A)将在10个时期后给出约75%的验证准确度,但方法(B)将仅给出~58%(没有数据增加)。但是,我希望它们大致相同。我试图调试,看看我做了什么重大错误,但无法发现任何问题。
我读到的一件事是,由于过去的错误,假设在方法B中被冻结的权重可能不会被冻结。但目前的Keras版本2.1.6应该是免费的。以下是我在conv_base中冻结权重的方法。
conv_base.trainable = False
for layer in conv_base.layers:
layer.trainable = False
可能不需要循环但我添加它以防万一。事实证明,在几个时代之后检查它们的重量实际上是冻结的。所以这可能不是导致问题的原因。
任何有关如何调试或可能出错的提示的人都请告诉我。
我将这两个游戏发布为GitHub的要点。我在谷歌colab上运行它并导出它们。相关部分应从那些Keras进口开始。
方法A):https://gist.github.com/kechan/38b4e6c85501246a2a49deadd26aefd7
方法B):https://gist.github.com/kechan/f3fea62279ac847e9adc100351b7e9e8
我进一步将两种转学方式结合到一个笔记本中,并尝试保留其他所有内容"常数"越多越好。这是新要点:
https://gist.github.com/kechan/9487fad4dfeaede212e3d9899fb21105
答案 0 :(得分:0)
这似乎是ego_graph
层(BN)或其他任何层的影响,它们在训练与推理上的作用不同。特别是国阵在推理中使用了保存的人口统计数据,而在训练中使用了当前的小批量统计数据。在基本模型中冻结BN层的权重然后进行训练时,将会发生小批量统计信息。这可能会导致不良结果,因为相邻的转换层期望使用保存的人口统计信息对输入进行标准化。
如果您首先使用基本模型提取特征,则不会看到任何不良影响,因为基本模型处于推断模式,并且使用了人口统计信息。
一种解决方案是继承BatchNormalization
的子类并覆盖BatchNormalization
方法,将__call__
标志设置为False。类似于以下内容:
training
看看keras代码,它会变得很清楚:https://github.com/keras-team/keras/blob/master/keras/layers/normalization.py#L132