pytorch 官方文档-变量和梯度

torch.Tensor的属性.requires_grad设置为True,它将记录自身所有的操作.当计算完成后可以调用.backward()函数来计算梯度.梯度将会存放在.grad属性里面.
通过.detach()方法可以停止tensor记录历史,也可以停止未来的计算.

TensorFunction是紧密相连的.每一个tensor都有一个.grad_fn属性,他对应了一个创建TensorFunction.

autograd提供了自动微分操作.

Tensor

import torch
# 创建一个tensor
x = torch.ones(2, 2, requires_grad=True)
print(x)
# 对tensor进行操作
y = x + 2
print(y)
# y是计算的结果,所以他会有`grad_fn`
print(y.grad_fn)

# 对y进行更多的操作
z = y * y * 3
out = z.mean()

print(z, out)

# `.requires_grad_(...)`用来指定一个tensor的`requires_grad`标志, 默认是`False`
a = torch.randn(2, 2)
a = ((a * 3) / (a - 1))
print(a.requires_grad)
a.requires_grad_(True)
print(a.requires_grad)
b = (a * a).sum()
print(b.grad_fn)

Gradients

接下来计算反向传播.因为out只包含了一个值,所以out.backward()等价于out.backward(torch.tensor(1.)),也就是说如果结果是矩阵的话,要在backward方法里指明维度.

out.backward()
print(x.grad)

输出的结果是

tensor([[4.5000, 4.5000],
        [4.5000, 4.5000]])

为什么会得到这个结果?回想刚才我们的计算公式:

x = torch.ones(2, 2, requires_grad=True)
y = x + 2
z = y * y * 3
out = z.mean()

转换为数学公式为:
o = 1 4 ∑ i z i o = \frac{1}{4}\sum_i z_i o=41izi
z i = 3 ( x i + 2 ) 2 z_i = 3(x_i+2)^2 zi=3(xi+2)2
我们得到,当x=1时:
z i ∣ x i = 1 = 27 z_i\bigr\rvert_{x_i=1} = 27 zixi=1=27
因此,得到在x=1那个点的斜率为:
∂ o ∂ x i = 3 2 ( x i + 2 ) \frac{\partial o}{\partial x_i} = \frac{3}{2}(x_i+2) xio=23(xi+2)
∂ o ∂ x i ∣ x i = 1 = 9 2 = 4.5 \frac{\partial o}{\partial x_i}\bigr\rvert_{x_i=1} = \frac{9}{2} = 4.5 xioxi=1=29=4.5

如果最后输出的y,不是一个值而是一个向量,则:

x = torch.randn(3, requires_grad=True)

y = x * 2
while y.data.norm() < 1000:
    y = y * 2

print(y)

v = torch.tensor([0.1, 1.0, 0.0001], dtype=torch.float)
y.backward(v)

print(x.grad)


print(x.requires_grad)
print((x ** 2).requires_grad)

with torch.no_grad():
    print((x ** 2).requires_grad)

参考文献:
https://pytorch.apachecn.org/#/docs/3
https://pytorch.org/tutorials/beginner/blitz/autograd_tutorial.html#sphx-glr-beginner-blitz-autograd-tutorial-py

你可能感兴趣的:(人工神经网络)