<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          PyTorch的自動求導(dǎo)機(jī)制詳細(xì)解析,PyTorch的核心魔法

          共 4756字,需瀏覽 10分鐘

           ·

          2022-07-05 10:35

          點(diǎn)擊上方小白學(xué)視覺”,選擇加"星標(biāo)"或“置頂

          重磅干貨,第一時間送達(dá)


          者:Vaibhav Kumar

          編譯:ronghuaiyang

          導(dǎo)讀

          這篇文章詳細(xì)解析了PyTorch的自動求導(dǎo)機(jī)制,讓你了解PyTorch的核心魔法。

          在這個過程中,它從不顯式地構(gòu)造整個雅可比矩陣。直接計算JVP通常更簡單、更有效。

          我們都同意,當(dāng)涉及到大型神經(jīng)網(wǎng)絡(luò)時,我們都不擅長微積分。通過顯式求解數(shù)學(xué)方程來計算這樣大的復(fù)合函數(shù)的梯度是不現(xiàn)實(shí)的,特別是這些曲線存在于大量的維數(shù)中,是無法理解的。

          要處理14維空間中的超平面,想象一個三維空間,大聲地對自己說“14”。每個人都這么做——Geoffrey Hinton

          這就是PyTorch的autograd發(fā)揮作用的地方。它抽象了復(fù)雜的數(shù)學(xué),幫助我們“神奇地”計算高維曲線的梯度,只需要幾行代碼。這篇文章試圖描述autograd的魔力。


          PyTorch基礎(chǔ)

          在進(jìn)一步討論之前,我們需要了解一些基本的PyTorch概念。

          張量:簡單地說,它只是PyTorch中的一個n維數(shù)組。張量支持一些額外的增強(qiáng),這使它們獨(dú)一無二:除了CPU,它們可以加載或GPU更快的計算。在設(shè)置.requires_grad = True的時候,他們開始形成一個反向圖,跟蹤應(yīng)用于他們的每個操作,使用所謂的動態(tài)計算圖(DCG)計算梯度(后面會進(jìn)一步解釋)。

          在早期版本的PyTorch中,使用torch.autograd.Variable類用于創(chuàng)建支持梯度計算和操作跟蹤的張量,但截至PyTorch v0.4.0,Variable類已被禁用。torch.Tensortorch.autograd.Variable現(xiàn)在是同一個類。更準(zhǔn)確地說, torch.Tensor能夠跟蹤歷史并表現(xiàn)得像舊的Variable

          import torch import numpy as np  x = torch.randn(2, 2, requires_grad = True)  # From numpy x = np.array([1., 2., 3.]) #Only Tensors of floating point dtype can require gradients x = torch.from_numpy(x) # Now enable gradient x.requires_grad_(True) # _ above makes the change in-place (its a common pytorch thing)

          創(chuàng)建啟用梯度的張量的各種方法的代碼

          注意:根據(jù)PyTorch的設(shè)計,梯度只能計算浮點(diǎn)張量,這就是為什么我創(chuàng)建了一個浮點(diǎn)類型的numpy數(shù)組,然后將它設(shè)置為啟用梯度的PyTorch張量。

          Autograd:這個類是一個計算導(dǎo)數(shù)的引擎(更精確地說是雅克比向量積)。它記錄了梯度張量上所有操作的一個圖,并創(chuàng)建了一個稱為動態(tài)計算圖的非循環(huán)圖。這個圖的葉節(jié)點(diǎn)是輸入張量,根節(jié)點(diǎn)是輸出張量。梯度是通過跟蹤從根到葉的圖形,并使用鏈?zhǔn)椒▌t將每個梯度相乘來計算的。


          神經(jīng)網(wǎng)絡(luò)和反向傳播

          神經(jīng)網(wǎng)絡(luò)只不過是經(jīng)過精心調(diào)整(訓(xùn)練)以輸出所需結(jié)果的復(fù)合數(shù)學(xué)函數(shù)。調(diào)整或訓(xùn)練是通過一種稱為反向傳播的出色算法完成的。反向傳播用來計算相對于輸入權(quán)值的損失梯度,以便以后更新權(quán)值,最終減少損失。

          在某種程度上,反向傳播只是鏈?zhǔn)椒▌t的一個花哨的名字—— Jeremy Howard

          創(chuàng)建和訓(xùn)練神經(jīng)網(wǎng)絡(luò)包括以下基本步驟:

          1. 定義體系結(jié)構(gòu)

          2. 使用輸入數(shù)據(jù)在體系結(jié)構(gòu)上向前傳播

          3. 計算損失

          4. 反向傳播,計算每個權(quán)重的梯度

          5. 使用學(xué)習(xí)率更新權(quán)重

          損失變化引起的輸入權(quán)值的微小變化稱為該權(quán)值的梯度,并使用反向傳播計算。然后使用梯度來更新權(quán)值,使用學(xué)習(xí)率來整體減少損失并訓(xùn)練神經(jīng)網(wǎng)絡(luò)。

          這是以迭代的方式完成的。對于每個迭代,都要計算幾個梯度,并為存儲這些梯度函數(shù)構(gòu)建一個稱為計算圖的東西。PyTorch通過構(gòu)建一個動態(tài)計算圖(DCG)來實(shí)現(xiàn)這一點(diǎn)。此圖在每次迭代中從頭構(gòu)建,為梯度計算提供了最大的靈活性。例如,對于前向操作(函數(shù))Mul ,向后操作函數(shù)MulBackward被動態(tài)集成到后向圖中以計算梯度。


          動態(tài)計算圖

           

          支持梯度的張量(變量)和函數(shù)(操作)結(jié)合起來創(chuàng)建動態(tài)計算圖。數(shù)據(jù)流和應(yīng)用于數(shù)據(jù)的操作在運(yùn)行時定義,從而動態(tài)地構(gòu)造計算圖。這個圖是由底層的autograd類動態(tài)生成的。你不必在啟動訓(xùn)練之前對所有可能的路徑進(jìn)行編碼——你運(yùn)行的是你所區(qū)分的。

          一個簡單的DCG用于兩個張量的乘法會是這樣的:

          帶有requires_grad = False的DCG

          圖中的每個點(diǎn)輪廓框是一個變量,紫色矩形框是一個操作。

          每個變量對象都有幾個成員,其中一些成員是:

          Data:它是一個變量持有的數(shù)據(jù)。x持有一個1x1張量,其值等于1.0,而y持有2.0。z持有兩個的乘積,即2.0。

          requires_grad:這個成員(如果為true)開始跟蹤所有的操作歷史,并形成一個用于梯度計算的向后圖。對于任意張量a,可以按如下方式對其進(jìn)行原地處理:a.requires_grad_(True)

          grad: grad保存梯度值。如果requires_grad 為False,它將持有一個None值。即使requires_grad 為真,它也將持有一個None值,除非從其他節(jié)點(diǎn)調(diào)用.backward()函數(shù)。例如,如果你對out關(guān)于x計算梯度,調(diào)用out.backward(),則x.grad的值為?out/?x

          grad_fn:這是用來計算梯度的向后函數(shù)。

          is_leaf:如果:

          1. 它被一些函數(shù)顯式地初始化,比如x = torch.tensor(1.0)x = torch.randn(1, 1)(基本上是本文開頭討論的所有張量初始化方法)。

          2. 它是在張量的操作之后創(chuàng)建的,所有張量都有requires_grad = False

          3. 它是通過對某個張量調(diào)用.detach()方法創(chuàng)建的。

          在調(diào)用backward()時,只計算requires_gradis_leaf同時為真的節(jié)點(diǎn)的梯度。

          當(dāng)打開 requires_grad = True時,PyTorch將開始跟蹤操作,并在每個步驟中存儲梯度函數(shù),如下所示:

          requires_grad = True的DCG

          在PyTorch下生成上圖的代碼是:


          Backward()函數(shù)


           

          Backward函數(shù)實(shí)際上是通過傳遞參數(shù)(默認(rèn)情況下是1x1單位張量)來計算梯度的,它通過Backward圖一直到每個葉節(jié)點(diǎn),每個葉節(jié)點(diǎn)都可以從調(diào)用的根張量追溯到葉節(jié)點(diǎn)。然后將計算出的梯度存儲在每個葉節(jié)點(diǎn)的.grad中。請記住,在正向傳遞過程中已經(jīng)動態(tài)生成了后向圖。backward函數(shù)僅使用已生成的圖形計算梯度,并將其存儲在葉節(jié)點(diǎn)中。

          讓我們分析以下代碼:

           import torch # Creating the graph x = torch.tensor(1.0, requires_grad = True) z = x ** 3 z.backward() #Computes the gradient print(x.grad.data) #Prints '3' which is dz/dx

          需要注意的一件重要事情是,當(dāng)調(diào)用z.backward()時,一個張量會自動傳遞為z.backward(torch.tensor(1.0))torch.tensor(1.0)是用來終止鏈?zhǔn)椒▌t梯度乘法的外部梯度。這個外部梯度作為輸入傳遞給MulBackward函數(shù),以進(jìn)一步計算x的梯度。傳遞到.backward()中的張量的維數(shù)必須與正在計算梯度的張量的維數(shù)相同。例如,如果梯度支持張量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

          然后,要計算z關(guān)于x或者y的梯度,需要將一個外部梯度傳遞給z.backward()函數(shù),如下所示:

           z.backward(torch.FloatTensor([1.0, 1.0, 1.0])

          z.backward() 會給出 RuntimeError: grad can be implicitly created only for scalar outputs

          反向函數(shù)傳遞的張量就像梯度加權(quán)輸出的權(quán)值。從數(shù)學(xué)上講,這是一個向量乘以非標(biāo)量張量的雅可比矩陣(本文將進(jìn)一步討論),因此它幾乎總是一個維度的單位張量,與 backward張量相同,除非需要計算加權(quán)輸出。

          tldr :向后圖是由autograd類在向前傳遞過程中自動動態(tài)創(chuàng)建的。Backward()只是通過將其參數(shù)傳遞給已經(jīng)生成的反向圖來計算梯度。 


          數(shù)學(xué)—雅克比矩陣和向量

          從數(shù)學(xué)上講,autograd類只是一個雅可比向量積計算引擎。雅可比矩陣是一個非常簡單的單詞,它表示兩個向量所有可能的偏導(dǎo)數(shù)。它是一個向量相對于另一個向量的梯度。

          注意:在這個過程中,PyTorch從不顯式地構(gòu)造整個雅可比矩陣。直接計算JVP (Jacobian vector product)通常更簡單、更有效。

          如果一個向量X = [x1, x2,…xn]通過f(X) = [f1, f2,…fn]來計算其他向量,則雅可比矩陣(J)包含以下所有偏導(dǎo)組合:

          雅克比矩陣

          上面的矩陣表示f(X)相對于X的梯度。

          假設(shè)一個啟用PyTorch梯度的張量X

          X = [x1,x2,…,xn](假設(shè)這是某個機(jī)器學(xué)習(xí)模型的權(quán)值)

          X經(jīng)過一些運(yùn)算形成一個向量Y

          Y = f(X) = [y1, y2,…,ym]

          然后使用Y計算標(biāo)量損失l。假設(shè)向量v恰好是標(biāo)量損失l關(guān)于向量Y的梯度,如下:

          向量v稱為grad_tensor,并作為參數(shù)傳遞給backward() 函數(shù)。

          為了得到損失的梯度l關(guān)于權(quán)重X的梯度,雅可比矩陣J是向量乘以向量v

          這種計算雅可比矩陣并將其與向量v相乘的方法使PyTorch能夠輕松地為非標(biāo)量輸出提供外部梯度。


          好消息!

          小白學(xué)視覺知識星球

          開始面向外開放啦??????




          下載1:OpenCV-Contrib擴(kuò)展模塊中文版教程
          在「小白學(xué)視覺」公眾號后臺回復(fù):擴(kuò)展模塊中文教程即可下載全網(wǎng)第一份OpenCV擴(kuò)展模塊教程中文版,涵蓋擴(kuò)展模塊安裝、SFM算法、立體視覺、目標(biāo)跟蹤、生物視覺、超分辨率處理等二十多章內(nèi)容。

          下載2:Python視覺實(shí)戰(zhàn)項(xiàng)目52講
          小白學(xué)視覺公眾號后臺回復(fù):Python視覺實(shí)戰(zhàn)項(xiàng)目即可下載包括圖像分割、口罩檢測、車道線檢測、車輛計數(shù)、添加眼線、車牌識別、字符識別、情緒檢測、文本內(nèi)容提取、面部識別等31個視覺實(shí)戰(zhàn)項(xiàng)目,助力快速學(xué)校計算機(jī)視覺。

          下載3:OpenCV實(shí)戰(zhàn)項(xiàng)目20講
          小白學(xué)視覺公眾號后臺回復(fù):OpenCV實(shí)戰(zhàn)項(xiàng)目20講即可下載含有20個基于OpenCV實(shí)現(xiàn)20個實(shí)戰(zhàn)項(xiàng)目,實(shí)現(xiàn)OpenCV學(xué)習(xí)進(jìn)階。

          交流群


          歡迎加入公眾號讀者群一起和同行交流,目前有SLAM、三維視覺、傳感器自動駕駛、計算攝影、檢測、分割、識別、醫(yī)學(xué)影像、GAN算法競賽等微信群(以后會逐漸細(xì)分),請掃描下面微信號加群,備注:”昵稱+學(xué)校/公司+研究方向“,例如:”張三 + 上海交大 + 視覺SLAM“。請按照格式備注,否則不予通過。添加成功后會根據(jù)研究方向邀請進(jìn)入相關(guān)微信群。請勿在群內(nèi)發(fā)送廣告,否則會請出群,謝謝理解~


          瀏覽 48
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲 国产 另类 无码 日韩 | 香港操逼视频 | 99爱视频在线 | 日逼网站视频 | 国产性爱网址 |