- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章pytorch fine-tune 预训练的模型操作由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
之一
torchvision 中包含了很多预训练好的模型,这样就使得 fine-tune 非常容易。本文主要介绍如何 fine-tune torchvision 中预训练好的模型.
1
|
pip install torchvision
|
如何 fine-tune 。
以 resnet18 为例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
from
torchvision
import
models
from
torch
import
nn
from
torch
import
optim
resnet_model
=
models.resnet18(pretrained
=
True
)
# pretrained 设置为 True,会自动下载模型 所对应权重,并加载到模型中
# 也可以自己下载 权重,然后 load 到 模型中,源码中有 权重的地址。
# 假设 我们的 分类任务只需要 分 100 类,那么我们应该做的是
# 1. 查看 resnet 的源码
# 2. 看最后一层的 名字是啥 (在 resnet 里是 self.fc = nn.Linear(512 * block.expansion, num_classes))
# 3. 在外面替换掉这个层
resnet_model.fc
=
nn.Linear(in_features
=
..., out_features
=
100
)
# 这样就 哦了,修改后的模型除了输出层的参数是 随机初始化的,其他层都是用预训练的参数初始化的。
# 如果只想训练 最后一层的话,应该做的是:
# 1. 将其它层的参数 requires_grad 设置为 False
# 2. 构建一个 optimizer, optimizer 管理的参数只有最后一层的参数
# 3. 然后 backward, step 就可以了
# 这一步可以节省大量的时间,因为多数的参数不需要计算梯度
for
para
in
list
(resnet_model.parameters())[:
-
2
]:
para.requires_grad
=
False
optimizer
=
optim.SGD(params
=
[resnet_model.fc.weight, resnet_model.fc.bias], lr
=
1e
-
3
)
...
|
这里介绍下 运行resnet_model.fc= nn.Linear(in_features=..., out_features=100)时 框架内发生了什么 。
这时应该看 nn.Module 源码的 __setattr__ 部分,因为 setattr 时都会调用这个方法:
1
2
3
4
5
|
def
__setattr__(
self
, name, value):
def
remove_from(
*
dicts):
for
d
in
dicts:
if
name
in
d:
del
d[name]
|
首先映入眼帘就是 remove_from 这个函数,这个函数的目的就是,如果出现了 同名的属性,就将旧的属性移除。 用刚才举的例子就是:
预训练的模型中 有个 名字叫fc 的 Module.
在类定义外,我们 将另一个 Module 重新 赋值给了 fc.
类定义内的 fc 对应的 Module 就会从 模型中 删除.
之二
这篇文章算是论坛PyTorch Forums关于参数初始化和finetune的总结,也是我在写代码中用的算是“最佳实践”吧。最后希望大家没事多逛逛论坛,有很多高质量的回答.
参数的初始化其实就是对参数赋值。而我们需要学习的参数其实都是Variable,它其实是对Tensor的封装,同时提供了data,grad等借口,这就意味着我们可以直接对这些参数进行操作赋值了。这就是PyTorch简洁高效所在.
所以我们可以进行如下操作进行初始化,当然其实有其他的方法,但是这种方法是PyTorch作者所推崇的:
1
2
3
4
5
6
7
8
9
|
def
weight_init(m):
# 使用isinstance来判断m属于什么类型
if
isinstance
(m, nn.Conv2d):
n
=
m.kernel_size[
0
]
*
m.kernel_size[
1
]
*
m.out_channels
m.weight.data.normal_(
0
, math.sqrt(
2.
/
n))
elif
isinstance
(m, nn.BatchNorm2d):
# m中的weight,bias其实都是Variable,为了能学习参数以及后向传播
m.weight.data.fill_(
1
)
m.bias.data.zero_()
|
往往在加载了预训练模型的参数之后,我们需要finetune模型,可以使用不同的方式finetune.
有时候我们加载了训练模型后,只想调节最后的几层,其他层不训练。其实不训练也就意味着不进行梯度计算,PyTorch中提供的requires_grad使得对训练的控制变得非常简单.
1
2
3
4
5
6
7
8
9
|
model
=
torchvision.models.resnet18(pretrained
=
True
)
for
param
in
model.parameters():
param.requires_grad
=
False
# 替换最后的全连接层, 改为训练100类
# 新构造的模块的参数默认requires_grad为True
model.fc
=
nn.Linear(
512
,
100
)
# 只优化最后的分类层
optimizer
=
optim.SGD(model.fc.parameters(), lr
=
1e
-
2
, momentum
=
0.9
)
|
有时候我们需要对全局都进行finetune,只不过我们希望改换过的层和其他层的学习速率不一样,这时候我们可以把其他层和新层在optimizer中单独赋予不同的学习速率。比如:
1
2
3
4
5
6
7
8
|
ignored_params
=
list
(
map
(
id
, model.fc.parameters()))
base_params
=
filter
(
lambda
p:
id
(p)
not
in
ignored_params,
model.parameters())
optimizer
=
torch.optim.SGD([
{
'params'
: base_params},
{
'params'
: model.fc.parameters(),
'lr'
:
1e
-
3
}
], lr
=
1e
-
2
, momentum
=
0.9
)
|
其中base_params使用1e-3来训练,model.fc.parameters使用1e-2来训练,momentum是二者共有的.
之三:
文章主要讲述如何在pytorch上读取以往训练的模型参数,在模型的名字已经变更的情况下又如何读取模型的部分参数等.
其中在模型的保存过程有存储模型和参数一起的也有单独存储模型参数的 。
存储时使用:
1
|
torch.save(the_model.state_dict(), PATH)
|
读取时:
1
2
|
the_model
=
TheModelClass(
*
args,
*
*
kwargs)
the_model.load_state_dict(torch.load(PATH))
|
存储:
1
|
torch.save(the_model, PATH)
|
读取:
1
|
the_model
=
torch.load(PATH)
|
fine-tune的过程是读取原有模型的参数,但是由于模型的所要处理的数据集不同,最后的一层class的总数不同,所以需要修改模型的最后一层,这样模型读取的参数,和在大数据集上训练好下载的模型参数在形式上不一样。需要我们自己去写函数读取参数.
模型的参数是以字典的形式存储的.
1
2
3
|
model_dict
=
the_model.state_dict(),
for
k,v
in
model_dict.items():
print
(k)
|
即可看到所有的键值 。
1
|
model_dict[k]
=
new_value
|
最后更新模型的参数 。
1
|
the_model.load_state_dict(model_dict)
|
我们可以通过下列算法进行读取模型 。
1
2
3
4
5
6
7
8
9
10
11
|
model_dict
=
model.state_dict()
pretrained_dict
=
torch.load(model_path)
# 1. filter out unnecessary keys
diff
=
{k: v
for
k, v
in
model_dict.items()
if
\
k
in
pretrained_dict
and
pretrained_dict[k].size()
=
=
v.size()}
pretrained_dict
=
{k: v
for
k, v
in
pretrained_dict.items()
if
k
in
model_dict
and
model_dict[k].size()
=
=
v.size()}
pretrained_dict.update(diff)
# 2. overwrite entries in the existing state dict
model_dict.update(pretrained_dict)
# 3. load the new state dict
model.load_state_dict(model_dict)
|
1
2
3
4
5
6
7
8
9
10
11
12
|
model_dict
=
model.state_dict()
pretrained_dict
=
torch.load(model_path)
keys
=
[]
for
k,v
in
pretrained_dict.items():
keys.append(k)
i
=
0
for
k,v
in
model_dict.items():
if
v.size()
=
=
pretrained_dict[keys[i]].size():
print
(k,
','
, keys[i])
model_dict[k]
=
pretrained_dict[keys[i]]
i
=
i
+
1
model.load_state_dict(model_dict)
|
自己找对应关系,一个key对应一个key的赋值 。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持我.
原文链接:https://blog.csdn.net/Scythe666/article/details/82809615 。
最后此篇关于pytorch fine-tune 预训练的模型操作的文章就讲到这里了,如果你想了解更多关于pytorch fine-tune 预训练的模型操作的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
这一章我们介绍在下游任务微调中固定LM参数,只微调Prompt的相关模型。这类模型的优势很直观就是微调的参数量小,能大幅降低LLM的微调参数量,是轻量级的微调替代品。和前两章微调LM和全部冻结的pr
LLM微调方法(Efficient-Tuning)六大主流方法:思路讲解&优缺点对比[P-tuning、Lora、Prefix tuing等] 由于LLM参数量都是在亿级以上,少则数十亿,多
微调 API 中关于 model 属性的 OpenAI 文档说明有点令人困惑: model The name of the base model to fine-tune. You can selec
微调 API 中关于 model 属性的 OpenAI 文档说明有点令人困惑: model The name of the base model to fine-tune. You can selec
我正在尝试使用带有调整网格的 Caret 创建模型 svmGrid up_inside Support Vector Machines with Linear Kernel 100 samples
当涉及到语言模型(LLM)的教学微调时,什么时候应该选择有监督的微调培训器(SFTTrainer)而不是常规的Transformers培训器?据我所知,常规的Transformers培训人员通常指的是
RHEL/CentOS 在 6.3 版本以后引入了一套新的系统调优工具 tuned/tuned-adm,其中 tuned 是服务端程序,用来监控和收集系统各个组件的数据,并依据数据提供的信息动态调整
关闭。这个问题需要debugging details .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 2年前关闭。 Improve this questio
我有一个大约 4MB 的文件,该文件是一个仅包含普通键盘字符的 ascii 文件。我尝试了 java.io 包中的许多类来将文件内容读取为字符串。逐个字符地读取它们(使用 FileReader 和 B
之一: torchvision 中包含了很多预训练好的模型,这样就使得 fine-tune 非常容易。本文主要介绍如何 fine-tune torchvision 中预训练好的模型。 安装
有没有办法停止ray.tune实验(例如使用 PBT)当明显过度拟合或一个指标长时间没有改善时? 最佳答案 现在,这在 Tune 中得到了很好的支持,https://github.com/ray-pr
构建 LINQ 表达式(对我来说,是 linq to object)时,有很多方法可以完成某件事,其中一些方法比其他方法更好、更高效。 有没有好的方法来“调整”或优化这些表达式? 人们采用哪些基本指标
我正在尝试保存一个经过微调的 bert 模型。我已经正确运行了代码 - 它工作正常,并且在 ipython 控制台中我可以调用 getPrediction 并让它产生结果。 我已保存体重文件(最高的是
我有这样的查询。 SELECT count(*) FROM table1 e WHERE e.column1=1 AND e.id IN (SELECT MAX(ID) FROM
我在 node.js 上使用 ffmpeg。并选择“-tune Zerolatency”以实现低延迟 但是当我插入“-tune Zerolatency”时,出现错误:无法识别的选项“tune”。 有人
我目前正在训练 CNN 来对波进行分类。虽然代码运行完美,但用于超参数调整的 GridSearchCV 无法按预期工作。我很困惑,因为我在 MLP 中使用了类似的代码来调整超参数,而且效果很好。这是完
我的应用程序在我的 iPad 上运行。但它的表现非常糟糕——我的速度低于 15fps。谁能帮我优化一下? 它基本上是一个轮子(派生自 UIView),包含 12 个按钮(派生自 UIControl)。
SQL Turning 是Quest公司出品的Quest Central软件中的一个工具。Quest Central是一款集成化、图形化、跨平台的数据库管理解决方案,可以同时管理 Oracle、DB
让事件记录在开发环境中对所有查询使用 SQL_NO_CACHE 的简单方法是什么? 我想优化最坏情况加载时间的语句。希望这样做是有意义的,但是我在第一页命中时查询非常慢,而下次所有查询都非常快,因为服
我有一个电子邮件数据集,我正在使用 SVM 来确定电子邮件是否是垃圾邮件 我将数据集分为测试和训练,然后随机挑选了一组 500 条记录来调整 svm。我正在使用 RBF 内核。以下是原始数据 make
我是一名优秀的程序员,十分优秀!