【笔记】记录对python中.grad()的一些理解

这几天再看神经网络,有点不明白.grad()、.detach()、.backward()等等等等这些关于梯度计算的东西,今天好像理解了一点,来做一个自己理解的总结。

首先来看一段非常简单的代码:

python 复制代码
import torch

X = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)
y = X * 2
z = y.sum()

z.backward()

print(X.grad)

这里我们定义了一个张量X,定义时将它的requires_grad设为了True,表示后面我们将会计算X的梯度。

然后我们对X进行了一系列运算,首先将它的所有元素乘以2,然后将所有元素相加。

最后实行反向传播计算并将梯度存储在内部,输入梯度。

要注意的是是对z进行反向传播,但梯度是记录在X中的。

最近看到了这样的一段代码:

python 复制代码
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9) #定义一个随机梯度下降类
for epoch in range(num_epochs):
    # 前向传播
    outputs = model(inputs)
    loss = criterion(outputs, targets)

    # 反向传播和优化
    optimizer.zero_grad()  # 清空之前的梯度
    loss.backward()        # 计算梯度
    optimizer.step()       # 更新权重

就很疑惑:为什么optimizer只要执行一个step就能准确根据梯度更新参数,而loss.backward()好像干了什么但又好像什么都没干,optimizer并没有传入loss作为参数,它是怎么知道要如何更新参数的呢?

现在才知道了,loss.backward()这步就是将梯度存储在先前的参数w、b中,执行完这一步后参数就会带上它的梯度,因此optimizer.step()就能通过w.grad、b.grad调用它的梯度。

另外requires_grad=True这个设置也可有在后面进行取消:

python 复制代码
import torch

X = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)
y = X * 2

y.detach_()

z = y.sum()
z.backward()

print(X.grad)

这样在中间插入了y.detach_(),就相当于把y的requires_grad改回了False,并且y和X的关系被切断,所以无法输出X的grad。

但是:

python 复制代码
import torch

X = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)
y = X * 2

z = y.sum()

y.detach_()

z.backward()

print(X.grad)

这样的话z在y更改设置之前就保留了y和X的关系,所以还是能够输出X的梯度。

相关推荐
左漫在成长1 小时前
王佩丰24节Excel学习笔记——第十六讲:简单文本函数
笔记·学习·excel
左漫在成长1 小时前
王佩丰24节Excel学习笔记——第十五讲:条件格式与公式
笔记·学习·excel
小马哥编程1 小时前
Jupyter Notebook的安装与使用
ide·python·jupyter
向宇it2 小时前
【从零开始入门unity游戏开发之——C#篇13】命名规范——驼峰命名法和帕斯卡命名法,函数(方法)的使用介绍
java·开发语言·游戏·unity·c#·游戏引擎
Forworder2 小时前
MVC前后端交互案例--留言板
java·开发语言·java-ee·mvc·intellij-idea·交互·postman
鱼香鱼香rose2 小时前
面经zijie
java·开发语言
观音山保我别报错2 小时前
JavaSe部分总结
java·开发语言
TechPioneer_lp4 小时前
腾讯技术岗位笔试&面试题(三)
c++·笔记·面试·软件工程·个人开发
shaoweijava4 小时前
智能家居销量数据分析(源码+数据库)
java·开发语言·数据库·spring boot·mysql·mybatis·智能家居
echo的PHP开发5 小时前
【python虚拟环境安装】linux centos 下的python虚拟环境配置
linux·python·centos·虚拟环境