PyTorch学习——关于tensor、Variable、nn.Parameter()、叶子节点、非叶子节点、detach()函数、查看网络层参数

系列文章目录

pytorch优化器——add_param_group()介绍及示例、Yolov7 优化器代码示例
pytorch学习率设置——optimizer.param_groups、对不同层设置学习率、动态调整学习率
PyTorch学习——关于tensor、Variable、nn.Parameter()、叶子节点、非叶子节点、detach()函数、查看网络层参数
PyTorch model 返回函数总结——model.state_dict(),model.modules(),model.children(),model.parameters()
PyTorch模型参数初始化(weights_init)——torch.nn.init、加载预权重



tensor、Variable、nn.Parameter()

tensor(张量)能够更方便地在GPU上进行运算。
Variable是对Tensor的封装,为了引入计算图(自动求导),方便构建神经网络。Variable、tensor默认 requires_grad=False。
nn.Parameter()是pytorch中定义可学习参数的一种方法,可进行梯度求导,是将一个不可训练的类型Tensor转换成可以训练的类型,默认require_grad=True。

叶子节点和非叶子节点

关于叶子节点:
叶子节点可以理解成不依赖其他tensor的tensor。
只有叶子张量在反向传播的过程中才会将本身的grad传入backward()计算。
require_grad=True:

默认情况下,非叶子节点的梯度值在反向传播过程中使用完后就会被清除,不会被保留。 默认情况下,只有叶子节点的梯度值能够被保留下来。
被保留下来的叶子节点的梯度值会存入tensor的grad属性中,在
optimizer.step()过程中会更新叶子节点的data属性值,从而实现参数的更新。

1.首先requires_grad这个是看用户需求进行设定,如果为false则把你视为叶子节点。requires_grad=False,而is_leaf=True,则不计算该张量的grad
2.如果requires_grad=True and is_leaf=True,则计算该张量的grad,并且把计算得到的grad放到该张量的grad属性里面,
3. requires_grad=True and is_leaf=False, 不保留grad.
4. 如果是非叶子节点,也就是requires_grad=True and is_leaf=False,则可以通过retain_grad()来得到grad。

reaquires_grad=False的张量都是叶子张量;requires_grad=True的张量,如果是由用户创建的,例如卷积核的参数和一些可以学习的参数,则它们是叶子张量。
中间生成的结果都是非叶子节点,grad_fn is None

无论requires_grad属性为何值,原先的叶子节点求导通路中断,便无法获得梯度数值了。
在这里插入图片描述

.requires_grad :查看是否计算梯度
.grad:查看梯度值
.is_leaf:查看是否为叶子节点

import torch
a=torch.tensor([1.1],requires_grad=True)   # 设置张量计算梯度
b=a*2
print(b.requires_grad)  # 查看是否计算梯度
print(b)  
b.backward()  # 反向求导
print(a.grad)  # 输出梯度值
print(a.is_leaf) # 查看是否为叶子节点

detach()函数

detach剥离其梯度属性,剥离后的张量与原张量内存相同,但不会累计梯度,其属性里也没有了grad_fn。

import torch
import torch.nn as nn
import torch.nn.functional as F

a = torch.tensor([1, 1, 1], requires_grad=True, dtype=torch.float32)
b = torch.tensor([1, 1, 1], requires_grad=False, dtype=torch.float32)
b.requires_grad_(True)
c = (a + 2 * b.detach()).sum()
c.backward()

print(a.grad, b.grad)  # tensor([1., 1., 1.]) None

with torch.no_grad()

被torch.no_grad()包裹起来的部分不会被追踪梯度,虽然仍可以前向传播进行计算得到输出,但计算过程(grad_fn)不会被记录,也就不能反向传播更新参数。具体地,对非叶子节点来说:
非叶子节点的requires_grad属性变为了False
非叶子节点的grad_fn属性变为了None
这样便不会计算非叶子节点的梯度。因此,虽然叶子结点(模型各层的可学习参数)的requires_grad属性没有改变(依然为True),也不会计算梯度,grad属性为None,型的可学习参数不会更新。

backward之后x.grad为None

查看叶节点的require_grad属性是否为True

输出网络层参数

for name, parameter in model_train.named_parameters():
    print(name,parameter.shape)
for name, p in model.named_modules():
	print(name,p)

总结

学习小计。

猜你喜欢

转载自blog.csdn.net/weixin_45464524/article/details/130199878