pytorch 矩阵相乘_深度学习 — — PyTorch入门(三)
autograd和動(dòng)態(tài)計(jì)算圖可以說是pytorch中非常核心的部分,我們?cè)谥暗奈恼轮刑岬?#xff1a;autograd其實(shí)就是反向求偏導(dǎo)的過程,而在求偏導(dǎo)的過程中,鏈?zhǔn)角髮?dǎo)法則和雅克比矩陣是其實(shí)現(xiàn)的數(shù)學(xué)基礎(chǔ);Tensor構(gòu)成的動(dòng)態(tài)計(jì)算圖是使用pytorch的實(shí)現(xiàn)的結(jié)構(gòu)。
backward()函數(shù)
backward()是通過將參數(shù)(默認(rèn)為1x1單位張量)通過反向圖追蹤所有對(duì)于該張量的操作,使用鏈?zhǔn)角髮?dǎo)法則從根張量追溯到每個(gè)葉子節(jié)點(diǎn)以計(jì)算梯度。下圖描述了pytorch對(duì)于函數(shù)z = (a + b)(b - c)構(gòu)建的計(jì)算圖,以及從根節(jié)點(diǎn)z到葉子節(jié)點(diǎn)a,b,c的求導(dǎo)過程:
注意:計(jì)算圖已經(jīng)在前向傳遞過程中已經(jīng)被動(dòng)態(tài)創(chuàng)建了,反向傳播僅使用已存在的計(jì)算圖計(jì)算梯度并將其存儲(chǔ)在葉子節(jié)點(diǎn)中。
為了節(jié)約內(nèi)存,在每一輪迭代完成后,計(jì)算圖就會(huì)被釋放,若需要多次調(diào)用backward()方法,則需要在使用時(shí)添加retain_graph=True,否則會(huì)報(bào)如下錯(cuò)誤:
RuntimeError:?Trying to backward through the graph a second time, but the buffers have already been freed.
若我們?cè)谑褂眠^程中,僅僅想求得某個(gè)節(jié)點(diǎn)的梯度,而非整個(gè)圖的梯度,則需要用到Tensor的.grad屬性,如下列代碼所示:
import torch# 創(chuàng)建計(jì)算圖x = torch.tensor(1.0, requires_grad = True)z = x ** 3# 計(jì)算梯度z.backward() print(x.grad.data)需要注意的是:當(dāng)調(diào)用z.backward()時(shí),將自動(dòng)計(jì)算z.backward(torch.tensor(1.0)),其中 torch.tensor(1.0)是用于終止連式法則梯度乘法的外部梯度??梢詫⒋俗鳛檩斎雮鬟f給MulBackward函數(shù),以進(jìn)一步計(jì)算x的梯度。
在上述的示例中,我們給出了標(biāo)量對(duì)向量的求導(dǎo)過程,那么當(dāng)向量對(duì)向量進(jìn)行求導(dǎo)時(shí)呢?例如,需要計(jì)算梯度的張量x和y如下:
x = torch.tensor([0.0, 2.0, 8.0], requires_grad = True)y = torch.tensor([5.0 , 1.0 , 7.0], requires_grad = True)z = x * y此時(shí)調(diào)用z.backward()函數(shù)將會(huì)報(bào)如下錯(cuò)誤:
RuntimeError: grad can be implicitly created only for scalar outputs
錯(cuò)誤提示我們只能應(yīng)用于標(biāo)量輸出。若我們想對(duì)向量z進(jìn)行梯度計(jì)算,先了解一下Jacobian矩陣。
Jacobian矩陣和向量
從數(shù)學(xué)角度上來講:雅克比矩陣是基于函數(shù)對(duì)所有變量一階偏導(dǎo)數(shù)的數(shù)值矩陣,當(dāng)輸入個(gè)數(shù)等于輸出個(gè)數(shù)時(shí)又稱為雅克比行列式。
而autograd類在實(shí)際運(yùn)用的過程中也是通過計(jì)算雅克比向量積實(shí)現(xiàn)對(duì)向量梯度的計(jì)算。簡單來說,雅可比矩陣是代表兩個(gè)向量的所有可能偏導(dǎo)數(shù)的矩陣,可以用于求一個(gè)向量相對(duì)于另一個(gè)向量的梯度。
注:在此過程中,PyTorch不會(huì)顯式構(gòu)造整個(gè)Jacobian矩陣,而是直接計(jì)算Jacobian矢量積,這種計(jì)算方式更為簡便。
如果向量X = [x1,x2,… xn]通過函數(shù)f(X)= [f1,f2,… fn]計(jì)算其他向量,假設(shè)f對(duì)于x的每個(gè)一階偏導(dǎo)數(shù)都存在,則f(X)相對(duì)于X的梯度矩陣為:
假設(shè)待計(jì)算梯度的張量X為:X = [x1,x2,… xn](機(jī)器學(xué)習(xí)模型的權(quán)重),X可以進(jìn)行一些運(yùn)算以形成向量Y:Y = f(X)= [y1,y2,… ym]。然后,使用Y來計(jì)算標(biāo)量損失l。假設(shè)向量v恰好是標(biāo)量損失l相對(duì)于向量Y的梯度,則:
此時(shí),向量v則被稱為grad_tensor,即梯度張量。并將其作為參數(shù)傳遞給backward()函數(shù)。為了獲得損失l相對(duì)于權(quán)重X的梯度,將Jacobian矩陣J與向量v相乘,得到最終梯度:
綜上所述,pytorch在使用計(jì)算圖求導(dǎo)的過程中整體可以分為以下兩種情況:
1. 若標(biāo)量對(duì)向量求導(dǎo),則可以直接調(diào)用backward()函數(shù);
2. 若向量A對(duì)向量B求導(dǎo),則先求得向量A對(duì)于向量B的Jacobian矩陣,并將其與grad_tensors對(duì)應(yīng)的矩陣進(jìn)行點(diǎn)乘計(jì)算得到最終梯度。
·? END? ·
RECOMMEND推薦閱讀?1. 效率提升的軟件大禮包
?2.?深度學(xué)習(xí)——入門PyTorch(一)
?3.?深度學(xué)習(xí)——入門PyTorch(二)
?4. PyTorch入門——autograd(一)
?5. PyTorch入門——autograd(二)
總結(jié)
以上是生活随笔為你收集整理的pytorch 矩阵相乘_深度学习 — — PyTorch入门(三)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 哪种语言 连接 oracle,Go语言连
- 下一篇: 计算机视觉中的多视图几何_基于深度学习的