1、torch.autograd.backward
# torch.autograd.backward(
# tensor,
# grad_tensors=None,
# retain_graph=None,
# create_graph=False
# )
功能:自动求取梯度
tensors
:用于求导的张量retain_graph
:保存计算图creat_graph
:创建导数计算图,用于高阶求导grad_tensors
:多梯度权重
示例:
y = ( x + w ) ∗ ( w + 1 ) y = (x + w) * (w + 1) y=(x+w)∗(w+1)
a = x + w a = x + w a=x+w
b = w + 1 b = w + 1 b=w+1
y = a ∗ b y = a * b y=a∗b
∂ y ∂ w = ∂ y ∂ a ∂ a ∂ w + ∂ y ∂ b ∂ b ∂ w = 5 \frac{∂y}{∂w} = \frac{∂y}{∂a} \frac{∂a}{∂w} + \frac{∂y}{∂b} \frac{∂b}{∂w} = 5 ∂w∂y=∂a∂y∂w∂a+∂b∂y∂w∂b=5
if True:
w = torch.tensor([1.],requires_grad=True)
x = torch.tensor([2.],requires_grad=True)
a = torch.add(w, x)
b = torch.add(w, 1)
y = torch.mul(a, b)
y.backward(retain_graph=True) # retain_graph=True表示不释放计算图
print(w.grad, x.grad)
"""
输出:
tensor([5.]) tensor([2.])
"""
if True:
w = torch.tensor([1.],requires_grad=True)
x = torch.tensor([2.],requires_grad=True)
a = torch.add(w, x)
b = torch.add(w, 1)
y0 = torch.mul(a, b)
y1 = torch.add(a, b)
loss = torch.cat([y0, y1], dim=0)
grad_tensors = torch.tensor([1., 1.])
loss.backward(gradient=grad_tensors)
print(w.grad, x.grad)
"""
输出:
tensor([7.]) tensor([3.])
"""
2、torch.autograd.grad
# torch.autograd.grad(
# outputs,
# inputs,
# grad_outputs=None,
# retain_graph=None,
# create_graph=False,
# only_inputs=True,
# allow_unused=False
# )
功能:求取梯度
ouputs
:用于求导的张量inputs
:需要梯度的张量create_graph
:创建导数计算图,用于高阶求导retain_graph
:保存计算图grad_outputs
:多梯度权重
if True:
x = torch.tensor([3.], requires_grad=True)
y = torch.pow(x, 2) # y = x^2
grad_1 = torch.autograd.grad(y, x, create_graph=True) # 计算y对x的导数
print(grad_1) # grad_1 = 2*x = 6
grad_2 = torch.autograd.grad(grad_1, x, create_graph=True) # 计算y对x的二阶导数
print(grad_2) # grad_2 = 2
"""
输出:
(tensor([6.], grad_fn=<MulBackward0>),)
(tensor([2.], grad_fn=<MulBackward0>),)
"""
3、注意
3.1 梯度不自动清零
if True:
w = torch.tensor([1.], requires_grad=True)
x = torch.tensor([2.], requires_grad=True)
for i in range(4):
a = torch.add(w, x)
b = torch.add(w, 1)
y = torch.mul(a, b)
y.backward()
print(w.grad, x.grad)
w.grad.zero_() # 清空梯度
x.grad.zero_() # 清空梯度
"""
输出:
tensor([5.]) tensor([2.])
tensor([5.]) tensor([2.])
tensor([5.]) tensor([2.])
tensor([5.]) tensor([2.])
"""
3.2 依赖于叶子结点的结点,requires_grad
默认为True
3.3 叶子结点不可执行in-place
if True:
a = torch.ones((1, ))
print(id(a), a)
a = a + torch.ones((1, ))
print(id(a), a) # 这里的a是一个新的tensor,和之前的a不是同一个tensor了
"""
输出:
2719495780496 tensor([1.])
2719495881744 tensor([2.])
"""
if True:
a = torch.ones((1, ))
print(id(a), a)
a += torch.ones((1, ))
print(id(a), a)
"""
输出:
2719495530336 tensor([1.])
2719495530336 tensor([2.])
"""
微语录:要往前走,就得先忘掉过去。