迁移学习、fine-tune和局部参数恢复

参考:迁移学习——Fine-tune

一、迁移学习

就是把已训练好的模型参数迁移到新的模型来帮助新模型训练。

模型的训练与预测:
深度学习的模型可以划分为 训练预测 两个阶段。
训练 分为两种策略:一种是白手起家从头搭建模型进行训练,一种是通过预训练模型进行训练。
预测 相对简单,直接用已经训练好的模型对数据集进行预测即可。

优点:

1)站在巨人的肩膀上:前人花很大精力训练出来的模型在大概率上会比你自己从零开始搭的模型要强悍,没有必要重复造轮子。
2)训练成本可以很低:如果采用导出特征向量的方法进行迁移学习,后期的训练成本非常低,用CPU都完全无压力,没有深度学习机器也可以做。
3)适用于小数据集:对于数据集本身很小(几千张图片)的情况,从头开始训练具有几千万参数的大型神经网络是不现实的,因为越大的模型对数据量的要求越大,过拟合无法避免。这时候如果还想用上大型神经网络的超强特征提取能力,只能靠迁移学习。

迁移学习的几种方式:

1、Transfer Learning:冻结预训练模型的全部卷积层,只训练自己定制的全连接层。

2、Extract Feature Vector:先计算出预训练模型的卷积层对所有训练和测试数据的特征向量,然后抛开预训练模型,只训练自己定制的简配版全连接网络。
3、Fine-tune:冻结预训练模型的部分卷积层(通常是靠近输入的多数卷积层),训练剩下的卷积层(通常是靠近输出的部分卷积层)和全连接层。
* 注:Transfer Learning关心的问题是:什么是“知识”以及如何更好地运用之前得到的“知识”,这可以有很多方法和手段,eg:SVM,贝叶斯,CNN等。

而fine-tune只是其中的一种手段,更常用于形容迁移学习的后期微调中。

三种迁移学习方式对比

1、第一种和第二种训练得到的模型本质上并没有什么区别,但是第二种的计算复杂度要远远优于第一种。
2、第三种是对前两种方法的补充,以进一步提升模型性能。要注意的是,这种方法并不一定能真的对模型有所提升。
本质上来讲:这三种迁移学习的方式都是为了让预训练模型能够胜任新数据集的识别工作,能够让预训练模型原本的特征提取能力得到充分的释放和利用。但是,在此基础上如果想让模型能够达到更低的Loss,那么光靠迁移学习是不够的,靠的更多的还是模型的结构以及新数据集的丰富程度。

二、实验:尝试对模型进行微调,以进一步提升模型性能

1、fine-tune的作用:

拿到新数据集,先用预训练模型处理,通常用上面的方法一或方法二测试预训练模型在新数据上的表现,如果表现不错,可以尝试fine-tune,进一步解锁卷积层以继续训练。

但是不要期待质的飞跃,另外,如果由于新数据集与原数据集差别太大导致表现很差,一方面可以考虑从头训练,另一方面也可以考虑解锁比较多层的训练。

2、不同数据集下使用微调

数据集1:数据量少,但数据相似度非常高

在这种情况下,我们所做的只是修改最后几层或最终的softmax图层的输出类别,方法一

数据集2:数据量少,数据相似度低

在这种情况下,我们可以冻结预训练模型的初始层(比如k层),并再次训练剩余的(n-k)层。由于新数据集的相似度较低,因此根据新数据集对较高层进行重新训练具有重要意义。方法三

数据集3:数据量大,数据相似度低

在这种情况下,由于我们有一个大的数据集,我们的神经网络训练将会很有效。但是,由于我们的数据与用于训练我们的预训练模型的数据相比有很大不同。使用预训练模型进行的预测不会有效。因此,最好根据你的数据从头开始训练神经网络(Training from scatch)。

数据集4:数据量大,相似度高

这是理想情况。在这种情况下,预训练模型应该是最有效的。使用模型的最好方法是保留模型的体系结构和模型的初始权重。然后,我们可以使用在预先训练的模型中的权重来重新训练该模型。

3.微调的注意事项
1)通常的做法是截断预先训练好的网络的最后一层(softmax层),并用与我们自己的问题相关的新的softmax层替换它。
2)使用较小的学习率来训练网络。
3)如果数据集数量过少,我们进来只训练最后一层,如果数据集数量中等,冻结预训练网络的前几层的权重也是一种常见做法。

注:卷积神经网络的核心是:
(1)浅层卷积层提取基础特征,比如边缘,轮廓等基础特征。
(2)深层卷积层提取抽象特征,比如整个脸型。
(3)全连接层根据特征组合进行评分分类。

4、实验操作具体步骤

1、下载预训练模型

2、预处理:按照预训练模型原本的预处理方式对数据进行预处理,使用预训练模型一定要确保让待训练的数据尽可能向原数据集靠拢,这样才能最大程度发挥模型的识图本领。

3、基模型和定制模型:构建和预训练里面完全相同的模型。

4、查看固定和恢复节点名

5、训练过程设置恢复,固定张量的列表

三、代码详情

基模型和定制模型

import slim.nets.resnet_v1 as resnet_v1

# 定义模型,因为给出的只有参数,并没有模型,这里需要指定模型的具体结构
    with slim.arg_scope(resnet_v1.resnet_arg_scope()):
        # logits就是最后预测值,images就是输入数据,指定num_classes=None是为了使resnet模型最后的输出层禁用
        logits, end_points = resnet_v1.resnet_v1_50(inputs=input_images, num_classes=None)

    # 自定义的输出层
    with tf.variable_scope("Logits"):
        # 将原始模型的输出数据去掉维度为2和3的维度,最后只剩维度1的batch数和维度4的300*300*3
        # 也就是将原来的二三四维度全部压缩到第四维度
        net = tf.squeeze(logits, axis=[1, 2])
        # 加入一层dropout层
        net = slim.dropout(net, keep_prob=0.5, scope=‘dropout_scope‘)
        # 加入一层全连接层,指定最后输出大小
        logits = slim.fully_connected(net, num_outputs=labels_nums, scope=‘fc‘)

查看固定和恢复节点名

look_checkpoint.py

import os
from tensorflow.python import pywrap_tensorflow

model_dir = os.getcwd() # 获取当前文件工作路径
print(model_dir)#输出当前工作路径
checkpoint_path = r‘G:\1-modelused\Siamese_Densenet_Single_Net\output\640model\model3/model_epoch_20.ckpt‘#model_dir + "\\ckpt_dir\\model-ckpt-100"

print(checkpoint_path)#输出读取的文件路径
# 从checkpoint文件中读取参数
reader = pywrap_tensorflow.NewCheckpointReader(checkpoint_path)
var_to_shape_map = reader.get_variable_to_shape_map()
# 输出变量名称及变量值
for key in var_to_shape_map:
    # if key.startswith(‘DenseNet_121/AuxLogits‘):

    #     print(1)
    #     print(key)
    print("tensor_name: ", key)

训练过程设置恢复,固定张量的列表

CKPT_FILE = r‘.\pretrain\resnet_v1_50.ckpt‘
#不需要从谷歌训练好的模型中加载的参数。这里就是最后的全连接层,因为在新的问题中要重新训练这一层中的参数。
#这里给出的是参数的前缀
CHECKPOINT_EXCLUDE_SCOPES = ‘Logits‘
## 指定最后的全连接层为可训练的参数,需要训练的网络层参数名称,在fine-tuning的过程中就是最后的全连接层
TRAINABLE_SCOPES = ‘Logits‘

#获取所有需要从谷歌训练好的模型中加载的参数
def get_tuned_variables():
    exclusions = [scope.strip() for scope in CHECKPOINT_EXCLUDE_SCOPES.split(‘,‘)]
    variables_to_restore = []
    #枚举inception-v3模型中所有的参数,然后判断是否需要从加载列表中移除
    for var in slim.get_model_variables():
        excluded = False
        for exclusion in exclusions:
            if var.op.name.startswith(exclusion):
                excluded = True
                break
        if not excluded:
            variables_to_restore.append(var)
    return variables_to_restore

#获取所有需要训练的变量列表。
def get_trainable_variables():
    scopes = [scope.strip() for scope in TRAINABLE_SCOPES.split(‘,‘)]
    variables_to_train = []
    #枚举所有需要训练的参数前缀,并通过这些前缀找到所有的参数。
    for scope in scopes:
        variables = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES,scope)
        variables_to_train.extend(variables)
    return variables_to_train

#定义加载Google训练好的Inception-v3模型的Saver
    load_fn = slim.assign_from_checkpoint_fn(
        CKPT_FILE,
        get_tuned_variables(),
        ignore_missing_vars=True
    )

    saver = tf.train.Saver(max_to_keep=100)
    max_acc = 0.0
    with tf.Session() as sess:
        ckpt = tf.train.get_checkpoint_state(‘models/resnet_v1/‘)
        if ckpt and tf.train.checkpoint_exists(ckpt.model_checkpoint_path):
            saver.restore(sess, ckpt.model_checkpoint_path)
        else:
            sess.run(tf.global_variables_initializer())
            sess.run(tf.local_variables_initializer())
            # 加载谷歌已经训练好的模型
            print(‘Loading tuned variables from %s‘ % CKPT_FILE)
            load_fn(sess)

原文地址:https://www.cnblogs.com/qqw-1995/p/11423203.html

时间: 2024-08-30 07:37:43

迁移学习、fine-tune和局部参数恢复的相关文章

caffe简易上手指南(三)—— 使用模型进行fine tune

之前的教程我们说了如何使用caffe训练自己的模型,下面我们来说一下如何fine tune. 所谓fine tune就是用别人训练好的模型,加上我们自己的数据,来训练新的模型.fine tune相当于使用别人的模型的前几层,来提取浅层特征,然后在最后再落入我们自己的分类中. fine tune的好处在于不用完全重新训练模型,从而提高效率,因为一般新训练模型准确率都会从很低的值开始慢慢上升,但是fine tune能够让我们在比较少的迭代次数之后得到一个比较好的效果.在数据量不是很大的情况下,fin

TensorFlow从1到2(九)迁移学习

迁移学习基本概念 迁移学习是这两年比较火的一个话题,主要原因是在当前的机器学习中,样本数据的获取是成本最高的一块.而迁移学习可以有效的把原有的学习经验(对于模型就是模型本身及其训练好的权重值)带入到新的领域,从而不需要过多的样本数据,也能达到大批量数据所达成的效果,进一步节省了学习的计算量和时间. MobileNet V2是由谷歌在2018年初发布的一个视觉模型,在Keras中已经内置的并使用ImageNet完成了训练,可以直接拿来就用,这个我们在本系列第五篇中已经提过了.MobileNet V

百分点认知智能实验室出品:深度迁移学习十八问

编者按 深度迁移学习是基于深度神经网络的迁移学习方法,BERT通过预训练模型达到深度迁移学习的效果,自从2018年底BERT横空出世以来,就以势不可挡的姿态横扫了众多榜单,甚至在阅读理解任务SQuAD 中超越人类水平.BERT在公检法.媒体出版.军工.快消零售等工业界也迅速落地,如百分点智能对话系统.百分点智能审校系统和百分点智能翻译系统等.BERT几乎在所有的下游任务中效果都获得了明显提升,BERT自此开创了一个NLP的新时代,那就是pre-train + fine-tuning的时代. 基于

迁移学习(Transfer Learning)(转载)

原文地址:http://blog.csdn.net/miscclp/article/details/6339456 在传统的机器学习的框架下,学习的任务就是在给定充分训练数据的基础上来学习一个分类模型:然后利用这个学习到的模型来对测试文档进行分类与预测.然而,我 们看到机器学习算法在当前的Web挖掘研究中存在着一个关键的问题:一些新出现的领域中的大量训练数据非常难得到.我们看到Web应用领域的发展非常快速.大量新的领域不断涌现,从传统的新闻,到网页,到图片,再到博客.播客等等.传统的机器学习需要

『TensorFlow』迁移学习_他山之石,可以攻玉

目的: 使用google已经训练好的模型,将最后的全连接层修改为我们自己的全连接层,将原有的1000分类分类器修改为我们自己的5分类分类器,利用原有模型的特征提取能力实现我们自己数据对应模型的快速训练.实际中对于一个陌生的数据集,原有模型经过不高的迭代次数即可获得很好的准确率. 实战: 实机文件夹如下,两个压缩文件可以忽略: 花朵图片数据下载: 1 curl -O http://download.tensorflow.org/example_images/flower_photos.tgz 已经

迁移学习( Transfer Learning )

在传统的机器学习的框架下,学习的任务就是在给定充分训练数据的基础上来学习一个分类模型:然后利用这个学习到的模型来对测试文档进行分类与预测.然而,我们看到机器学习算法在当前的Web挖掘研究中存在着一个关键的问题:一些新出现的领域中的大量训练数据非常难得到.我们看到Web应用领域的发展非常快速.大量新的领域不断涌现,从传统的新闻,到网页,到图片,再到博客.播客等等.传统的机器学习需要对每个领域都标定大量训练数据,这将会耗费大量的人力与物力.而没有大量的标注数据,会使得很多与学习相关研究与应用无法开展

增强学习、增量学习、迁移学习——概念性认知

一.增强学习/强化学习(Reinforcement Learning ) 我们总是给定一个样本x,然后给或者不给label y.之后对样本进行拟合.分类.聚类或者降维等操作.然而对于很多序列决策或者控制问题,很难有这么规则的样本.比如,四足机器人的控制问题,刚开始都不知道应该让其动那条腿,在移动过程中,也不知道怎么让机器人自动找到合适的前进方向.另外如要设计一个下象棋的AI,每走一步实际上也是一个决策过程,虽然对于简单的棋有A*的启发式方法,但在局势复杂时,仍然要让机器向后面多考虑几步后才能决定

迁移学习全面概述:从基本概念到相关研究

目录: 1.什么是迁移学习? 2.为什么现在需要迁移学习? 3.迁移学习的定义 4.迁移学习的场景 5.迁移学习的应用 从模拟中学习 适应到新的域 跨语言迁移知识 6.迁移学习的方法 使用预训练的 CNN 特征 学习域不变的表征 让表征更加相似 混淆域 7.相关的研究领域 半监督学习 更有效地使用可用的数据 提高模型的泛化能力 让模型更加稳健 多任务学习 持续学习 zero-shot 学习 8.总结 ------------------------------------------------

tensorflow实现迁移学习

此例程出自<TensorFlow实战Google深度学习框架>6.5.2小节 卷积神经网络迁移学习. 数据集来自http://download.tensorflow.org/example_images/flower_photos.tgz ,及谷歌提供的Inception-v3模型https://storage.googleapis.com/download.tensorflow.org/models/inception_dec_2015.zip . 自行下载和解压. 解压后的文件夹包含5个子