PyTorch Tutorial 03 - Gradient Calcul...
教程Python代码如下:
import torch
x = torch.randn(5)
print(x)
#如果想计算一些函数的梯度,必须指定参数,要求grad=True
"""
在Tensor上的所有操作,Autograd都能为它们自动提供微分,避免手动计算导数的复杂过程。
autograd.Variable是 Autograd 中的核心类,它简单封装了Tensor,并支持几乎所有Tensor 的操作。
Tensor在被封装为Variable之后,可以调用它的.backward实现反向传播,自动计算所有梯度。
"""
x = torch.randn(5,requires_grad=True)
print(x)
y = x + 2
print(y)
z = y * y * 2
print(z)
z = z.mean()
print(z)
print("\n" + "计算z相当于x的梯度")
"""
计算z相当于x的梯度
注意:grad在反向传播过程中是累加的( accumulated ),这意味着每次运行反向传播,梯度都会累加之前的梯度,所以反向传播之前需把梯度清零。
"""
print(x.grad)
z.backward() #dz9
print(x.grad)
#如果没有z = z.mean()
x = torch.randn(3,requires_grad=True)
y = x + 2
z = y * y * 2
v = torch.tensor([0.1,0.01,0.001],dtype=torch.float32)
z.backward(v) #这里没有z = z.mean(),所以z不是一个标量,而是一个矢量,所以我们要给它一个矢量
print(x.grad)
print("\n" + "防止跟踪梯度的三种选择")
"""
防止跟踪梯度的三种选择:
1:x.requires_grad_(False)
2:x.detach() #创建一个不需要梯度的新张量
3:with torch.no_grad(): #包装在 with 语句中
"""
x = torch.randn(3,requires_grad=True)
print(x)
x.requires_grad_(False)
print(x)
x = torch.randn(3,requires_grad=True)
print(x)
y = x.detach()
print(y)
x = torch.randn(3,requires_grad=True)
print(x)
with torch.no_grad():
y = x + 2
print(y)
print("\n" + "梯度累加")
"""注意:grad在反向传播过程中是累加的( accumulated ),这意味着每次运行反向传播,梯度都会累加之前的梯度,所以反向传播之前需把梯度清零。"""
print("\n" + "一次迭代")
weights = torch.ones(4,requires_grad=True)
for epoch in range(1):
model_output = (weights*3).sum()
model_output.backward()
print(weights.grad)
print("\n" + "二次迭代")
weights = torch.ones(4,requires_grad=True)
for epoch in range(2):
model_output = (weights*3).sum()
model_output.backward()
print(weights.grad)
print("\n" + "三次迭代")
weights = torch.ones(4,requires_grad=True)
for epoch in range(3):
model_output = (weights*3).sum()
model_output.backward()
print(weights.grad)
"""梯度累加在很多时候显然是不对的,所以我们在下一次运算前要先清空梯度"""
print("\n" + "清空梯度的三次迭代")
weights = torch.ones(4,requires_grad=True)
for epoch in range(3):
model_output = (weights*3).sum()
model_output.backward()
print(weights.grad)
weights.grad.zero_()

