欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Pytorch自動(dòng)求導(dǎo)函數(shù)詳解流程以及與TensorFlow搭建網(wǎng)絡(luò)的對(duì)比

 更新時(shí)間:2021年11月01日 08:45:03   作者:柚子味的羊  
PyTorch是一個(gè)開(kāi)源的Python機(jī)器學(xué)習(xí)庫(kù),基于Torch,用于自然語(yǔ)言處理等應(yīng)用程序。2017年1月,由Facebook人工智能研究院(FAIR)基于Torch推出了PyTorch,這篇文章主要介紹了Pytorch自定義自動(dòng)求導(dǎo)函數(shù),以及PyTorch與TensorFlow搭建網(wǎng)絡(luò)的對(duì)比

一、定義新的自動(dòng)求導(dǎo)函數(shù)

在底層,每個(gè)原始的自動(dòng)求導(dǎo)運(yùn)算實(shí)際上是兩個(gè)在Tensor上運(yùn)行的函數(shù)。其中,forward函數(shù)計(jì)算從輸入Tensor獲得的輸出Tensors。而backward函數(shù)接收輸出,Tensors對(duì)于某個(gè)標(biāo)量值得梯度,并且計(jì)算輸入Tensors相對(duì)于該相同標(biāo)量值得梯度。
在Pytorch中,可以容易地通過(guò)定義torch.autograd.Function的子類實(shí)現(xiàn)forward和backward函數(shù),來(lái)定義自動(dòng)求導(dǎo)函數(shù)。之后就可以使用這個(gè)新的自動(dòng)梯度運(yùn)算符了。我們可以通過(guò)構(gòu)造一個(gè)實(shí)例并調(diào)用函數(shù),傳入包含輸入數(shù)據(jù)的tensor調(diào)用它,這樣來(lái)使用新的自動(dòng)求導(dǎo)運(yùn)算
以下例子,自定義一個(gè)自動(dòng)求導(dǎo)函數(shù)展示ReLU的非線性,并調(diào)用它實(shí)現(xiàn)兩層網(wǎng)絡(luò),如上一節(jié)

import torch
class myrelu(torch.autograd.Function):#自定義子類
    # 通過(guò)建立torch.autograd的子類來(lái)實(shí)現(xiàn)自定義的autograd函數(shù),并完成張量的正向和反向傳播
    @staticmethod
    def forward(ctx, x):
        # 在正向傳播中,接受到一個(gè)上下文對(duì)象和一個(gè)包含輸入的張量,必須返回一個(gè)包含輸出的張量,可以使用上下文對(duì)象來(lái)緩存對(duì)象,以便在反向傳播中使用
        ctx.save_for_backward(x)
        return x.clamp(min=0)
    @staticmethod
    def backward(ctx, grad_output):
        """
        在反向傳播中,我們接收到上下文對(duì)象和一個(gè)張量,
        其包含了相對(duì)于正向傳播過(guò)程中產(chǎn)生的輸出的損失的梯度。
        我們可以從上下文對(duì)象中檢索緩存的數(shù)據(jù),
        并且必須計(jì)算并返回與正向傳播的輸入相關(guān)的損失的梯度。
        """
        x, = ctx.saved_tensors
        grad_x = grad_output.clone()
        grad_x[x < 0] = 0
        return grad_x

調(diào)用自定義的類實(shí)現(xiàn)兩層網(wǎng)絡(luò)

#%%
device=torch.device('cuda' if torch.cuda.is_available() else 'cpu')
# n是批量大小,d_in是輸入維度
# h是隱藏的維度,d_out是輸出維度
n,d_in,h,d_out=64,1000,100,10
# 創(chuàng)建隨機(jī)輸入和輸出數(shù)據(jù),requires_grad默認(rèn)設(shè)置為False,表示不需要后期微分操作
x=torch.randn(n,d_in,device=device)
y=torch.randn(n,d_out,device=device)
# 隨機(jī)初始化權(quán)重,requires_grad默認(rèn)設(shè)置為T(mén)rue,表示想要計(jì)算其微分
w1=torch.randn(d_in,h,device=device,requires_grad=True)
w2=torch.randn(h,d_out,device=device,requires_grad=True)

learning_rate=1e-6
for i in range(500):
    #前向傳播,使用tensor上的操作計(jì)算預(yù)測(cè)值y
  #調(diào)用自定義的myrelu.apply函數(shù)
    y_pred=myrelu.apply(x.mm(w1)).mm(w2)
       
    
    #使用tensor中的操作計(jì)算損失值,loss.item()得到loss這個(gè)張量對(duì)應(yīng)的數(shù)值
    loss=(y_pred-y).pow(2).sum()
    print(i,loss.item())
    
    #使用autograd計(jì)算反向傳播,這個(gè)調(diào)用將計(jì)算loss對(duì)所有的requires_grad=True的tensor梯度,
    #調(diào)用之后,w1.grad和w2.grad將分別是loss對(duì)w1和w2的梯度張量
    loss.backward()
    #使用梯度下降更新權(quán)重,只想對(duì)w1和w2的值進(jìn)行原地改變:不想更新構(gòu)建計(jì)算圖
    #所以使用torch.no_grad()阻止pytorch更新構(gòu)建計(jì)算圖
    with torch.no_grad():
        w1-=learning_rate*w1.grad
        w2-=learning_rate*w2.grad
        #反向傳播后手動(dòng)將梯度置零
        w1.grad.zero_()
        w2.grad.zero_() 

運(yùn)行結(jié)果

在這里插入圖片描述


在這里插入圖片描述

二、Pytorch 和 TensorFlow對(duì)比

  • PyTorch自動(dòng)求導(dǎo)看似非常像TensorFlow:這兩個(gè)框架中,都定義了計(jì)算圖,使用自動(dòng)微分來(lái)計(jì)算梯度,兩者最大的不同是TensorFlow的計(jì)算圖是靜態(tài)的,而PyTorch使用的是動(dòng)態(tài)的計(jì)算圖。
  • 在TensorFlow中,定義計(jì)算圖一次,然后重復(fù)執(zhí)行相同的圖,可能會(huì)提供不同的輸入數(shù)據(jù),而在PyTorch中,每一個(gè)前向通道定義一個(gè)新的計(jì)算圖。
  • **靜態(tài)圖的好處在于可以預(yù)先對(duì)圖進(jìn)行優(yōu)化。**如:一個(gè)框架可以融合一些圖的運(yùn)算來(lái)提升效率,或者產(chǎn)生一個(gè)策略來(lái)將圖分布到多個(gè)GPU或機(jī)器上。但是如果重復(fù)使用相同的圖,那么重復(fù)運(yùn)行同一個(gè)圖時(shí),前期潛在的代價(jià)高昂的預(yù)先優(yōu)化的消耗就會(huì)被分?jǐn)偂?/li>
  • 靜態(tài)圖和動(dòng)態(tài)圖的一個(gè)區(qū)別就是控制流。對(duì)于一些模型,對(duì)每個(gè)數(shù)據(jù)點(diǎn)執(zhí)行不同的計(jì)算。如:一個(gè)遞歸神經(jīng)網(wǎng)絡(luò)可能對(duì)于每個(gè)數(shù)據(jù)點(diǎn)執(zhí)行不同的時(shí)間步數(shù),這個(gè)展開(kāi)可以作為一個(gè)循環(huán)來(lái)實(shí)現(xiàn)。對(duì)于一個(gè)靜態(tài)圖,循環(huán)結(jié)構(gòu)要作為圖的一部分。因此,TensorFlow提供了運(yùn)算符將循環(huán)嵌入到圖當(dāng)中。對(duì)于動(dòng)態(tài)圖來(lái)說(shuō),情況更加簡(jiǎn)單:為每個(gè)例子即時(shí)創(chuàng)建圖,使用普通的命令式控制流來(lái)為每個(gè)輸入執(zhí)行不同的計(jì)算。

使用TensorFlow擬合一個(gè)簡(jiǎn)單的兩層網(wǎng)絡(luò)(上面做對(duì)比):

#%%使用TensorFlow
import tensorflow.compat.v1 as tf   #為了用placeholder不惜一切代價(jià)
tf.disable_v2_behavior()
import numpy as np
#%%
# 建立計(jì)算圖

# n是批量大小,d_in是輸入維度
# h是隱藏的維度,d_out是輸出維度
n,d_in,h,d_out=64,1000,100,10

# 為輸入和目標(biāo)數(shù)據(jù)創(chuàng)建placeholder,在執(zhí)行計(jì)算圖時(shí),他們將會(huì)被真實(shí)的數(shù)據(jù)填充
x=tf.placeholder(tf.float32,shape=(None,d_in))
y=tf.placeholder(tf.float32,shape=(None,d_out))

# 為權(quán)重創(chuàng)建variable并用隨機(jī)數(shù)據(jù)初始化,TensorFlow的variable在執(zhí)行計(jì)算圖時(shí)不會(huì)改變
w1 = tf.Variable(tf.random_normal((d_in,h)))
w2=tf.Variable(tf.random_normal((h,d_out)))
# 前向傳播:使用TensorFlow的張量運(yùn)算計(jì)算預(yù)測(cè)值y(這段代碼不執(zhí)行任何數(shù)值運(yùn)算,只是建立了稍后要執(zhí)行的計(jì)算圖)
h=tf.matmul(x,w1)
h_relu=tf.maximum(h,tf.zeros(1))
y_pred=tf.matmul(h_relu,w2)
# 使用TensorFlow的張量運(yùn)算損失loss
loss=tf.reduce_sum((y-y_pred)**2.0)
# 計(jì)算loss對(duì)于權(quán)重w1和w2的導(dǎo)數(shù)
grad_w1,grad_w2=tf.gradients(loss,[w1,w2])
# 使用梯度下降更新權(quán)重,為了實(shí)際更新權(quán)重,我們需要在執(zhí)行計(jì)算圖時(shí)計(jì)算new_w1和new_w2
# 注:在TensorFlow中,更新權(quán)重值得行為是計(jì)算圖的一部分,但在Pytorch中發(fā)生在計(jì)算圖形之外
learning_rate=1e-6
new_w1=w1.assign(w1-learning_rate*grad_w1)
new_w2=w2.assign(w2-learning_rate*grad_w2)

# 現(xiàn)在搭建好了計(jì)算圖,開(kāi)始一個(gè)TensorFlow回話來(lái)執(zhí)行計(jì)算圖
with tf.Session() as sess:
    # 運(yùn)算一次計(jì)算圖來(lái)出事話variable w1和w2
    sess.run(tf.global_variables_initializer())
    # 創(chuàng)建numpy數(shù)組存儲(chǔ)輸入x和目標(biāo)y的實(shí)際數(shù)據(jù)
    x_value=np.random.randn(n,d_in)
    y_value=np.random.randn(n,d_out)
    for i in range(500):
        # 多次運(yùn)行計(jì)算圖,每次執(zhí)行時(shí),都有feed_dict參數(shù),
        # 將x_value綁定到x,將y_value綁定到y(tǒng).每次執(zhí)行計(jì)算圖都要計(jì)算損失,
        # new_w1和new_w2,這些張量的值以numpy數(shù)組的形式返回
        loss_value,i,i=sess.run([loss,new_w1,new_w2],
                                feed_dict={x:x_value,y:y_value})
        print(loss_value)

運(yùn)行結(jié)果

在這里插入圖片描述


在這里插入圖片描述

今日告一段落,重點(diǎn)是比較了TensorFlow和Pytorch在自動(dòng)求導(dǎo)中的區(qū)別——計(jì)算圖前者是靜態(tài)的,后者是動(dòng)態(tài)的。
再見(jiàn)啦,明天可能不更~因?yàn)橄挛缤砩隙加姓n,雖然我可能不去上(哈哈哈哈哈哈哈哈,別學(xué)我)后面一節(jié)來(lái)寫(xiě)神經(jīng)網(wǎng)絡(luò),不見(jiàn)不散!!

到此這篇關(guān)于Pytorch自動(dòng)求導(dǎo)函數(shù)詳解流程以及與TensorFlow搭建網(wǎng)絡(luò)的對(duì)比的文章就介紹到這了,更多相關(guān)Pytorch 自動(dòng)求導(dǎo)函數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python流程控制if條件選擇與for循環(huán)

    Python流程控制if條件選擇與for循環(huán)

    這篇文章主要介紹了Python流程控制if條件選擇與for循環(huán),文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下
    2022-07-07
  • python 實(shí)現(xiàn)將Numpy數(shù)組保存為圖像

    python 實(shí)現(xiàn)將Numpy數(shù)組保存為圖像

    今天小編就為大家分享一篇python 實(shí)現(xiàn)將Numpy數(shù)組保存為圖像,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-01-01
  • Python中itertools庫(kù)的四個(gè)函數(shù)介紹

    Python中itertools庫(kù)的四個(gè)函數(shù)介紹

    這篇文章主要介紹了Python中itertools庫(kù)的四個(gè)函數(shù),主要討論itertools庫(kù)中的十分使用的幾個(gè)函數(shù),并重點(diǎn)介紹什么時(shí)候我們應(yīng)該考慮使用它們,需要的朋友可以參考一下
    2022-04-04
  • 詳解scrapy內(nèi)置中間件的順序

    詳解scrapy內(nèi)置中間件的順序

    這篇文章主要介紹了詳解scrapy內(nèi)置中間件的順序,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • python+selenium 定位到元素,無(wú)法點(diǎn)擊的解決方法

    python+selenium 定位到元素,無(wú)法點(diǎn)擊的解決方法

    今天小編就為大家分享一篇python+selenium 定位到元素,無(wú)法點(diǎn)擊的解決方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-01-01
  • Pygame游戲開(kāi)發(fā)之太空射擊實(shí)戰(zhàn)盾牌篇

    Pygame游戲開(kāi)發(fā)之太空射擊實(shí)戰(zhàn)盾牌篇

    相信大多數(shù)8090后都玩過(guò)太空射擊游戲,在過(guò)去游戲不多的年代太空射擊自然屬于經(jīng)典好玩的一款了,今天我們來(lái)自己動(dòng)手實(shí)現(xiàn)它,在編寫(xiě)學(xué)習(xí)中回顧過(guò)往展望未來(lái),在本課中,我們將為玩家添加一個(gè)盾牌以及一個(gè)用于顯示盾牌等級(jí)的欄
    2022-08-08
  • 淺談keras2 predict和fit_generator的坑

    淺談keras2 predict和fit_generator的坑

    這篇文章主要介紹了淺談keras2 predict和fit_generator的坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-06-06
  • 圖解python全局變量與局部變量相關(guān)知識(shí)

    圖解python全局變量與局部變量相關(guān)知識(shí)

    這篇文章主要介紹了圖解python全局變量與局部變量相關(guān)知識(shí),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • Anaconda環(huán)境改名的實(shí)現(xiàn)步驟

    Anaconda環(huán)境改名的實(shí)現(xiàn)步驟

    本文主要介紹了Anaconda環(huán)境改名的實(shí)現(xiàn)步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • 詳解Python實(shí)現(xiàn)圖像分割增強(qiáng)的兩種方法

    詳解Python實(shí)現(xiàn)圖像分割增強(qiáng)的兩種方法

    圖像分割就是把圖像分成若干個(gè)特定的、具有獨(dú)特性質(zhì)的區(qū)域并提出感興趣目標(biāo)的技術(shù)和過(guò)程。本文將為大家分享兩個(gè)用Python實(shí)現(xiàn)像分割增強(qiáng)的方法,需要的可以參考一下
    2022-03-03

最新評(píng)論