最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

PyTorch的張量tensor和自動(dòng)求導(dǎo)autograd詳解

 更新時(shí)間:2024年02月27日 10:04:56   作者:Vic·Tory  
這篇文章主要介紹了PyTorch的張量tensor和自動(dòng)求導(dǎo)autograd,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

PyTorch是一個(gè)基于python的科學(xué)計(jì)算包,除了可以替代NumPy構(gòu)建數(shù)組張量來(lái)利用GPU進(jìn)行計(jì)算之外,還是一個(gè)高靈活性、速度快的深度學(xué)習(xí)平臺(tái)

張量

張量(Tensor)實(shí)際上是一個(gè)多維數(shù)組,使用GPU可以加速?gòu)埩康倪\(yùn)算。

創(chuàng)建tensor:可以通過(guò)torch.tensor()將普通數(shù)組轉(zhuǎn)化為tensor,torch.empty()rand()可以創(chuàng)建隨機(jī)tensor,torch.zeros()、ones()創(chuàng)建數(shù)據(jù)都是0或1的tensor。

t.clone()可以克隆一個(gè)張量,t.size()可以獲取張量的形狀。

import torch

t = torch.tensor([[5, 6], [7, 8]])  # 轉(zhuǎn)化為tensor
t1 = torch.empty(5, 3)  # 創(chuàng)建隨機(jī)5×3的tensor
t2 = torch.rand(5, 3)
t3 = torch.zeros(5, 3, dtype=torch.float16)  # 創(chuàng)建全為0的5×3數(shù)組
t4 = torch.ones(5, 3)	# 創(chuàng)建全為1的
t5 = torch.ones_like(t3)	# 創(chuàng)建形狀和t3一樣、全為1的數(shù)組
print(t5.size())  # 輸出:torch.Size([5, 3])

操作tensor:tensor可以像Numpy一樣直接對(duì)數(shù)組進(jìn)行索引、截取、切片等操作。

  • view(-1,2)可以改變tensor的形狀,類似于numpy.reshape(),這里修改為第一維長(zhǎng)度為2,第二維-1代表自動(dòng)計(jì)算維度。
  • permute()可以交換數(shù)組維度位置,類似于numpy.transpose()
  • squeeze()可以壓縮張量中長(zhǎng)度為1的維度,比如數(shù)組[[1,2,3]]形狀為(1,3),經(jīng)過(guò)壓縮后變成長(zhǎng)度為3的數(shù)組[1,2,3]。反之,unsqueeze()可以在指定位置將維度增加長(zhǎng)度為1
  • expand()可以按原數(shù)據(jù)為元素?cái)U(kuò)大維度,即將原來(lái)的數(shù)據(jù)復(fù)制多份并一起組成更高維度,擴(kuò)大tensor不需要分配新內(nèi)存,只是僅僅新建一個(gè)tensor的視圖。使用時(shí)注意保持新維度與原維度的統(tǒng)一。
t = torch.tensor([[1, 2, 3],
                  [4, 5, 6]])
print(t[0, :2])  # 選取首行前兩個(gè)元素,輸出tensor([1, 2])
print(t.view(-1, 2))	# 改變形狀
'''
tensor([[1, 2],
        [3, 4],
        [5, 6]])
'''
t = torch.unsqueeze(t, dim=0)  # 給張量第一維增加一個(gè)維度
print(t)
'''
tensor([[[1, 2, 3],
         [4, 5, 6]]])
'''
print(t.permute(2, 1, 0))  # 交換維度位置
'''
tensor([[1, 3, 5],
        [2, 4, 6]])
'''
print(t.expand(2, 2, 3))    # 將(2,3)的tensor擴(kuò)維成為(2,2,3)
'''
tensor([[[1, 2, 3],
         [4, 5, 6]],
        [[1, 2, 3],
         [4, 5, 6]]])
'''

通過(guò)tensor進(jìn)行四則運(yùn)算也十分方便,下面以加法為例記錄幾種使用的形式:

x = torch.tensor([[1, 2, 3],
                  [4, 5, 6]])
y = torch.tensor([[7, 8, 9],
                  [10, 11, 12]])
print(x + y)  # 用運(yùn)算符
print(torch.add(x, y))  # 用add()函數(shù)
z = torch.empty(2, 3)
torch.add(x, y, out=z)  # 指明輸出對(duì)象
print(z)
y.add_(x)  # 在原數(shù)組上操作
print(y)

值得注意的是,pytorch中在原張量上進(jìn)行的操作函數(shù)后面都跟有一個(gè)_,例如其他的還有在原張量上復(fù)制x.copy_()。

和NumPy數(shù)組相互轉(zhuǎn)化:通過(guò)tensor.numpy()可以將tensor轉(zhuǎn)為numpy數(shù)組,但二者會(huì)共享一個(gè)內(nèi)存空間,即對(duì)tensor進(jìn)行的修改操作之后,輸出numpy的結(jié)果也會(huì)隨之改變。如果希望產(chǎn)生一個(gè)新的可以通過(guò)clone()函數(shù)。通過(guò)torch.from_numpy()可以從numpy數(shù)組創(chuàng)建tensor,同樣地二者共享內(nèi)存。

t = torch.ones(5)
print(t)
n1 = t.numpy()  # 轉(zhuǎn)化為numpy
n2 = t.clone().numpy()
t.add_(1)  # 對(duì)原來(lái)的tensor進(jìn)行操作
print(n1)
print(n2)

n = np.ones(5)	
t2 = torch.from_numpy(n)	# 從numpy創(chuàng)建tensor
'''
tensor([1., 1., 1., 1., 1.])	原來(lái)的t
[2. 2. 2. 2. 2.]				操作t后對(duì)應(yīng)的n1也隨之改變
[1. 1. 1. 1. 1.]				但是克隆產(chǎn)生的n2不會(huì)改變
'''

使用不同設(shè)備計(jì)算tensor,例如下面使用to()來(lái)將tensor移入和移出GPU

if torch.cuda.is_available():
    device = torch.device("cuda")  # a CUDA device object
    y = torch.ones_like(x, device=device)  # 直接在GPU上創(chuàng)建tensor
    x = x.to(device)  # 或者使用.to("cuda"),將tensor移入GPU
    z = x + y
    print(z)
    print(z.to("cpu", torch.double))  # 將tensor移出GPU,也能在移動(dòng)時(shí)改變dtype
'''
tensor([2., 2., 2., 2., 2.], device='cuda:0')
tensor([2., 2., 2., 2., 2.], dtype=torch.float64)
'''

自動(dòng)求導(dǎo)

PyTorch中,所有神經(jīng)網(wǎng)絡(luò)的核心是 autograd 包,它為張量上的所有操作提供了自動(dòng)求導(dǎo)機(jī)制。

Pytorch通過(guò)Tensor來(lái)儲(chǔ)存數(shù)據(jù),我們可以把它看作一個(gè)節(jié)點(diǎn),通過(guò)Function實(shí)現(xiàn)數(shù)據(jù)操作,即節(jié)點(diǎn)之間轉(zhuǎn)換的路徑。

如下所示為一個(gè)訓(xùn)練過(guò)程,輸入張量x,經(jīng)過(guò)一系列操作之后得到輸出y。

如下所示為實(shí)現(xiàn)上面過(guò)程的代碼,首先通過(guò)tensor定義張量,通過(guò)屬性requires_grad指定是否需要自動(dòng)求導(dǎo)。之后執(zhí)行正向操作*w1、+b、*w2,最后求平均得到輸出y。

接著通過(guò)backward()執(zhí)行反向傳播,就可以得到張量的grad值了。

# 定義張量
x = torch.ones(5, requires_grad=True)
w1 = torch.tensor(2.0, requires_grad=True)
w2 = torch.tensor(3.0, requires_grad=True)
b = torch.tensor(4.0, requires_grad=False)

# 執(zhí)行正向操作
l1 = x * w1
l2 = l1 + b
l3 = l2 * w2
y = l3.mean()

# 反向傳播
y.backward()

print(l1.data, l1.grad, l1.grad_fn)
# tensor([2., 2., 2., 2., 2.]) None <MulBackward0 object at 0x0000024D8E921BE0>
print(l2.data, l2.grad, l2.grad_fn)
# tensor([6., 6., 6., 6., 6.]) None <AddBackward0 object at 0x000001B960FC0F98>
print(y)
# tensor(18., grad_fn=<MeanBackward0>)
print(w1.grad, w2.grad)
# tensor(3.) tensor(6.)
print(x.grad)
# tensor([1.2000, 1.2000, 1.2000, 1.2000, 1.2000])

從上面的輸出可以看到x一開(kāi)始為[1,1,1,1,1],乘以w1后為[2., 2., 2., 2., 2.],+b之后為[6., 6., 6., 6., 6.],再乘以3為[18., 18., 18., 18., 18.],求均值得到y(tǒng)為18。

Tensor的grad_fn屬性用于記錄上一步是經(jīng)過(guò)怎樣的操作得到自己的,用于反向傳播時(shí)進(jìn)行求導(dǎo)。例如l1.grad_fn為MulBackward0代表其反向傳播操作為乘法

反向傳播后通過(guò)grade屬性可以獲得最后輸出對(duì)本張量的導(dǎo)數(shù)值。例如上面的操作中輸出為y,反向傳播后,w2.grad獲得的就是dy/dw2。由鏈?zhǔn)角髮?dǎo)法則可得dy/dw2=dy/dl3 × dl3/dw2。由于y由l3求均值得到,即y=1/5(Σl3),所以dy/dl3=1/5,又l3=l2 * w2,所以dl3/dw2=l2,所以dy/dw2=1/5*l2=1/5(6., 6., 6., 6., 6.)=6。同理通過(guò)反向鏈?zhǔn)角髮?dǎo)得到w1、x的grad

注意到l1、l2的grade值為None,這是由于張量l1、l2、l3都是中間計(jì)算結(jié)果,它們被稱為非葉張量,相對(duì)地由用戶創(chuàng)建的x、w1、w2被稱為葉張量(leaf tensor)。pytorch為了節(jié)約內(nèi)存并不會(huì)保存中間張量的導(dǎo)數(shù)值,只會(huì)用grad_fn來(lái)記錄是通過(guò)什么操作產(chǎn)生的。如果我們希望查看的話,可以通過(guò)retain_grad()來(lái)保存非葉張量的導(dǎo)數(shù)值。

...
l1.retain_grad()
l2.retain_grad()
y.backward()

print(l1.data, l1.grad, l1.grad_fn)
# tensor([2., 2., 2., 2., 2.]) tensor([0.6000, 0.6000, 0.6000, 0.6000, 0.6000]) <MulBackward0 object at 0x000001DF52100F60>
print(l2.data, l2.grad, l2.grad_fn)
# tensor([6., 6., 6., 6., 6.]) tensor([0.6000, 0.6000, 0.6000, 0.6000, 0.6000]) <AddBackward0 object at 0x000001DF52111048>

如果我們?cè)O(shè)置了張量requires_grad,但在某個(gè)訓(xùn)練過(guò)程中不需要記錄梯度grad,可以把代碼塊包裹在with torch.no_grad():中,這樣里面的所有張量都不會(huì)保存grad

x = torch.ones(5, requires_grad=True)
print((x ** 2).requires_grad)   # 輸出True,記錄grad

with torch.no_grad():
    print((x ** 2).requires_grad)   # 輸出False,不記錄

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。 

相關(guān)文章

  • Python實(shí)現(xiàn)識(shí)別文字中的省市區(qū)并繪圖

    Python實(shí)現(xiàn)識(shí)別文字中的省市區(qū)并繪圖

    在做NLP(自然語(yǔ)言處理)相關(guān)任務(wù)時(shí),經(jīng)常會(huì)遇到需要識(shí)別并提取省、城市、行政區(qū)的需求。今天給大家介紹一個(gè)模塊,你只需要把字符串傳遞給這個(gè)模塊,他就能給你返回這個(gè)字符串內(nèi)的省、市、區(qū)關(guān)鍵詞,快來(lái)學(xué)習(xí)一下吧
    2022-06-06
  • Python實(shí)現(xiàn)復(fù)制文件從一個(gè)目錄到另外一個(gè)目錄

    Python實(shí)現(xiàn)復(fù)制文件從一個(gè)目錄到另外一個(gè)目錄

    這篇文章主要為大家詳細(xì)介紹了如何使用Python實(shí)現(xiàn)復(fù)制文件從一個(gè)目錄到另外一個(gè)目錄,文中的示例代碼簡(jiǎn)潔易懂,有需要的小伙伴可以參考一下
    2025-01-01
  • 如何用Python中Tushare包輕松完成股票篩選(詳細(xì)流程操作)

    如何用Python中Tushare包輕松完成股票篩選(詳細(xì)流程操作)

    這篇文章主要介紹了如何用Python中Tushare包輕松完成股票篩選(詳細(xì)流程操作),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • scrapy自定義pipeline類實(shí)現(xiàn)將采集數(shù)據(jù)保存到mongodb的方法

    scrapy自定義pipeline類實(shí)現(xiàn)將采集數(shù)據(jù)保存到mongodb的方法

    這篇文章主要介紹了scrapy自定義pipeline類實(shí)現(xiàn)將采集數(shù)據(jù)保存到mongodb的方法,涉及scrapy采集及操作mongodb數(shù)據(jù)庫(kù)的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-04-04
  • TensorFlow2.0:張量的合并與分割實(shí)例

    TensorFlow2.0:張量的合并與分割實(shí)例

    今天小編就為大家分享一篇TensorFlow2.0:張量的合并與分割實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-01-01
  • python 繪圖模塊matplotlib的使用簡(jiǎn)介

    python 繪圖模塊matplotlib的使用簡(jiǎn)介

    這篇文章主要介紹了python 繪圖模塊matplotlib的使用簡(jiǎn)介,幫助大家更好的理解和學(xué)習(xí)使用python,感興趣的朋友可以了解下
    2021-03-03
  • Python中使用defaultdict和Counter的方法

    Python中使用defaultdict和Counter的方法

    本文深入探討了Python中的兩個(gè)強(qiáng)大工具——defaultdict和Counter,并詳細(xì)介紹了它們的工作原理、應(yīng)用場(chǎng)景以及在實(shí)際編程中的高效使用方法,感興趣的朋友跟隨小編一起看看吧
    2025-01-01
  • 利用Python搶回在螞蟻森林逝去的能量(實(shí)現(xiàn)代碼)

    利用Python搶回在螞蟻森林逝去的能量(實(shí)現(xiàn)代碼)

    螞蟻森林是一項(xiàng)旨在帶動(dòng)公眾低碳減排的公益項(xiàng)目,每個(gè)人的低碳行為在螞蟻森林里可計(jì)為"綠色能量",很多小伙伴都玩過(guò),今天小編給大家分享一篇教程關(guān)于Python搶回在螞蟻森林逝去的能量,感興趣的朋友跟隨小編一起看看吧
    2022-03-03
  • python 破解加密zip文件的密碼

    python 破解加密zip文件的密碼

    這篇文章主要介紹了python 如何破解加密zip文件的密碼,幫助大家更好的理解和學(xué)習(xí)使用python,感興趣的朋友可以了解下
    2021-04-04
  • Python queue模塊的用法

    Python queue模塊的用法

    本文主要介紹了Python queue模塊的用法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06

最新評(píng)論

长兴县| 无为县| 吉隆县| 彰化市| 泽州县| 治县。| 克拉玛依市| 高台县| 浮梁县| 从化市| 五常市| 合肥市| 上思县| 桃江县| 溧水县| 秦安县| 英山县| 冀州市| 栾川县| 郸城县| 苗栗县| 崇文区| 大兴区| 辽阳县| 封开县| 深泽县| 昭平县| 前郭尔| 绥宁县| 曲麻莱县| 东莞市| 瓮安县| 翼城县| 屏南县| 齐河县| 济源市| 女性| 台湾省| 万年县| 田阳县| 靖江市|