學了本文你能學到什麼?僅供學習,如有疑問,請留言。。。
注:紅色是小結, 紫色是重點,能像被課文一樣背誦,初次系統性的學習,請多多指點
目錄
2.3自動求梯度
在深度學習中,我們經常需要對函數求梯度(gradient)。PyTorch提供的autograd包能夠根據輸入和前向傳播過程自動構建計算圖,並執行反向傳播。
本節將介紹如何使用autograd包來進行自動求梯度的有關操作。
# 2.3.1 概念
'''
# Tensor是這個包的核心類,如果將其屬性.requires_grad設置爲True,它將開始追蹤(track)在其上的所有操作(這樣就可以利用鏈式法則進行梯度傳播了)
# 完成計算後,可以調用.backward()來完成所有梯度計算。此Tensor的梯度將累積到.grad屬性中。
# todo 注意在y.backward()時,如果y是標量,則不需要爲backward()傳入任何參數;否則,需要傳入一個與y同形的Tensor。"
# 如果不想要被繼續追蹤,可以調用.detach()將其從追蹤記錄中分離出來,這樣就可以防止將來的計算被追蹤,這樣梯度就傳不過去了。
# 此外,還可以用with torch.no_grad()將不想被追蹤的操作代碼塊包裹起來,這種方法在評估模型的時候很常用,
# 因爲在評估模型時,我們並不需要計算可訓練參數(requires_grad=True)的梯度。
# function是另外一個很重要的類。Tensor和Function互相結合就可以構建一個記錄有整個計算過程的有向無環圖(DAG)(非循環)。
# 每個Tensor都有一個.grad_fn屬性,該屬性即創建該Tensor的Function, 就是說該Tensor是不是通過某些運算得到的,若是,則grad_fn返回一個與這些運算相關的對象,否則是None。
'''
# 2.3.2 Tensor
# 創建一個Tensor並設置requires_grad=True:
import torch
x = torch.ones(2, 2, requires_grad=True)
print(x)
print(x.grad_fn)
y = x + 2
print(y)
print(y.grad_fn)
"注意x是直接創建的,所以它沒有grad_fn, 而y是通過一個加法操作創建的,所以它有一個爲<AddBackward>的grad_fn。"
"像x這種直接創建的稱爲葉子節點,葉子節點對應的grad_fn是None。"
print(x.is_leaf,y.is_leaf)
z = y * y *3
out = z.mean()
print(z, out)
print("-----------------------------------------華麗的分割線-----------------------------------")
"通過.requires_grad_()來用in-place的方式改變requires_grad屬性:"
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)
"""
import torch
x = torch.ones(2, 2, requires_grad=True)
print(x)
# 2.3.3 梯度(這裏他好像沒講清楚)
grad在反向傳播過程中是累加的(accumulated),這意味着每一次運行反向傳播,梯度都會累加之前的梯度,所以一般在反向傳播之前需把梯度清零。
"爲什麼在y.backward()時,如果y是標量,則不需要爲backward()傳入任何參數;否則,需要傳入一個與y同形的Tensor? "
"簡單來說就是爲了避免向量(甚至更高維張量)對張量求導,而轉換成標量對張量求導。"
"舉個例子,假設形狀爲 m x n 的矩陣 X 經過運算得到了 p x q 的矩陣 Y,Y 又經過運算得到了 s x t 的矩陣 Z。那麼按照前面講的規則,dZ/dY 應該是一個 s x t x p x q 四維張量,dY/dX 是一個 p x q x m x n的四維張量" \
"問題來了,怎樣反向傳播?怎樣將兩個四維張量相乘???這要怎麼乘???就算能解決兩個四維張量怎麼乘的問題,四維和三維的張量又怎麼乘?導數的導數又怎麼求,這一連串的問題,感覺要瘋掉……" \
" 爲了避免這個問題,我們不允許張量對張量求導,只允許標量對張量求導,求導結果是和自變量同形的張量"
"所以必要時我們要把張量通過將所有張量的元素加權求和的方式轉換爲標量,
舉個例子,假設y由自變量x計算而來,w是和y同形的張量,則y.backward(w)的含義是:先計算l = torch.sum(y * w),則l是個標量,然後求l對自變量x的導數"
。。。。。。