Pytorch 學習筆記之梯度

x = torch.ones(2, 2, requires_grad=True)
print(x)
print(x.grad_fn)

tensor([[1., 1.],[1., 1.]], requires_grad=True)
None

y = x + 2
print(y)
print(y.grad_fn)

tensor([[3., 3.], [3., 3.]], grad_fn=)
<AddBackward object at 0x1100477b8>
注意x是直接創建的,所以它沒有 grad_fn , ⽽y是通過⼀個加法操作創建的,所以它有⼀個爲 的 grad_fn 。

z = y * y * 3
out = z.mean()
print(z, out)

tensor([[27., 27.], [27., 27.]], grad_fn=) tensor(27., grad_fn=)
在反向傳播求梯度的時候使用backward()函數,注意在 y.backward() 時,如果 y 是標量,則不需要爲 backward() 傳⼊任何參數;否則,需要傳⼊⼀個與 y 同形的 Tensor 。

因爲 out 是⼀個標量,所以調⽤ backward() 時不需要指定求導變量:

out.backward() # 等價於 out.backward(torch.tensor(1.))
print(x.grad)

tensor([[4.5000, 4.5000],
[4.5000, 4.5000]])
在這裏插入圖片描述

x = torch.tensor([1.0, 2.0, 3.0, 4.0], requires_grad=True)
y = 2 * x
z = y.view(2, 2)
print(z)

tensor([[2., 4.], [6., 8.]], grad_fn=)
現在 y 不是⼀個標量,所以在調⽤ backward 時需要傳⼊⼀個和 y 同形的權᯿向量進⾏加權求和得到⼀個標量。

v = torch.tensor([[1.0, 0.1], [0.01, 0.001]], dtype=torch.float)
z.backward(v)
print(x.grad)

tensor([2.0000, 0.2000, 0.0200, 0.0020])
假設 y 由 ⾃ 變 量 x 計 算 ⽽ 來 , w 是 和 y 同 形 的 張 量 ,
則 y.backward(w) 的含義是:先計算 l = torch.sum(y * w) ,則 l 是個標量,然後求 l 對⾃變量 x 的導數。
注意, x.grad 是和 x 同形的張量。

x = torch.ones([2,2],requires_grad=True)
out = x.sum()
out.backward()
print(x.grad)
#梯度累加
out2 = x.sum()
out2.backward()
print(x.grad)
#梯度清零
x.grad.zero_()
out3 = x.sum()
out3.backward()
print(x.grad)

tensor([[1., 1.],
[1., 1.]])
tensor([[2., 2.],
[2., 2.]])
tensor([[1., 1.],
[1., 1.]])
注意:grad在反向傳播過程中是累加的(accumulated),這意味着每⼀次運⾏反向傳播,梯度都會累
加之前的梯度,所以⼀般在反向傳播之前需把梯度清零。

參考書籍:動⼿學深度學習 PYTORCH 版

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章