【Pytorch教程】Pytorch tutorials 02-Autograd 中文翻譯

Autograd

本篇文章是本人對Pytorch官方教程的原創(chuàng)翻譯(原文鏈接)僅供學(xué)習(xí)交流使用昭殉,轉(zhuǎn)載請注明出處频丘!

autograd是Pytorch搭建神經(jīng)網(wǎng)絡(luò)最關(guān)鍵的包谣拣。它可以自動計(jì)算tensor操作產(chǎn)生的微分杠袱,也就是說辐怕,autograd是一個define-by-run的框架,可以自動對你的網(wǎng)絡(luò)進(jìn)行反向傳播澈蝙。

在聲明一個tesnor時吓坚,可以指定參數(shù).requires_grad=True開啟自動求導(dǎo),這樣Pytorch就會跟蹤它的所有操作灯荧,在tensor運(yùn)算完成后礁击,可以調(diào)用.backward()方法計(jì)算梯度,tesnor的梯度存放在它的.grad屬性當(dāng)中逗载。

.detach()方法可以取消對tensor的梯度追蹤哆窿,這樣Pytorch就會把tensor從追蹤記錄中移除,不再繼續(xù)追蹤厉斟。

為了節(jié)約內(nèi)存挚躯、提高效率,可以在代碼塊前注明with torch.no_grad()捏膨,因?yàn)橛行┳兞侩m然requires_grad=True但其實(shí)并不需要計(jì)算梯度。

在autograd包中食侮,還有一個非常重要的類就是Function号涯,除了用戶基于數(shù)據(jù)直接創(chuàng)建的Tensor(像a=torch.Tensor([1, 2, 3,])這樣),其他的Tensor必然是根據(jù)某些Tensor通過運(yùn)算得到的锯七,F(xiàn)unction類就記錄了這一運(yùn)算過程链快,并存儲在.grad_fn屬性中。

當(dāng)需要計(jì)算梯度時眉尸,首先需要調(diào)用y.backward()如果y是一個標(biāo)量的話域蜗,則無需傳參,否則噪猾,必須傳入一個與y規(guī)模相同的tensor霉祸。

這是因?yàn)椋赼utograd包中袱蜡,實(shí)際計(jì)算的是vector-Jacobian積丝蹭。也就是給定任意的向量v=(v_1 v_2 \cdots v_m)^T ,計(jì)算v與Jacobian矩陣 J的積{v^T}·J。如果v恰好是某個標(biāo)量函數(shù)l=g(\overrightarrow{y})的梯度坪蚁,即:

v=\left( \frac{\partial{l}}{\partial{y_1}} \frac{\partial{l}}{\partial{y_2}} \cdots \frac{\partial{l}}{\partial{y_m}}\right)^T

Jacobian矩陣:

J= \begin{pmatrix} \frac{\partial y_1}{\partial x_1} & \frac{\partial y_1}{\partial x_2} & \cdots & \frac{\partial y_1}{\partial x_n} \\ \frac{\partial y_2}{\partial x_1} & \frac{\partial y_2}{\partial x_2} & \cdots & \frac{\partial y_2}{\partial x_n} \\ \vdots & \vdots & \ddots & \vdots \\ \frac{\partial y_m}{\partial x_1} & \frac{\partial y_m}{\partial x_2} & \cdots & \frac{\partial y_m}{\partial x_n} \\ \end{pmatrix}

其中:{y_i}是關(guān)于{x_1,x_2,\cdots,x_n}的多元函數(shù),即:{y_i}={y_i}\left( x_1,x_2,\cdots,x_n \right)

那么根據(jù)鏈?zhǔn)椒▌t,v-J積的結(jié)果即是l關(guān)于\overrightarrow x的梯度:

{J^T}·v={\begin{pmatrix}\frac{\partial y_1}{\partial x_1} & \frac{\partial y_1}{\partial x_2} & \cdots & \frac{\partial y_1}{\partial x_n} \\ \frac{\partial y_2}{\partial x_1} & \frac{\partial y_2}{\partial x_2} & \cdots & \frac{\partial y_2}{\partial x_n} \\ \vdots & \vdots & \ddots & \vdots \\ \frac{\partial y_m}{\partial x_1} & \frac{\partial y_m}{\partial x_2} & \cdots & \frac{\partial y_m}{\partial x_n} \\ \end{pmatrix}}·{\begin{pmatrix} \frac{\partial{l}}{\partial{y_1}} \\ \frac{\partial{l}}{\partial{y_2}} \\ \vdots \\ \frac{\partial{l}}{\partial{y_m}} \end{pmatrix}} = {\begin{pmatrix} \frac{\partial{l}}{\partial{x_1}} \\ \frac{\partial{l}}{\partial{x_2}} \\ \vdots \\ \frac{\partial{l}}{\partial{x_n}} \end{pmatrix}}

定理:({AB})^T={B^T}{A^T}奔穿,因此計(jì)算{v^T}·J等價于{J^T}·v

vector-Jacobian積的這種特性使得模型非常容易擴(kuò)展镜沽。


接下來看一些例子:

import torch

初始化一個tensor,并將它的requires_grad屬性設(shè)為True,追蹤它的運(yùn)算贱田。

x = torch.ones(2, 2, requires_grad=True)
print(x)
tensor([[1., 1.],
        [1., 1.]], requires_grad=True)

創(chuàng)建一個tensory = x + 2

y = x + 2
print(y)
tensor([[3., 3.],
        [3., 3.]], grad_fn=<AddBackward0>)

y是由x計(jì)算得到的缅茉,所以它的.grad_fn不為空

print(y.grad_fn)
<AddBackward0 object at 0x0000028CCEE770C8>

做一些其他運(yùn)算:

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

print(z, out)
tensor([[27., 27.],
        [27., 27.]], grad_fn=<MulBackward0>) tensor(27., grad_fn=<MeanBackward0>)

.requires_grad_(...)方法可以改變tensor的requires_grad屬性。默認(rèn)情況下男摧,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)
False
True
<SumBackward0 object at 0x0000028CCEE83CC8>

接下來嘗試使用自動求導(dǎo)機(jī)制蔬墩,上文中使用到的out是一個標(biāo)量,那么對out反向傳播則可以直接調(diào)用out.backward()彩倚,等價于out.backward(torch.tensor(1))

out.backward()
print(x.grad)
tensor([[4.5000, 4.5000],
        [4.5000, 4.5000]])

檢驗(yàn):

\begin{equation}\begin{split} out&=\frac{1}{4}\sum_i{z_i}\\ z_i&=3({x_i}+2)^2\\ {z_i}\big|_{{x_i}=1}&=27\\ \frac{\partial out}{\partial x_i}&=\frac{3}{2}({x_i}+2)=4.5\\ \end{split}\end{equation}

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

y = x * 2
while y.data.norm() < 1000:  #norm是L-p范數(shù)筹我,默認(rèn)求2范數(shù)
    y = y * 2
    
print(y)
tensor([939.6540, 998.4269,   6.6829], grad_fn=<MulBackward0>)

L-P范數(shù) L_p=\left\|x\right\|_p=\sqrt[p]{\sum_{i=1}^n{x_{i}^{p}}}

此時y不再是標(biāo)量,自動求導(dǎo)機(jī)制不能直接計(jì)算Jacobian行列式帆离,反向傳播得到的.grad是vector-Jacobian積蔬蕊。

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

print(x.grad)
tensor([1.0240e+02, 1.0240e+03, 1.0240e-01])

with torch.no_grad():可以臨時取消對代碼塊內(nèi)的tensor的追蹤。

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

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

.detach()方法可以將tensor從自動求導(dǎo)機(jī)制中隔離出來哥谷,得到的新tensor將不再需要求導(dǎo)岸夯。

print(x.requires_grad)
# y和x數(shù)據(jù)相同,不需要求導(dǎo)
# y不是x的拷貝们妥,對y的修改也會影響x
# 如果直接令y = x猜扮,那么是不會取消追蹤的
y = x.detach() 
print(y.requires_grad)
print(x.eq(y).all())  # 對比全部數(shù)據(jù)
True
False
tensor(True)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市监婶,隨后出現(xiàn)的幾起案子旅赢,更是在濱河造成了極大的恐慌,老刑警劉巖惑惶,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件煮盼,死亡現(xiàn)場離奇詭異,居然都是意外死亡带污,警方通過查閱死者的電腦和手機(jī)僵控,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鱼冀,“玉大人报破,你說我怎么就攤上這事∏鳎” “怎么了充易?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長荸型。 經(jīng)常有香客問我蔽氨,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任鹉究,我火速辦了婚禮宇立,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘自赔。我一直安慰自己妈嘹,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布绍妨。 她就那樣靜靜地躺著润脸,像睡著了一般。 火紅的嫁衣襯著肌膚如雪他去。 梳的紋絲不亂的頭發(fā)上毙驯,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天,我揣著相機(jī)與錄音灾测,去河邊找鬼爆价。 笑死,一個胖子當(dāng)著我的面吹牛媳搪,可吹牛的內(nèi)容都是我干的铭段。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼秦爆,長吁一口氣:“原來是場噩夢啊……” “哼序愚!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起等限,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤爸吮,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后望门,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體形娇,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年怒允,在試婚紗的時候發(fā)現(xiàn)自己被綠了埂软。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片锈遥。...
    茶點(diǎn)故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡纫事,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出所灸,到底是詐尸還是另有隱情丽惶,我是刑警寧澤,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布爬立,位于F島的核電站钾唬,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜抡秆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一奕巍、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧儒士,春花似錦的止、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至拖叙,卻和暖如春氓润,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背薯鳍。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工咖气, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人辐啄。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓采章,卻偏偏與公主長得像,于是被迫代替她去往敵國和親壶辜。 傳聞我的和親對象是個殘疾皇子悯舟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評論 2 353