【已解决】使用keras对resnet, inception3进行fine-tune出现训练集准确率很高但验证集很低的问题(BN)

最近用keras跑基于resnet50,inception3的一些迁移学习的实验,遇到一些问题。通过查看github和博客发现是由于BN层导致的,国外已经有人总结并提了一个PR(虽然并没有被merge到Keras官方库中),并写了一篇博客,也看到知乎有人翻译了一遍:Keras的BN你真的冻结对了吗

当保存模型后再加载模型去预测时发现与直接预测结果不一致也可能是BN层的问题。

总结:

  • keras中通常用trainable这个参数来控制某一层的权重是否更新,例如trainable可以控制BN中的和是否变化。

  • TF为后端时,BN有一个参数是training,控制归一化时用的是当前Batch的均值和方差(训练模式)还是移动均值和方差(测试模式),这个参数由Keras的K.learning_phase控制。若只设置trainable是不会影响BN的training参数。

  • 冻结时某一层时,我们希望这一层的状态和预训练模型中的状态一致

  • 我们通常希望训练和测试时网络中的配置一致,但BN训练和测试时的配置是不一样的,而frozen这个行为放大了这种不一致,导致精度下降。训练时用了新数据集的均值和方差去做归一化,测试时用了旧数据集的移动均值和方差去做归一化

  • 为了让训练和测试尽量一致,避免精度下降,有两种方案,一种是在测试时也用旧数据集的移动均值和方差

  • 另一种方案是在训练时也只用旧数据集的移动均值和方差,这是Keras作者fchollet在GitHub issue里回复的方案:在定义模型时,手动将training参数设为False(可以通过显式设置BN的training参数,或者通过设置learning_phase来隐式改变training参数),我觉得其实这种workaround还是挺好用的,而且也更符合frozen的意图,即:

显式设置:

   x = BatchNormalization()(y, training=False)

隐式设置:

    # Set up inference-mode base
    K.set_learning_phase(0)
    inputs = Input(...)
    x = layer1(...)(inputs)
    x = layer2(...)(x)
    ...
    x = layerN(...)(x)
    
    # Add training-mode layers
    K.set_learning_phase(1)
    x = layerNp1(...)(x)
    x = layerNp2(...)(x)

不可否认的是,默认的Frozen的BN的行为在迁移学习中确实是有training这个坑存在的,个人认为fchollet的修复方法更简单一点,并且这种方式达到的效果和使用预训练网络提取特征,单独训练分类层达到的效果是一致的,当你真的想要冻结BN层的时候,这种方式更符合冻结的这个动机;但在测试时使用新数据集的移动均值和方差一定程度上也是一种domain adaption。

译文:
虽然Keras节省了我们很多编码时间,但Keras中BN层的默认行为非常怪异,坑了我(此处及后续的“我”均指原文作者)很多次。Keras的默认行为随着时间发生过许多的变化,但仍然有很多问题以至于现在Keras的GitHub上还挂着几个相关的issue。在这篇文章中,我会构建一个案例来说明为什么Keras的BN层对迁移学习并不友好,并给出对Keras BN层的一个修复补丁,以及修复后的实验效果。

1. Introduction

这一节我会简要介绍迁移学习和BN层,以及learning_phase的工作原理,Keras BN层在各个版本中的变化。如果你已经了解过这些知识,可以直接跳到第二节(译者注:1.3和1.4跟这个问题还是比较相关的,不全是背景)。

1.1 迁移学习在深度学习中非常重要

深度学习在过去广受诟病,原因之一就是它需要太多的训练数据了。解决这个限制的方法之一就是迁移学习。

假设你现在要训练一个分类器来解决猫狗二分类问题,其实并不需要几百万张猫猫狗狗的图片。你可以只对预训练模型顶部的几层卷积层进行微调。因为预训练模型是用图像数据训练的࿰

  • 9
    点赞
  • 88
    收藏
    觉得还不错? 一键收藏
  • 22
    评论
评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值