1. 关于parameters()方法

Pytorch中继承了torch.nn.Module的模型类具有named_parameters()/parameters()方法,这两个方法都会返回一个用于迭代模型参数的迭代器(named_parameters还包括参数名字):

import torch

net = torch.nn.LSTM(input_size=512, hidden_size=64)
print(net.parameters())
print(net.named_parameters())
# <generator object Module.parameters at 0x12a4e9890>
# <generator object Module.named_parameters at 0x12a4e9890>

我们可以将net.parameters()迭代器和将net.named_parameters()转化为列表类型,前者列表元素是模型参数,后者是包含参数名和模型参数的元组。

当然,我们更多的是对迭代器直接进行迭代:

for param in net.parameters():
print(param.shape)
# torch.Size([256, 512])
# torch.Size([256, 64])
# torch.Size([256])
# torch.Size([256])
for name, param in net.named_parameters():
print(name, param.shape)
# weight_ih_l0 torch.Size([256, 512])
# weight_hh_l0 torch.Size([256, 64])
# bias_ih_l0 torch.Size([256])
# bias_hh_l0 torch.Size([256])

我们知道,Pytorch在进行优化时需要给优化器传入这个参数迭代器,如:

from torch.optim import RMSprop
optimizer = RMSprop(net.parameters(), lr=0.01)

2. 关于参数修改

那么底层具体是怎么对参数进行修改的呢?

我们在博客《Python对象模型与序列迭代陷阱》中介绍过,Python序列中本身存放的就是对象的引用,而迭代器返回的是序列中的对象的二次引用,如果序列的引用指向基础数据类型,则是不可以通过遍历序列进行修改的,如:

my_list = [1, 2, 3, 4]
for x in my_list:
x += 1
print(my_list) #[1, 2, 3, 4]

而序列中的引用指向复合数据类型,则可以通过遍历序列来完成修改操作,如:

my_list = [[1, 2],[3, 4]]
for sub_list in my_list:
sub_list[0] += 1
print(my_list)
# [1, 2, 3, 4]
# [[2, 2], [4, 4]]

具体原理可参照该篇博客,此处我就不在赘述。这里想提到的是,用net.parameters()/net.named_parameters()来迭代并修改参数,本质上就是上述第二种对复合数据类型序列的修改。我们可以如下写:

for param in net.parameters():
with torch.no_grad():
param += 1

with torch.no_grad():表示将将所要修改的张量关闭梯度计算。所增加的1会广播到param张量的中的每一个元素上。上述操作本质上为:

for param in net.parameters():
with torch.no_grad():
param += torch.ones(param.shape)

但是需要注意,如果我们想让参数全部置为0,切不可像下列这样写:

for param in net.parameters():
with torch.no_grad():
param = torch.zeros(param.shape)

param是二次引用,param=0操作再语义上会被解释为让param这个二次引用去指向新的全0张量对象,但是对参数张量本身并不会产生任何变动。该操作实际上类似下列这种操作:

list_1 = [1, 2]
list_2 = list_1
list_2 = [0, 0]
print(list_1) # [1, 2]

修改二次引用list_2自然不会影响到list_1引用的对象。

下面让我们纠正这种错误,采用下列方法直接来将参数张量中的所有数值置0:

for param in net.parameters():
with torch.no_grad():
param[:] = 0 #张量类型自带广播操作,等效于param[:] = torch.zeros(param.shape)

这时语义上就类似

list_1 = [1, 2]
list_2 = list_1
list_2[:] = [0, 0]
print(list_1) # [0, 0]

自然就能完成修改的操作了。

参考

Pytorch:利用torch.nn.Modules.parameters修改模型参数的更多相关文章

  1. pytorch中torch.nn构建神经网络的不同层的含义

    主要是参考这里,写的很好PyTorch 入门实战(四)--利用Torch.nn构建卷积神经网络 卷积层nn.Con2d() 常用参数 in_channels:输入通道数 out_channels:输出 ...

  2. [pytorch笔记] torch.nn vs torch.nn.functional; model.eval() vs torch.no_grad(); nn.Sequential() vs nn.moduleList

    1. torch.nn与torch.nn.functional之间的区别和联系 https://blog.csdn.net/GZHermit/article/details/78730856 nn和n ...

  3. PyTorch官方中文文档:torch.nn

    torch.nn Parameters class torch.nn.Parameter() 艾伯特(http://www.aibbt.com/)国内第一家人工智能门户,微信公众号:aibbtcom ...

  4. 到底什么是TORCH.NN?

    该教程是在notebook上运行的,而不是脚本,下载notebook文件. PyTorch提供了设计优雅的模块和类:torch.nn, torch.optim, Dataset, DataLoader ...

  5. 从 relu 的多种实现来看 torch.nn 与 torch.nn.functional 的区别与联系

    从 relu 的多种实现来看 torch.nn 与 torch.nn.functional 的区别与联系 relu多种实现之间的关系 relu 函数在 pytorch 中总共有 3 次出现: torc ...

  6. 小白学习之pytorch框架(3)-模型训练三要素+torch.nn.Linear()

    模型训练的三要素:数据处理.损失函数.优化算法    数据处理(模块torch.utils.data) 从线性回归的的简洁实现-初始化模型参数(模块torch.nn.init)开始 from torc ...

  7. pytorch保存模型等相关参数,利用torch.save(),以及读取保存之后的文件

    本文分为两部分,第一部分讲如何保存模型参数,优化器参数等等,第二部分则讲如何读取. 假设网络为model = Net(), optimizer = optim.Adam(model.parameter ...

  8. 小白学习之pytorch框架(4)-softmax回归(torch.gather()、torch.argmax()、torch.nn.CrossEntropyLoss())

    学习pytorch路程之动手学深度学习-3.4-3.7 置信度.置信区间参考:https://cloud.tencent.com/developer/news/452418 本人感觉还是挺好理解的 交 ...

  9. 小白学习之pytorch框架(1)-torch.nn.Module+squeeze(unsqueeze)

    我学习pytorch框架不是从框架开始,从代码中看不懂的pytorch代码开始的 可能由于是小白的原因,个人不喜欢一些一下子粘贴老多行代码的博主或者一些弄了一堆概念,导致我更迷惑还增加了畏惧的情绪(个 ...

  10. [深度学习] Pytorch学习(二)—— torch.nn 实践:训练分类器(含多GPU训练CPU加载预测的使用方法)

    Learn From: Pytroch 官方Tutorials Pytorch 官方文档 环境:python3.6 CUDA10 pytorch1.3 vscode+jupyter扩展 #%% #%% ...

随机推荐

  1. 这一次,让我们一起来搞懂MySQL

    欢迎加入我的专栏,和我一起开始 MySQL 学习之旅. 从日常的开发和优化中,一步步地从一个数据库小白成为 MySQL 调优的开发人员.回想起来,从我第一次带创建索引至今,已经有十个年头了.在这个过程 ...

  2. synchronized解锁源码分析

    上篇花了很大篇幅写了synchronized的加锁流程,并对比了ReentrantLock的设计,这篇我们收个尾,来聊一聊解锁流程,本来准备一章解决的,写着写着觉得内容过多,其实上一篇和Reentra ...

  3. VS 2020制作安装包

    VS制作安装包的一般步骤. 一·新建项目 (1)新建 (2)界面跳转 二·添加引用 (1)添加卸载程序 1.在'C:WINDOWSsystem32'路径下,找到msiexec.exe . 2.将msi ...

  4. ES6~ES9

    ES6 1. let 1.1 let 变量声明及声明特性 let 用来声明变量,具有以下特性: 一.相较于 var ,let 变量不能重复声明 let a = 'a'; let a = 'a'; // ...

  5. Pytorch DistributedDataParallel(DDP)教程一:快速入门理论篇

    一. 写在前面 随着深度学习技术的不断发展,模型的训练成本也越来越高.训练一个高效的通用模型,需要大量的训练数据和算力.在很多非大模型相关的常规任务上,往往也需要使用多卡来进行并行训练.在多卡训练中, ...

  6. Java中list集合深复制

    import org.apache.commons.collections.CollectionUtils; import java.util.ArrayList; import java.util. ...

  7. dom4j 通用解析器,解析成List<Map<String,Object>>

    import java.io.InputStream; import java.util.Iterator; import java.util.LinkedHashMap; import java.u ...

  8. Flink Standalone集群jobmanagers高可用配置

    上篇文章简单叙述了Flink standalone集群的基础部署,在生产环境中假如只有1个jobmanager的话,那么这个节点一旦挂掉,所有运行的task都会中断,带来的影响比较大,因此在生产环境至 ...

  9. steam社区留言红小作文模板

    steam社区留言红小作文模板 Dear steam: Im a steam user which most play csgo.i saw i had be banned in steam comm ...

  10. PostgreSQL 14.4的安装以及使用以及一些安装的异常

    PostgreSQL 14的安装以及使用 因为公司的一些要求,可能要换数据库,虽然之前装过,但是版本感觉还是新一点比较好,所以重新装一下 首先下载文件,直接去官网下载就行 https://www.en ...