【微调】李沐深度学习课程笔记

文章目录

      • 37:微调
        • 37-1:理论
        • 37-2:代码

课程链接:https://www.bilibili.com/video/BV1Sb4y1d7CR?spm_id_from=333.788.player.switch&vd_source=ecf655ee5d145d3636627119e18132ed&p=2

37:微调

37-1:理论

标注一个数据集很贵

  • ImageNet标注了一千多万张图片,但是实际使用的只有120 万张图片,类别数是1000,它算是一个比较大的数据集
  • Fashion-MNIST一共有6 万张图片,类别数是10, 算是一个比较小的数据集
  • 通常自己的数据集规模通常在这两者之间,大概在5 万张图片左右,类别数大概是100左右,平均下来每一类物体大概有500张图片左右

适合 ImageNet 的复杂模型可能会在自己的数据集上过拟合,另外由于训练样本有限,训练模型的准确性可能无法满足实际要求,解决以上问题有两种解决方案:

1、收集更多的数据。数据集越大越好,但是收集和标记数据可能需要大量的时间和金钱。

2、应用迁移学习(transfer leanring)。将从源数据集学到的知识迁移到目标数据集,通常来说希望在大数据集上训练好的模型能够提取到更通用的图像特征,有助于识别边缘纹理形状对象组合,从而帮助提升在自己数据集上的精度,核心思想是假设模型对整个物体识别有一定的基础的情况下,不需要自己提供太大的数据集就能够获得很好的识别精度,这也是人工智能所追求的目标

网络架构

一个神经网络一般可以分为两块,一部分做特征提取,一部分做线性分类

  • 假设将一张图像输入到模型中,可以认为最下面的一部分是在进行特征提取(特征抽取就是将原始像素变成容易线性分割的特征,深度学习的突破性进展就在于特征提取是可以学习的,而不用人工思考如何提供特征)
  • 最后一部分就是一个全连接层和 softmax 来进行分类(可以认为是一个简单的线性分类器:Softmax 回归。

微调

  • 假设在源数据集(一个比较大的数据集)上已经训练好了一个模型,模型中特征提取的部分对源数据集是有效的,那么它对目标数据集也应该是有效的。
  • 最后一部分是不能直接使用的,因为标号发生了改变,所以最后一部分难以进行重用
  • 微调的核心思想是:在一个比较大的源数据集上训练好的模型中用于特征提取的部分,在目标数据集上提取特征时进行重用

微调中的权重初始化

微调包括四个步骤:

  1. 在源数据集(例如 ImageNet 数据集)上预训练神经网络模型,即源模型(pre-train model)
  2. 创建一个新的神经网络模型,即目标模型。新模型的初始化不再是随机的初始化,而是复制源模型上的所有模型设计及其参数(输出层除外)。假定这些模型参数包含从源数据集中学到的知识,这些知识也将适用于目标数据集,使得新模型在一开始就能很好地提取特征;同时假设源模型的输出层与源数据集的标签密切相关,因此不在目标模型中使用该层
  3. 向目标模型添加输出层,其输出数是目标数据集中的类别数,然后随机初始化该层的模型参数(最后的分类部分由于标号不同,因此还是做随机初始化)
  4. 在目标数据集上训练目标模型。输出层将从头开始进行训练,而所有其他层的参数将根据源模型的参数进行微调
  • 因为损失 Loss 是从后往前进行传递的,所以最后的分类部分训练比较快,进行随机初始化也不会有太大的影响;而前面的特征提取的部分本身已经具备很好的特征提取效果,只是根据源数据集和目标数据集的差异进行微调,可能在最开始训练的时候就已经比较接近最终的结果,所以不用做过多的训练和变动

训练

是一个目标数据集上的正常训练任务,但使用更强的正则化(如果不使用预训练模型,直接在自己的数据集上正常训练,在时间足够的情况下也是可以从随机初始化训练到完全 fitting 自己的数据集,但是可能会导致 Overfitting ,这是没有必要的,不如对预训练模型进行微调)

  • 使用更小的学习率(已经比较接近最优解了,因此不需要太大的学习率)
  • 使用更少的数据迭代

源数据集远远复杂于目标数据集,通常微调的效果更好

  • 源数据集的类别数图片数量样本个数通常是目标数据集的10 倍或者 100 倍,才能达到很好的微调效果,否则微调的效果不如直接在目标数据集上进行重新训练

重用分类器权重

  • 源数据集中可能也有目标数据中的标号
  • 可以使用预训练好的模型分类器中对应标号对应的向量来做初始化

固定一些层

神经网络通常学习有层次的特征表示

  • 低层次的特征更加通用(越低层次学习的是一些底层的细节)
  • 高层次的特征则更跟数据集相关(越高层次则更加语义化)
  • 可以认为越到后面和标号的关联度越大,约到前面则越低层,所以底层的特征更加通用,高层的特征和数据的关联度更大

可以固定底部一些层的参数,不参与更新(不做优化,在微调的时候不改变底层类别的权重,因为这些参数不再发生变化,所以模型的复杂度变低了,可以认为是更强的正则的效果)

  • 更强的正则

通常来说,假设数据集很小,直接训练很容易过拟合的情况下,可以固定底部的一些参数不参与更新

总结

1、微调通过使用在大数据上得到的预训练好的模型来初始化目标数据集上的模型权重来完成提升精度

2、预训练模型质量很重要

3、微调通常速度更快,精度更高(可以借助在大数据集上所获得的先验知识)

4、建议尽量从微调开始训练,不要直接从目标数据集上从零开始进行训练

  • 未来从原始数据集上进行训练的会越来越少,主要是学术界或者大公司在很大的数据集上进行重新训练
  • 对于个人或者实际应用来讲,通常是使用微调

5、迁移学习将从源数据集中学到的知识“迁移”到目标数据集,微调迁移学习的常见技巧

6、除输出层外,目标模型从源模型中复制所有模型设计及其参数,并根据目标数据集对这些参数进行微调,但是目标模型的输出层需要从头开始训练

7、通常微调参数使用较小的学习率,而从头开始训练输出层可以使用更大的学习率

37-2:代码
importosimporttorchimporttorchvisionfromtorchimportnnfromd2limporttorchasd2l data_dir=r'D:\pycharm-code\data\hotdog'

创建两个实例来分别读取训练和测试数据集中的所有图像文件。

train_imgs=torchvision.datasets.ImageFolder(os.path.join(data_dir,'train'))test_imgs=torchvision.datasets.ImageFolder(os.path.join(data_dir,'test'))

下面显示了前8个正类样本图片和最后8张负类样本图片。正如所看到的,图像的大小和纵横比各有不同。

hotdogs=[train_imgs[i][0]foriinrange(8)]not_hotdogs=[train_imgs[-i-1][0]foriinrange(8)]d2l.show_images(hotdogs+not_hotdogs,2,8,scale=1.4);

在训练期间,我们首先从图像中裁切随机大小和随机长宽比的区域,然后将该区域缩放为224×224输入图像。 在测试过程中,我们将图像的高度和宽度都缩放到256像素,然后裁剪中央224×224区域作为输入。 此外,对于RGB(红、绿和蓝)颜色通道,我们分别标准化每个通道。 具体而言,该通道的每个值减去该通道的平均值,然后将结果除以该通道的标准差。

  • RandomResizedCrop(224)(训练用):随机裁剪 + 缩放成 224×224,增加数据多样性(比如不同区域的热狗图),避免模型只记住固定位置的特征,减少过拟合。
  • RandomHorizontalFlip()(训练用):随机水平翻转图像,同样是数据增强 —— 现实中热狗可以正放 / 反放,模型需要对这种变化不敏感。
  • Resize([256, 256]) + CenterCrop(224)(测试用):测试时不能随机操作(否则结果不稳定),先放大到 256 再居中裁剪到 224,是 ImageNet 标准的测试预处理方式。

标准化的均值 / 方差来自 ImageNet 数据集的统计值,这么做的核心原因是:

  1. 预训练模型的 “输入分布对齐”

    你后续用的模型(比如 ResNet、VGG 等)大概率是在ImageNet 数据集上预训练的,而这些预训练模型在训练时,输入图像就是用这个均值 / 方差做的标准化。

    如果你的数据不做同样的标准化,输入的像素分布和预训练时差异太大,预训练的权重就会 “失效”(模型学到的特征和新输入不匹配)。

  2. 为什么自己的数据集也要用?

    这是迁移学习的要求:当你基于 ImageNet 预训练模型做 “热狗分类”(小数据集任务)时,必须保持 “数据预处理流程和预训练一致”,才能最大化复用预训练的特征提取能力。

    (如果是从头训练自己的数据集,其实应该用自己数据集的均值 / 方差;但迁移学习必须对齐预训练的预处理)

# 使用RGB通道的均值和标准差,以标准化每个通道。左边是RGB通道的mean,右边是RGB通道的std(因为imagenet做了这样的标准化,)normalize=torchvision.transforms.Normalize([0.485,0.456,0.406],[0.229,0.224,0.225])train_augs=torchvision.transforms.Compose([torchvision.transforms.RandomResizedCrop(224),torchvision.transforms.RandomHorizontalFlip(),torchvision.transforms.ToTensor(),normalize])test_augs=torchvision.transforms.Compose([torchvision.transforms.Resize([256,256]),torchvision.transforms.CenterCrop(224),torchvision.transforms.ToTensor(),normalize])

使用在ImageNet数据集上预训练的ResNet-18作为源模型。 在这里,我们指定==pretrained=True==以自动下载预训练的模型参数。 首次使用此模型,需要连网下载。

pretrained_net = torchvision.models.resnet18(pretrained=True)

预训练的源模型实例包含许多特征层和一个输出层fc。 此划分的主要目的是促进对除输出层以外所有层的模型参数进行微调。 下面给出了源模型的成员变量fc,

pretrained_net.fc

这个输出展示了源网络中分类层的结构:

Linear(in_features=512, out_features=1000, bias=True)

在ResNet的全局平均汇聚层后,全连接层转换为ImageNet数据集的1000个类输出。 之后,我们构建一个新的神经网络作为目标模型。 它的定义方式与预训练源模型的定义方式相同,只是最终层中的输出数量被设置为目标数据集中的类数(而不是1000个)。

所以finetune_net.fc.in_features是512的输入,但是类别数只有2

finetune_net=torchvision.models.resnet18(pretrained=True)finetune_net.fc=nn.Linear(finetune_net.fc.in_features,2)#只对最后一层进行随机初始化nn.init.xavier_uniform_(finetune_net.fc.weight)

定义了一个训练函数train_fine_tuning,该函数使用微调,因此可以多次调用。

由于模型参数是在ImageNet数据集上预训练的,并且足够好,因此通常只需要较小的学习率即可微调这些参数。

成员变量output的参数是随机初始化的,通常需要更高的学习率才能从头开始训练。 假设Trainer实例中的学习率为r,我们将成员变量output中参数的学习率设置为10r。

# 如果param_group=True,输出层中的模型参数将使用十倍的学习率,deftrain_fine_tuning(net,learning_rate,batch_size=128,num_epochs=5,param_group=True):train_iter=torch.utils.data.DataLoader(torchvision.datasets.ImageFolder(os.path.join(data_dir,'train'),transform=train_augs),batch_size=batch_size,shuffle=True)test_iter=torch.utils.data.DataLoader(torchvision.datasets.ImageFolder(os.path.join(data_dir,'test'),transform=test_augs),batch_size=batch_size)devices=d2l.try_all_gpus()or[torch.device('cpu')]loss=nn.CrossEntropyLoss(reduction="none")ifparam_group:params_1x=[paramforname,paraminnet.named_parameters()ifnamenotin["fc.weight","fc.bias"]]trainer=torch.optim.SGD([{'params':params_1x},{'params':net.fc.parameters(),'lr':learning_rate*10}],lr=learning_rate,weight_decay=0.001)else:trainer=torch.optim.SGD(net.parameters(),lr=learning_rate,weight_decay=0.001)d2l.train_ch13(net,train_iter,test_iter,loss,trainer,num_epochs,devices)

使用较小的学习率,通过微调预训练获得的模型参数。

train_fine_tuning(finetune_net,5e-5)
loss 0.177, train acc 0.932, test acc 0.943 968.4 examples/sec on [device(type='cuda', index=0), device(type='cuda', index=1)]

知识补充:

微调意味着神经网络在进行不同的目标检测时,前面层的网络进行的特征提取是通用的,且越前层越通用。

当目标数据集和源数据集的内容种类相差过大(比如识别癌细胞图片,与日常图片的imagenet差别较大)时,微调的效果可能不好

目标与源数据集差不多,并且可能出现交集或包含,微调 效果可能好很多

微调属于一种迁移学习算法。

基于大规模数据集训练出的源模型是一种财产,被大公司所保密。但基于imgnet训练的模型用于学术研究还是够用的。

在微调中,为了归一化保持一致非常重要。在本节代码中的normalize里的参数是根据imgnet计算出来的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1151191.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从照片到骨骼图:MediaPipe镜像手把手教学

从照片到骨骼图:MediaPipe镜像手把手教学 在智能健身镜中实时纠正深蹲姿势、通过普通摄像头捕捉舞蹈动作驱动虚拟角色、远程康复系统自动分析患者步态——这些看似复杂的交互背后,都依赖于一项正在普及的关键技术:人体骨骼关键点检测。而今天…

SpringBoot+Vue 人事系统管理平台源码【适合毕设/课设/学习】Java+MySQL

摘要 在信息化快速发展的时代背景下,企业人事管理逐渐从传统的手工操作转向数字化、智能化。传统的人事管理方式效率低下,容易出错,且难以满足现代企业对人力资源的高效管理需求。随着互联网技术的普及,基于Web的人事管理系统成为…

人体姿态估计实战:MediaPipe

人体姿态估计实战:MediaPipe 1. 引言:AI 人体骨骼关键点检测的现实价值 随着计算机视觉技术的不断演进,人体姿态估计(Human Pose Estimation)已成为智能健身、动作捕捉、虚拟试衣、安防监控等场景中的核心技术之一。…

提示工程架构师总结:产品管理中用Prompt提升用户满意度的策略

提示工程架构师总结:产品管理中用Prompt提升用户满意度的策略 关键词:提示工程、产品管理、用户满意度、Prompt策略、用户体验、人工智能、产品优化 摘要:本文深入探讨在产品管理领域,如何借助提示工程中的Prompt策略来显著提升用…

智能家居中Zigbee无线组网核心要点全面讲解

Zigbee如何撑起整个智能家居的无线骨架?一文讲透组网核心逻辑你有没有遇到过这种情况:家里的智能灯明明在App里显示“已连接”,可就是不听使唤;或者半夜人体传感器突然失联,安防系统形同虚设?很多人第一反应…

快速理解异或门硬件架构:基于与非门的构建方法

从与非门到异或门:一场数字逻辑的“变形记”你有没有想过,一个看似简单的“不同则输出1”的逻辑——异或门(XOR),在硬件层面其实并不像它表面那么“轻巧”?而在没有专用异或单元的芯片里,工程师…

MediaPipe Pose效果惊艳!舞蹈动作捕捉案例展示

MediaPipe Pose效果惊艳!舞蹈动作捕捉案例展示 1. 引言:从舞蹈到AI——姿态估计的现实应用 1.1 舞蹈教学中的技术痛点 在现代舞蹈教学与训练中,动作标准化和姿态纠正一直是核心挑战。传统方式依赖教练肉眼观察,主观性强、反馈延…

AI姿态估计技术解析:MediaPipe Pose模型架构详解

AI姿态估计技术解析:MediaPipe Pose模型架构详解 1. 技术背景与核心挑战 随着计算机视觉技术的快速发展,人体姿态估计(Human Pose Estimation)已成为智能健身、动作捕捉、虚拟现实和人机交互等领域的关键技术。其核心目标是从单…

人体动作分析系统:MediaPipe Pose部署与优化

人体动作分析系统:MediaPipe Pose部署与优化 1. 引言:AI 人体骨骼关键点检测的工程价值 随着计算机视觉技术的发展,人体姿态估计(Human Pose Estimation)已成为智能健身、虚拟试衣、动作捕捉、人机交互等场景的核心支…

零基础玩转骨骼关键点检测:MediaPipe镜像保姆级教程

零基础玩转骨骼关键点检测:MediaPipe镜像保姆级教程 1. 引言:为什么你需要关注人体骨骼关键点检测? 在计算机视觉的众多分支中,人体姿态估计(Human Pose Estimation)正迅速成为智能交互、运动分析、虚拟现…

vivado2023.2下载安装教程:项目应用前的环境验证方法

Vivado 2023.2 安装全攻略:从下载到环境验证,一步到位打造稳定FPGA开发平台 你是不是也经历过这样的场景?好不容易下完几十GB的Vivado安装包,结果安装到一半卡死;或者刚打开软件就弹出“License not available”警告&…

MediaPipe Pose部署教程:33个关键点检测代码实例详解

MediaPipe Pose部署教程:33个关键点检测代码实例详解 1. 引言 1.1 AI 人体骨骼关键点检测的应用价值 随着计算机视觉技术的快速发展,人体姿态估计(Human Pose Estimation)已成为智能健身、动作捕捉、虚拟试衣、安防监控等领域的…

AI姿态估计入门必看:MediaPipe Pose极速CPU版使用手册

AI姿态估计入门必看:MediaPipe Pose极速CPU版使用手册 1. 技术背景与应用价值 随着人工智能在计算机视觉领域的深入发展,人体姿态估计(Human Pose Estimation)已成为智能健身、动作捕捉、虚拟试衣、人机交互等场景的核心技术之一…

网站信息管理系统源码-SpringBoot后端+Vue前端+MySQL【可直接运行】

摘要 随着信息技术的快速发展,网站信息管理系统成为企业和机构高效管理数据的重要工具。传统的静态网站或单一架构的系统在灵活性、扩展性和维护性方面存在明显不足,无法满足现代动态业务需求。基于此,开发一套集成前后端技术的网站信息管理系…

人体骨骼检测案例:MediaPipe Pose在体育分析中

人体骨骼检测案例:MediaPipe Pose在体育分析中的应用 1. 引言:AI 人体骨骼关键点检测的现实价值 随着人工智能技术在计算机视觉领域的深入发展,人体姿态估计(Human Pose Estimation)已成为智能健身、运动分析、虚拟现…

elasticsearch 201状态码在日志分析中的实际意义(核心要点)

深入理解 Elasticsearch 的 201 状态码:日志写入成功的真正信号在现代云原生架构中,日志不再是简单的调试输出,而是系统可观测性的核心支柱。每天数以亿计的日志事件被采集、索引、分析,支撑着故障排查、安全审计和业务监控。而在…

视频动作分析神器:MediaPipe骨骼检测镜像避坑指南

视频动作分析神器:MediaPipe骨骼检测镜像避坑指南 1. 引言:为什么选择MediaPipe做动作分析? 在智能健身、远程康复、体育训练等领域,人体姿态估计(Human Pose Estimation)正成为核心技术。通过精准识别视…

AI骨骼关键点检测:MediaPipe Pose模型蒸馏

AI骨骼关键点检测:MediaPipe Pose模型蒸馏 1. 技术背景与应用价值 随着人工智能在计算机视觉领域的深入发展,人体姿态估计(Human Pose Estimation)已成为智能健身、动作捕捉、虚拟现实和人机交互等场景的核心技术之一。其核心目…

MediaPipe Pose性能优化指南:让骨骼检测速度提升3倍

MediaPipe Pose性能优化指南:让骨骼检测速度提升3倍 1. 引言:为什么需要优化MediaPipe Pose? 随着AI在健身指导、动作识别、虚拟试衣等场景的广泛应用,实时人体姿态估计已成为智能交互系统的核心能力之一。Google开源的 MediaPi…

健身动作分析实战:MediaPipe Pose镜像快速搭建教程

健身动作分析实战:MediaPipe Pose镜像快速搭建教程 1. 引言:为什么需要本地化人体骨骼关键点检测? 在智能健身、运动康复和体态评估等场景中,精准的人体姿态识别是实现自动化分析的核心前提。传统依赖云端API或复杂深度学习框架…