迁移学习|代码实现

还记得我们之前实现的猫狗分类器 吗?在哪里,我们设计了一个网络,这个网络接受一张图片,最后输出这张图片属于猫还是狗。实现分类器的过程比较复杂,准备的数据也比较少。所以我们是否可以使用一种方法,在数据很少的情况下仍然可以训练出较好的模型。

借助已经训练好的模型是个不错的想法。因此我们将学习如何使用预训练好的模型来构建只需要很少数据的先进的猫狗图像分类器。

首先,加载一个预训练的模型,例如ResNet18。

借助torchvision库,我们很容易获得一组已经训练好的模型。这些模型大多数接受一个称为pretrained的参数,当这个参数为True时,它会下载为ImageNet分类问题调整好的权重。就像这样:

复制代码
from torchvision import modelsnetwork1=models.resnet18(pretrained=True)

当代码第一次运行时,需要一点时间...

接着,我们需要冻结所有层,所有权重不会随训练而更新。​​​​​​​

复制代码
for param in network1.parameters():    param.requires_grad=False

当然,这个模型并不是针对2分类问题,所以,我们需要将其最后一层的输出特征从1000改为2

首先我们要知道最后一层的名字:​​​​​​​

复制代码
network1ResNet(  (conv1): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)  (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)...  ...  ...  (fc): Linear(in_features=512, out_features=1000, bias=True)

最后一层是个全连接层,名为fc。

所以,我们就可将最后一层替换为输出特征为2的全连接层

复制代码
network1.fc=nn.Linear(512,2)

注:此时,因为该层为新的层,所以其requires_grad=True,这样整个网络仅有这一层可以更新权重

打印网络​​​​​​​

复制代码
network1ResNet(  (conv1): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)  (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)  (relu): ReLU(inplace=True)  (maxpool): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)...  ...  ...  (fc): Linear(in_features=512, out_features=2, bias=True)

此时,network1就是一个符合猫狗分类问题的模型

最后,既然我们只对最后一层训练,那么我们只需要将最后一层的参数传入优化器

复制代码
optimizer=optim.SGD(network1.fc.parameters(),lr=...,momentnum=...)

总结一下代码:​​​​​​​

复制代码
from torchvision import modelsimport torch.nn as nnimport torch.optim as optim#网络搭建network1=models.resnet18(pretrained=True)
for param in network1.parameters():    param.requires_grad=False
network1.fc=nn.Linear(512,2)#损失函数criterion=nn.CrossEntropyLoss()#优化器optimizer=optim.SGD(network1.fc.parameters(),lr=...,momentnum=...)

其实,我们就是利用已经训练好的模型的主要目的就是它已经能够提取出非常好的特征 ,最后一层接受前面层提取的特征,然后误差反向传播,仅更新这一层的权重,不断迭代,最后达到一个非常好的效果。

我们这里只对最后一层进行了调整 ,只训练这一层,主要原因就是数据太少 ;如果数据较多 ,可以把预训练的前面一些层权重固定住,后面层不固定,修改最后一层以满足任务,然后训练;如果数据很多,算力充沛,那么可以对所有层进行精调,只把预训练的模型的参数作为初始化参数。

相关推荐
文心快码 Baidu Comate14 分钟前
双十一将至,用Rules玩转电商场景提效
人工智能·ai编程·文心快码·智能编程助手·comate ai ide
瞻邈21 分钟前
LION运行笔记
人工智能·深度学习
CoovallyAIHub36 分钟前
外科医生离手术世界模型还有多远?首次提出SurgVeo基准,揭示AI生成手术视频的惊人差距
深度学习·算法·计算机视觉
Serverless 社区44 分钟前
助力企业构建 AI 原生应用,函数计算FunctionAI 重塑模型服务与 Agent 全栈生态
大数据·人工智能
大千AI助手1 小时前
参考先验(Reference Priors)详解:理论与Python实践
人工智能·机器学习·贝叶斯·大千ai助手·参考先验·贝叶斯推断·先验
Baihai_IDP1 小时前
面向 LLM 的 GPU 系统工程方法论
人工智能·面试·gpu
北京耐用通信1 小时前
冶金车间“迷雾”重重?耐达讯自动化Profibus转光纤为HMI点亮“透视眼”!
人工智能·物联网·网络协议·网络安全·自动化
xqlily1 小时前
Prover9/Mace4 的形式化语言简介
人工智能·算法
IT_陈寒1 小时前
Redis 高并发实战:我从 5000QPS 优化到 5W+ 的7个核心策略
前端·人工智能·后端
北京耐用通信1 小时前
耐达讯自动化Profibus光纤模块:智能仪表的“生命线”,极端环境通信无忧!
人工智能·物联网·网络协议·自动化·信息与通信