## 张量tensor介绍
import torch
x = torch.ones(2, 2, requires_grad=True) # 创建 tensor 变量,属性 .requires_grad 为 True,会追踪对于该张量的所有操作
y = x + 2 # y 也是一个 tensor 变量,y 的 .grad_fn 指向的是 y = x + 2
# 每个张量都有一个 .grad_fn 属性,该属性引用了创建 Tensor 自身的Function
z = y * y * 3 # tensor 变量 z,属性.grad_fn 指向 z = y * y * 3
out = z.mean() # out的属性.grad_fn 指向 mean()
# requires_grad_() 方法用于改变 requires_grad 属性的值, requires_grad 属性是不能使用属性名修改的
a = torch.randn(2, 2).requires_grad_(True)
# 当完成计算后可以通过调用 .backward(),来自动计算所有的梯度,张量的所有梯度将会自动累加到.grad属性.
out.backward() # backward() 可以传入一个 tensor 参数,指定求哪一点的导数
x.grad # 只有 "leaf Tensor"(叶张量) 才有grad属性,中间过程产生的张量没有该属性
# with torch.no_grad():的应用
with torch.no_grad():
print((x ** 2).requires_grad) # 这里的(x ** 2)的 .requires_grad 属性值为 False,backward() 不会反向计算这里的梯度