迁移学习之resnet50——解决过拟合及验证集上准确率上不去问题

4 篇文章 0 订阅
1 篇文章 0 订阅

keras之resnet50迁移学习做分类

问题1描述:迁移学习用resnet50做分类,验证集上的准确率一直是一个大问题,有时候稳定在一个低的准确率,我的一次是一直在75%上下波动。

问题2描述:resnet50迁移学习,训练集上的准确率一直在攀升,但验证集上的准确率一直上不去,一定程度上出现了过拟合现象,但加很多的BN、dropout、l1和l2正则化手段都不能有效的解决问题。

***问题1答案:***这个问题网络设计没有问题的话,一般出现在训练的数据量上,数据量偏少就会出现验证集上准确率一直很低。

问题2答案:

2020/10/12更新

根本原因可参考:https://github.com/keras-team/keras/pull/9965
解决方案:在这里插入图片描述其实就是加一个参数:layers=tf.keras.layers

下面的采坑可不看

--------------------------------------------

-----------------------------------------------

先来看一下一般resnet50迁移学习的网络设计:

 base_model = ResNet50(weights='imagenet', include_top=False,
                              input_shape=(image_size, image_size, 3), )
x = base_model.output
x = GlobalAveragePooling2D(name='average_pool')(x)
x = Flatten(name='flatten')(x)

这是一个典型的残差网络做迁移学习的套路,很多人都是这么做的,但真的有很高的准确率吗?反正我试了很多次,一直出现验证集上的准确率很低上不去的问题。不管怎么用防止过拟合的手段,效果都不是很好。后来研究BN层看了几篇相关的论文,发现包括resnet,inception等模型都包含了Batch Normalization层,如果使用pretrained参数进行finetune,这些BN层一般情况下使用了K.learning_phase的值作为is_training参数的默认值,因此导致训练的时候使用的一直是mini batch的平均值 ,由于trainable在finetune时候一般设置为false了导致整个layer 不会update,因此moving_mean\variance根本没有更新。导致你在test时用的moving_mean\variance全是imagenet数据集上的值。
参考链接:https://github.com/keras-team/keras/pull/9965
修正后的代码:

K.set_learning_phase(0)
base_model = ResNet50(weights='imagenet', include_top=False,
                              input_shape=(image_size, image_size, 3), )
 K.set_learning_phase(1)
x = base_model.output
x = GlobalAveragePooling2D(name='average_pool')(x)
x = Flatten(name='flatten')(x)
x = Dense(2048, activation='relu', kernel_regularizer=regularizers.l2(0.0001), )(x)
x = BatchNormalization()(x)
x = Dense(1024, activation='relu', kernel_regularizer=regularizers.l2(0.0001))(x)
x = BatchNormalization(name='bn_fc_01')(x)
predictions = Dense(num_classes, activation='softmax')(x)
model = Model(inputs=base_model.input, outputs=predictions)

这样更正后可以使得准确率有一个良好的上升,但优化的不够彻底,再有一些小的技巧可以让你的验证集上的准确率有更好的提升。这是一个试验,没有理论支持,如果上述的方案不能满足你对准确率的要求,不妨试试下面这个方案:

K.set_learning_phase(0)
Inp = Input((224, 224, 3))
base_model = ResNet50(weights='imagenet', include_top=False,
                              input_shape=(image_size, image_size, 3), )
 K.set_learning_phase(1)
 x = base_model(Inp)
x = GlobalAveragePooling2D(name='average_pool')(x)
x = Flatten(name='flatten')(x)
...
predictions = Dense(num_classes, activation='softmax')(x)
model = Model(inputs=Inp, outputs=predictions)

可看出区别了吗?下面代码将输入变更了,不用resnet的输出做输入,直接定义自己的输入,我有测试过,这样做确实对准确率有一定的提升。基本上resnet50迁移学习的坑就踩到这里。

  • 42
    点赞
  • 278
    收藏
    觉得还不错? 一键收藏
  • 39
    评论
ResNet-50是一个经典的深度卷积神经网络模型,其中50代表网络的层数。而MNIST是一个经典的手写数字识别数据集,包含了60000个训练样本和10000个测试样本,每个样本都是大小为28x28的灰度图像。 将ResNet-50应用于MNIST数据集时,需要对两者进行适配。首先,MNIST数据集是一个灰度图像数据集,而ResNet-50通常用于彩色图像识别,因此需要将MNIST数据集的图像转为RGB格式。方法是将MNIST图像的每个像素值复制三次,形成一个具有三个通道(RGB)的图像。此外,MNIST数据集中的图像尺寸为28x28,而ResNet-50要求输入图像的尺寸为224x224,因此需要对图像进行缩放。 在使用ResNet-50训练MNIST数据集时,可以使用预训练的ResNet-50模型进行迁移学习。通过在模型的最后一层添加一个全连接层,并将其输出节点数设置为10(对应MNIST数据集中0到9的数字类别),然后初始化全连接层的权重参数。接着,使用MNIST数据集进行训练,通常会使用交叉熵损失函数和随机梯度下降等优化算法。 通过这样的适配和训练,可以使得ResNet-50模型在MNIST数据集上学习到更好的特征表示,从而提高手写数字识别的准确率。然而,由于MNIST数据集相对简单,ResNet-50这样复杂的模型可能会导致过拟合问题,因此可能需要适当的正则化方法(如L1或L2正则化)来缓解过拟合。另外,还可以采用一些数据增强的技术,如随机旋转、平移或缩放等,来增加训练样本的多样性,提高模型的鲁棒性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 39
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值