1、标量的自动微分
2、非标量的自动微分
'''
自动微分___非标量的自动微分
'''
# 对⾮标量调⽤backward需要传⼊⼀个gradient参数,该参数指定微分函数关于self的梯度。
# 在我们的例⼦中,我们只想求偏导数的和,所以传递⼀个1的梯度是合适的
x.grad.zero_()
y = x * x # y = x * x = (x1^2 , x2^2 , x3^2 , x4^2)
# 等价于y.backward(torch.ones(len(x)))
y.sum().backward() # y.sum() ===> y_sum = x1^2 + x2^2 + x3^2 + x4^2
x.grad # 求梯度,x.grad = (2x1 , 2x2 , 2x3 , 2x4)
3、分离计算
'''
分离计算
# z=B(y)、y=A(x) 求B中参数的梯度,不求A中参数的梯度
y = A(x)
z = B(y.detach())
z.backward()
y.detach()
返回一个新的tensor,从当前计算图中分离下来的,但是仍指向原变量的存放位置(内存相同),不同之处只是requires_grad为false,
得到的这个tensor不再有计算梯度的能力,反向传播时遇到该tensor将停止,不再继续传播
'''
x.grad.zero_()
y = x * x
u = y.detach()
z = u * x
z.sum().backward() # z.sum() ===> z_sum = u(x1 + x2 + x3 + x4)
x.grad == u
4、Python控制流的梯度计算
'''
Python控制流的梯度计算
即使构建函数的计算图需要通过Python控制流(例如,条件、循环或任意函数调⽤),我们仍然可以计算得到的变量的梯度。
'''
def f(a):
b = a * 2
while b.norm() < 1000:
b = b * 2
if b.sum() > 0:
c = b
else:
c = 100 * b
return c
# 计算梯度
a = torch.randn(size=(), requires_grad=True)
a