当前位置: 首页 > news >正文

详解迁移学习,模型参数冻结,优化器参数定义

目录

  • 前言
  • 冻结参数的原理
    • 模型参数全部冻结
    • 模型参数部分冻结
    • 冻结预训练模型部分层并修改最后一层
  • 优化器
    • 优化器的作用
    • 直接传入参数生成器或参数列表
    • 传入参数组字典列表

前言

在使用预训练模型的时候能因为某些原因无需对模型的参数进行全部更新,这时候我们可能希望将其部分参数或者全部参数进行冻结。这里简单总结一些冻结模型参数的方法。

冻结参数的原理

requires_grad 属性的作用
在 PyTorch 中,每个 torch.Tensor 都有一个 requires_grad 属性,这个属性决定了该张量在反向传播过程中是否需要计算梯度。当 requires_gradTrue 时,PyTorch 会跟踪该张量上的所有操作,并在调用 backward() 方法时计算其梯度;当 requires_gradFalse 时,PyTorch 不会跟踪该张量的操作,也就不会计算其梯度。
在神经网络中,模型的参数本质上就是 torch.Tensor 对象,通过设置参数的 requires_grad 属性,我们可以控制哪些参数参与训练(即计算梯度并更新),哪些参数不参与训练(即冻结)。

模型参数全部冻结

import torch
import torch.nn as nnmodel = nn.Sequential(nn.Linear(10, 20),nn.ReLU(),nn.Linear(20, 1)
)for param in model.parameters():param.requires_grad = False
  • 原理:model.parameters() 是一个生成器,返回的是一个生成器对象,它会迭代返回模型中所有需要计算梯度的参数(即 requires_grad 为 True 的参数)。通过遍历这个生成器,将每个参数的 requires_grad 属性设置为 False,就可以实现整体冻结模型参数的目的。

模型参数部分冻结

import torch
import torch.nn as nnclass MyModel(nn.Module):def __init__(self):super(MyModel, self).__init__()self.conv1 = nn.Conv2d(3, 16, kernel_size=3)self.fc1 = nn.Linear(16 * 10 * 10, 10)def forward(self, x):x = self.conv1(x)x = x.view(-1, 16 * 10 * 10)x = self.fc1(x)return xmodel = MyModel()
for name, param in model.named_parameters():if 'conv' in name:param.requires_grad = False
  • 原理:model.named_parameters() 也是一个生成器,返回的也是一个生成器对象,每次迭代返回一个元组 (name, param),其中 name 是参数的名称(字符串类型),param 是对应的参数张量(torch.Tensor 类型)。通过检查参数名称中是否包含特定的字符串(如 ‘conv’),我们可以筛选出需要冻结的参数,并将其 requires_grad 属性设置为 False

冻结预训练模型部分层并修改最后一层

from torchvision.models import resnet18
import torch.nn as nnmodel = resnet18(pretrained=True)for param in model.parameters():param.requires_grad = Falsenum_ftrs = model.fc.in_features
model.fc = nn.Linear(num_ftrs, 1)
  • 原理:首先,通过遍历 model.parameters() 并将所有参数的 requires_grad 属性设置为 False,冻结了整个预训练模型的参数。然后,我们获取原最后一层全连接层的输入特征数 num_ftrs,并创建一个新的全连接层 nn.Linear(num_ftrs, 1) 替换原最后一层。新创建的层的参数的 requires_grad 属性默认是 True,因此只有这一层的参数会在训练时计算梯度并更新。

优化器

上面介绍了怎么冻结模型参数,冻结参数之后需要对模型的参数进行优化,常见的有两种参数方式,下面也一并介绍下。

优化器的作用

优化器的作用是根据计算得到的梯度来更新模型的参数,以最小化损失函数。在 PyTorch 中,常见的优化器有 SGD、Adam
等,它们都需要传入需要更新的参数。

直接传入参数生成器或参数列表

import torch
import torch.nn as nn
import torch.optim as optimmodel = nn.Sequential(nn.Linear(10, 20),nn.ReLU(),nn.Linear(20, 1)
)optimizer = optim.SGD(model[-1].parameters(), lr=0.001, momentum=0.9)
  • 原理:当我们直接将参数生成器(如 model[-1].parameters())或参数列表传递给优化器时,优化器会将这些参数视为一组,并使用相同的优化超参数(如学习率、动量等)来更新这些参数。在这个例子中,我们只传递了模型最后一层的参数,因此优化器只会更新最后一层的参数。
  • 注意:model[-1].parameters() 返回一个生成器对象,它会迭代返回模型最后一层的所有参数。

传入参数组字典列表

import torch
import torch.nn as nn
import torch.optim as optimmodel = nn.Sequential(nn.Linear(10, 20),nn.ReLU(),nn.Linear(20, 1)
)first_layer_params = list(model[0].parameters())
last_layer_params = list(model[2].parameters())param_list = [{'params': first_layer_params, 'lr': 0.0001},{'params': last_layer_params, 'lr': 0.001}
]optimizer = optim.Adam(param_list)
  • 原理:当我们需要为不同的参数组设置不同的优化超参数时,可以传入一个包含参数组字典的列表。每个字典代表一个参数组,其中 ‘params’ 键对应的值是该参数组的参数列表或参数生成器,还可以包含其他键值对来指定该参数组的特定超参数(如学习率、权重衰减等)。优化器会根据这些参数组的设置,对不同的参数组使用不同的超参数进行优化。

相关文章:

  • 蘑菇管理——AI与思维模型【94】
  • 【运维】构建基于Python的自动化运维平台:用Flask和Celery打造高效管理工具
  • TensorFlow 多卡训练 tf多卡训练
  • Android第四次面试总结之Java基础篇(补充)
  • NPP库中libnppc模块介绍
  • [原创](现代Delphi 12指南):[macOS 64bit App开发]: [1]如何加载动态链接库, 并无缝支持原生底层开发?
  • QpushButton 扩展InteractiveButtonBase
  • 【中间件】brpc_基础_remote_task_queue
  • AI功能测试源码AI聊天AI视觉AI图像AI视频AI画外音写作助手AI测试多语言无加密源码
  • 企业架构革新指南:中台的定义、实践与未来
  • 供应链算法整理(二)--- 智能补货
  • 哈夫曼树和哈夫曼编码
  • 【自存】python使用matplotlib正常显示中文、负号
  • 智能工厂边缘计算:从数据采集到实时决策
  • 【Linux】SELinux 的基本操作与防火墙的管理
  • 力扣-链表-2 两数相加
  • 课程10. 聚类问题
  • js逆向绕过指纹识别
  • 5个情感丰富GPT-4o图像提示词(不是吉卜力风格)
  • PyTorch数据集与数据集加载
  • 外交部就习近平主席将应邀对俄罗斯进行国事访问并出席纪念苏联伟大卫国战争胜利80周年庆典答问
  • 重庆渝中警方:男子点燃摩托车欲寻衅滋事,被民警和群众合力制服
  • 李在明回应韩国大法院判决:与自己所想截然不同,将顺从民意
  • “五一”假期首日国铁郑州局迎大客流,预计发送旅客逾95万人次
  • 车展之战:国产狂飙、外资反扑、智驾变辅助
  • 秦洪看盘|资金切换主线,重构市场风格