Lesson 3.张量的广播和科学运算
- 數(shù)學(xué)運(yùn)算與算子
??作為PyTorch中執(zhí)行深度學(xué)習(xí)的基本數(shù)據(jù)類型,張量(Tensor)也擁有非常多的數(shù)學(xué)運(yùn)算函數(shù)和方法,以及對(duì)應(yīng)的一系列計(jì)算規(guī)則。在PyTorch中,能夠作用與Tensor的運(yùn)算,被統(tǒng)一稱作為算子。并且相比于NumPy,PyTorch給出了更加規(guī)范的算子(運(yùn)算)的分類,從而方便用戶在不同場(chǎng)景下調(diào)用不同類型的算子(運(yùn)算)。
- 數(shù)學(xué)運(yùn)算的分類
PyToch總共為Tensor設(shè)計(jì)了六大類數(shù)學(xué)運(yùn)算,分別是:- 1.逐點(diǎn)運(yùn)算(Pointwise Ops):指的是針對(duì)Tensor中每個(gè)元素執(zhí)行的相同運(yùn)算操作;
- 2.規(guī)約運(yùn)算(Reduction Ops):指的是對(duì)于某一張量進(jìn)行操作得出某種總結(jié)值;
- 3.比較運(yùn)算(Comparison Ops):指的是對(duì)多個(gè)張量進(jìn)行比較運(yùn)算的相關(guān)方法;
- 4.譜運(yùn)算(Spectral Ops):指的是涉及信號(hào)處理傅里葉變化的操作;
- 5.BLAS和LAPACK運(yùn)算:指的是基礎(chǔ)線性代數(shù)程序集(Basic Linear Algeria Subprograms)和線性代數(shù)包(Linear Algeria Package)中定義的、主要用于線性代數(shù)科學(xué)計(jì)算的函數(shù)和方法;
- 6.其他運(yùn)算(Other Ops):其他未被歸類的數(shù)學(xué)運(yùn)算。
??由于譜運(yùn)算(Spectral Ops)前期不會(huì)涉及,而要理解傅里葉變換本身需要更多額外的數(shù)學(xué)基礎(chǔ),而很多其他運(yùn)算,我們?cè)谇懊娼榻B張量的基本方法時(shí)已經(jīng)介紹,因此接下來將主要圍繞逐點(diǎn)運(yùn)算、規(guī)約運(yùn)算、比較運(yùn)算和線性代數(shù)運(yùn)算四塊進(jìn)行講解,而線性代數(shù)部分由于涉及到大量的數(shù)學(xué)內(nèi)容,因此將放在Lesson 4中單獨(dú)進(jìn)行講解。
import torch import numpy as np關(guān)于數(shù)學(xué)運(yùn)算的另一種分類方法,是根據(jù)運(yùn)算使用場(chǎng)景進(jìn)行分類,如基礎(chǔ)數(shù)學(xué)運(yùn)算、數(shù)理統(tǒng)計(jì)運(yùn)算等。由于PyTorch官網(wǎng)是按照六類算子進(jìn)行的分類,因此本節(jié)將結(jié)合兩種分類方法進(jìn)行講解。
一、張量的廣播(Broadcast)特性
??在具體介紹張量的運(yùn)算操作之前,我們先要了解張量的運(yùn)算規(guī)則,其中最重要的一點(diǎn),就是張量具備和NumPy相同的廣播特性,也就是允許不同形狀的張量之間進(jìn)行計(jì)算。
1.相同形狀的張量計(jì)算
??根據(jù)官網(wǎng)說法,“same shapes are always broadcastable”,相同形狀數(shù)組總是可以進(jìn)行廣播計(jì)算。這里簡(jiǎn)單強(qiáng)調(diào)一下,雖然我們往往覺得不同形狀之間的張量計(jì)算才是應(yīng)用到廣播特性,但其實(shí)相同形狀的張量計(jì)算,盡管是對(duì)應(yīng)位置元素進(jìn)行計(jì)算,但本質(zhì)上也是應(yīng)用到了廣播特性。
t1 = torch.arange(3) t1 #tensor([0, 1, 2])t1 + t1 # 對(duì)應(yīng)位置元素依次相加 #tensor([0, 2, 4])思考:如果是兩個(gè)list相加,是什么結(jié)果?
2.不同形狀的張量計(jì)算
??廣播的特性是在不同形狀的張量進(jìn)行計(jì)算時(shí),一個(gè)或多個(gè)張量通過隱式轉(zhuǎn)化,轉(zhuǎn)化成相同形狀的兩個(gè)張量,從而完成計(jì)算的特性。但并非任何兩個(gè)不同形狀的張量都可以通過廣播特性進(jìn)行計(jì)算,因此,我們需要了解廣播的基本規(guī)則及其核心依據(jù)。
2.1 標(biāo)量和任意形狀的張量
??標(biāo)量可以和任意形狀的張量進(jìn)行計(jì)算,計(jì)算過程就是標(biāo)量和張量的每一個(gè)元素進(jìn)行計(jì)算。
t1 + 1 # 1是標(biāo)量,可以看成是零維 #tensor([1, 2, 3])# 二維加零維 t1 + torch.tensor(1) #tensor([1, 2, 3])t2 = torch.zeros((3, 4)) t2 #tensor([[0., 0., 0., 0.], # [0., 0., 0., 0.], # [0., 0., 0., 0.]])t2 + 1 #tensor([[1., 1., 1., 1.], # [1., 1., 1., 1.], # [1., 1., 1., 1.]])2.2 相同維度、不同形狀的張量之間計(jì)算
??對(duì)于不同形狀的張量計(jì)算,我們首先需要回顧張量的形狀屬性,并深化對(duì)其的理解。
??首先,我們都知道,張量的形狀可以用.shape屬性查看
t2.shape #torch.Size([3, 4])? ? ? ?對(duì)于返回結(jié)果,我們可以看成是一個(gè)序列,代表著張量各維度的信息。當(dāng)然,對(duì)于二維張量,由于我們可以將其視作一個(gè)矩陣,因此我們可以說t2是一個(gè)擁有三行四列的二維張量,但這種理解方式對(duì)于更高維度張量就存在一定的局限,因此我們需要樹立另外一種理解方法,那就是:t2是由3個(gè)一維張量組成,并且該一維張量、每個(gè)都包含四個(gè)元素。類似的,我們可以創(chuàng)建更高維度張量并對(duì)其形狀進(jìn)行解釋。
t3 = torch.zeros(3, 4, 5) t3 #tensor([[[0., 0., 0., 0., 0.], # [0., 0., 0., 0., 0.], # [0., 0., 0., 0., 0.], # [0., 0., 0., 0., 0.]], # # [[0., 0., 0., 0., 0.], # [0., 0., 0., 0., 0.], # [0., 0., 0., 0., 0.], # [0., 0., 0., 0., 0.]], # # [[0., 0., 0., 0., 0.], # [0., 0., 0., 0., 0.], # [0., 0., 0., 0., 0.], # [0., 0., 0., 0., 0.]]])t3.shape #torch.Size([3, 4, 5])我們可以將t3解釋為:t3是3個(gè)二維張量組成了三維張量,并且這些每個(gè)二維張量,都是由四個(gè)包含五個(gè)元素的一維張量所組成。由二維拓展至三維,即可拓展至N維。
接下來,我們以t2為例,來探討相同維度、不同形狀的張量之間的廣播規(guī)則。
t2 #tensor([[0., 0., 0., 0.], # [0., 0., 0., 0.], # [0., 0., 0., 0.]])t2.shape #torch.Size([3, 4])t21 = torch.ones(1, 4) t21 #tensor([[1., 1., 1., 1.]])t21的形狀是(1, 4),和t2的形狀(3, 4)在第一個(gè)分量上取值不同,但該分量上t21取值為1,因此可以廣播,也就可以進(jìn)行計(jì)算
t21 + t2 #tensor([[1., 1., 1., 1.], # [1., 1., 1., 1.], # [1., 1., 1., 1.]])而t21和t2的實(shí)際計(jì)算過程如下:
注意理解:此處的廣播相當(dāng)于將t21的形狀(1, 4)拓展成了t2的(3, 4),也就是復(fù)制了第一行三次,然后二者進(jìn)行相加。當(dāng)然,也可以理解成t21的第一行和t2的三行分別進(jìn)行了相加。?
t22 = torch.ones(3, 1) t22 #tensor([[1.], # [1.], # [1.]])t2 #tensor([[0., 0., 0., 0.], # [0., 0., 0., 0.], # [0., 0., 0., 0.]])t2.shape #torch.Size([3, 4])t22 + t2 # 形狀為(3,1)的張量和形狀為(3,4)的張量相加,可以廣播 #tensor([[1., 1., 1., 1.], # [1., 1., 1., 1.], # [1., 1., 1., 1.]])t2和t22實(shí)際計(jì)算過程如下:?
t23 = torch.ones(2, 4) t23.shape #torch.Size([2, 4])t2.shape #torch.Size([3, 4])'''注:此時(shí)t2和t23的形狀第一個(gè)分量維度不同,但二者取值均不為1,因此無法廣播''' t2 + t23 --------------------------------------------------------------------------- #RuntimeError Traceback (most recent call last) #<ipython-input-21-994547ec6516> in <module> #----> 1 t2 + t23 # #RuntimeError: The size of tensor a (3) must match the size of tensor b (2) at non-#singleton dimension 0 t24 = torch.arange(3).reshape(3, 1) t24 #tensor([[0], # [1], # [2]])t25 = torch.arange(3).reshape(1, 3) t25 #tensor([[0, 1, 2]])'''此時(shí),t24的形狀是(3, 1),而t25的形狀是(1, 3),二者的形狀在兩個(gè)份量上均不相同,但都有存在1的情況,因此也是可以廣播的''' t24 + t25 #tensor([[0, 1, 2], # [1, 2, 3], # [2, 3, 4]])二者計(jì)算過程如下:
?三維張量的廣播
t3 = torch.zeros(3, 4, 5) t3 #tensor([[[0., 0., 0., 0., 0.], # [0., 0., 0., 0., 0.], # [0., 0., 0., 0., 0.], # [0., 0., 0., 0., 0.]], # # [[0., 0., 0., 0., 0.], # [0., 0., 0., 0., 0.], # [0., 0., 0., 0., 0.], # [0., 0., 0., 0., 0.]], # # [[0., 0., 0., 0., 0.], # [0., 0., 0., 0., 0.], # [0., 0., 0., 0., 0.], # [0., 0., 0., 0., 0.]]])t31 = torch.ones(3, 4, 1) t31 #tensor([[[1.], # [1.], # [1.], # [1.]], # # [[1.], # [1.], # [1.], # [1.]], # # [[1.], # [1.], # [1.], # [1.]]])t3 + t31 #tensor([[[1., 1., 1., 1., 1.], # [1., 1., 1., 1., 1.], # [1., 1., 1., 1., 1.], # [1., 1., 1., 1., 1.]], # # [[1., 1., 1., 1., 1.], # [1., 1., 1., 1., 1.], # [1., 1., 1., 1., 1.], # [1., 1., 1., 1., 1.]], # # [[1., 1., 1., 1., 1.], # [1., 1., 1., 1., 1.], # [1., 1., 1., 1., 1.], # [1., 1., 1., 1., 1.]]])t32 = torch.ones(3, 1, 5) t32 #tensor([[[1., 1., 1., 1., 1.]], # # [[1., 1., 1., 1., 1.]], # # [[1., 1., 1., 1., 1.]]])t32 + t3 #tensor([[[1., 1., 1., 1., 1.], # [1., 1., 1., 1., 1.], # [1., 1., 1., 1., 1.], # [1., 1., 1., 1., 1.]], # # [[1., 1., 1., 1., 1.], # [1., 1., 1., 1., 1.], # [1., 1., 1., 1., 1.], # [1., 1., 1., 1., 1.]], # # [[1., 1., 1., 1., 1.], # [1., 1., 1., 1., 1.], # [1., 1., 1., 1., 1.], # [1., 1., 1., 1., 1.]]])兩個(gè)張量的形狀上有兩個(gè)分量不同時(shí),只要不同的分量仍然有一個(gè)取值為1,則仍然可以廣播?
t3.shape #torch.Size([3, 4, 5])t33 = torch.ones(1, 1, 5) t33 #tensor([[[1., 1., 1., 1., 1.]]])t3 + t33 #tensor([[[1., 1., 1., 1., 1.], # [1., 1., 1., 1., 1.], # [1., 1., 1., 1., 1.], # [1., 1., 1., 1., 1.]], # # [[1., 1., 1., 1., 1.], # [1., 1., 1., 1., 1.], # [1., 1., 1., 1., 1.], # [1., 1., 1., 1., 1.]], # # [[1., 1., 1., 1., 1.], # [1., 1., 1., 1., 1.], # [1., 1., 1., 1., 1.], # [1., 1., 1., 1., 1.]]])?t3和t33計(jì)算過程如下
注:此處標(biāo)注的兩次廣播,我們也可認(rèn)為上述全部過程的實(shí)現(xiàn)是一次“大的”廣播。同時(shí),此處最開始的t33也就相當(dāng)于一個(gè)一維的、包含五個(gè)元素的張量,因此上述過程也可視為一個(gè)一維張量和一個(gè)三維張量計(jì)算時(shí)的廣播過程。
2.3 不同維度的張量計(jì)算過程中廣播
??在理解相同維度、不同形狀的張量廣播之后,對(duì)于不同維度的張量之間的廣播其實(shí)就會(huì)容易很多,因?yàn)閷?duì)于不同維度的張量,我們首先可以將低維的張量升維,然后依據(jù)相同維度不同形狀的張量廣播規(guī)則進(jìn)行廣播。而低維向量的升維也非常簡(jiǎn)單,只需將更高維度方向的形狀填充為1即可,例如:
# 二維張量轉(zhuǎn)化為三維張量 t2 = torch.arange(4).reshape(2, 2) t2 #tensor([[0, 1], # [2, 3]])# 轉(zhuǎn)化為三維張量 t2.reshape(1, 2, 2) #tensor([[[0, 1], # [2, 3]]]) '''轉(zhuǎn)化之后表示只包含一個(gè)二維張量的三維張量,且二維張量就是t2'''# 轉(zhuǎn)化為四維張量 t2.reshape(1, 1, 2, 2) #tensor([[[[0, 1], # [2, 3]]]]) '''轉(zhuǎn)化之后表示只包含一個(gè)三維張量的四維張量,且三維張量只包含一個(gè)二維張量,且二維張量就是t2'''t3 = torch.zeros(3, 2, 2) '''t3和t2的計(jì)算過程,就相當(dāng)于形狀為(1,2,2)和(3,2,2)的兩個(gè)張量進(jìn)行計(jì)算'''t3 + t2 #tensor([[[0., 1.], # [2., 3.]], # # [[0., 1.], # [2., 3.]], # # [[0., 1.], # [2., 3.]]])t3 + t2.reshape(1, 2, 2) #tensor([[[0., 1.], # [2., 3.]], # # [[0., 1.], # [2., 3.]], # # [[0., 1.], # [2., 3.]]])思考:形狀為(2,1)的張量和形狀為(3,2,3)的張量可以進(jìn)行廣播計(jì)算么?計(jì)算過程是怎樣的?
二、逐點(diǎn)運(yùn)算(Pointwise Ops)
??PyTorch中逐點(diǎn)運(yùn)算大部分都是可以針對(duì)Tensor中每個(gè)元素都進(jìn)行的數(shù)學(xué)科學(xué)運(yùn)算,并且都是較為通用的數(shù)學(xué)科學(xué)運(yùn)算,和NumPy中針對(duì)Array的科學(xué)運(yùn)算類似。在PyTorch中文文檔中有全部運(yùn)算符的相關(guān)介紹,此處僅針對(duì)常用計(jì)算函數(shù)進(jìn)行介紹。
??逐點(diǎn)運(yùn)算主要包括數(shù)學(xué)基本運(yùn)算、數(shù)值調(diào)整運(yùn)算和數(shù)據(jù)科學(xué)運(yùn)算三塊,相關(guān)函數(shù)如下:
Tensor基本數(shù)學(xué)運(yùn)算
t1 = torch.tensor([1, 2]) t1 #tensor([1, 2])t2 = torch.tensor([3, 4]) t2 #tensor([3, 4])torch.add(t1, t2) #tensor([4, 6])t1 + t2 #tensor([4, 6])t1 / t2 #tensor([0.3333, 0.5000])Tensor數(shù)值調(diào)整函數(shù)
t = torch.randn(5) t #tensor([ 1.1971, 1.7523, 1.5678, -2.2227, -0.3082])torch.round(t) #tensor([ 1., 2., 2., -2., -0.])torch.abs(t) #tensor([1.1971, 1.7523, 1.5678, 2.2227, 0.3082])torch.neg(t) #tensor([-1.1971, -1.7523, -1.5678, 2.2227, 0.3082])'''注:雖然此類型函數(shù)是數(shù)值調(diào)整函數(shù),但并不會(huì)對(duì)原對(duì)象進(jìn)行調(diào)整,而是輸出新的結(jié)果。''' t # t本身并未發(fā)生變化 #tensor([ 1.1971, 1.7523, 1.5678, -2.2227, -0.3082])而若要對(duì)原對(duì)象本身進(jìn)行修改,則可考慮使用方法_()的表達(dá)形式,對(duì)對(duì)象本身進(jìn)行修改。此時(shí)方法就是上述同名函數(shù)。
t.abs_() #tensor([1.1971, 1.7523, 1.5678, 2.2227, 0.3082])t #tensor([1.1971, 1.7523, 1.5678, 2.2227, 0.3082])t.neg_() #tensor([-1.1971, -1.7523, -1.5678, -2.2227, -0.3082])t #tensor([-1.1971, -1.7523, -1.5678, -2.2227, -0.3082])'''除了上述數(shù)值調(diào)整函數(shù)有對(duì)應(yīng)的同名方法外,本節(jié)介紹的許多科學(xué)計(jì)算都有同名方法。''' t.exp_() #tensor([0.3021, 0.1734, 0.2085, 0.1083, 0.7348])t #tensor([0.3021, 0.1734, 0.2085, 0.1083, 0.7348])Tensor常用科學(xué)計(jì)算
- tensor的大多數(shù)科學(xué)計(jì)算只能作用于tensor對(duì)象
理解:相比于Python原生數(shù)據(jù)類型,張量是一類更加特殊的對(duì)象,例如張量可以指定運(yùn)行在CPU或者GPU上,因此很多張量的科學(xué)計(jì)算函數(shù)都不允許張量和Python原生的數(shù)值型對(duì)象混合使用。
- tensor的大多數(shù)科學(xué)運(yùn)算具有一定的靜態(tài)性
??所謂靜態(tài)性,指的是對(duì)輸入的張量類型有明確的要求,例如部分函數(shù)只能輸入浮點(diǎn)型張量,而不能輸入整型張量。
t = torch.arange(1, 4) t.dtype #torch.int64torch.exp(t) #tensor([ 2.7183, 7.3891, 20.0855])需要注意的是,雖然Python是動(dòng)態(tài)編譯的編程語言,但在PyTorch中,由于會(huì)涉及GPU計(jì)算,因此很多時(shí)候元素類型不會(huì)在實(shí)際執(zhí)行函數(shù)計(jì)算時(shí)進(jìn)行調(diào)整。此處的科學(xué)運(yùn)算大多數(shù)都要求對(duì)象類型是浮點(diǎn)型,我們需要提前進(jìn)行類型轉(zhuǎn)化。
t1 = t.float() t1 #tensor([1., 2., 3.])torch.exp(t1) #tensor([ 2.7183, 7.3891, 20.0855])torch.expm1(t1) #tensor([ 1.7183, 6.3891, 19.0855])注,此處返回結(jié)果是𝑒^𝑡?1,在數(shù)值科學(xué)計(jì)算中,expm1函數(shù)和log1p函數(shù)是一對(duì)對(duì)應(yīng)的函數(shù)關(guān)系,后面再介紹log1p的時(shí)候會(huì)講解這對(duì)函數(shù)的實(shí)際作用。
torch.exp2(t1) #tensor([2., 4., 8.])torch.pow(t, 2) #tensor([1, 4, 9]) '''注意區(qū)分2的t次方和t的2次方'''torch.square(t) #tensor([1, 4, 9])torch.sqrt(t1) #tensor([1.0000, 1.4142, 1.7321])torch.pow(t1, 0.5) #tensor([1.0000, 1.4142, 1.7321]) '''開根號(hào)也就相當(dāng)于0.5次冪'''torch.log10(t1) #tensor([0.0000, 0.3010, 0.4771])torch.log(t1) #tensor([0.0000, 0.6931, 1.0986])torch.log2(t1) #tensor([0.0000, 1.0000, 1.5850])同時(shí),我們也可簡(jiǎn)單回顧冪運(yùn)算和對(duì)數(shù)運(yùn)算之間的關(guān)系
torch.exp(torch.log(t1)) #tensor([1., 2., 3.])torch.exp2(torch.log2(t1)) #tensor([1., 2., 3.])a = torch.tensor(-1).float() a #tensor(-1.)torch.exp2(torch.log2(a)) #tensor(nan)- 排序運(yùn)算:sort
??在PyTorch中,sort排序函數(shù)將同時(shí)返回排序結(jié)果和對(duì)應(yīng)的索引值的排列。
t = torch.tensor([1.0, 3.0, 2.0]) t #tensor([1., 3., 2.])# 升序排列 torch.sort(t) #torch.return_types.sort( #values=tensor([1., 2., 3.]), #indices=tensor([0, 2, 1]))# 降序排列 torch.sort(t, descending=True) #torch.return_types.sort( #values=tensor([3., 2., 1.]), #indices=tensor([1, 2, 0]))三、規(guī)約運(yùn)算
??規(guī)約運(yùn)算指的是針對(duì)某張量進(jìn)行某種總結(jié),最后得出一個(gè)具體總結(jié)值的函數(shù)。此類函數(shù)主要包含了數(shù)據(jù)科學(xué)領(lǐng)域內(nèi)的諸多統(tǒng)計(jì)分析函數(shù),如均值、極值、方差、中位數(shù)函數(shù)等等。
Tensor統(tǒng)計(jì)分析函數(shù)
# 生成浮點(diǎn)型張量 t = torch.arange(10).float() t #tensor([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])# 計(jì)算均值 torch.mean(t) #tensor(4.5000)# 計(jì)算標(biāo)準(zhǔn)差、均值 torch.std_mean(t) #(tensor(3.0277), tensor(4.5000))# 計(jì)算最大值 torch.max(t) #tensor(9.)# 返回最大值的索引 torch.argmax(t) #tensor(9)# 計(jì)算中位數(shù) torch.median(t) #tensor(4.)# 求和 torch.sum(t) #tensor(45.)# 求積 torch.prod(t) #tensor(0.)torch.prod(torch.tensor([1, 2, 3])) #tensor(6)torch.topk(t, 2)
- dist計(jì)算距離
??dist函數(shù)可計(jì)算閔式距離(閔可夫斯基距離),通過輸入不同的p值,可以計(jì)算多種類型的距離,如歐式距離、街道距離等。閔可夫斯基距離公式如下:
p取值為2時(shí),計(jì)算歐式距離
t1 = torch.tensor([1.0, 2]) t1 #tensor([1., 2.])t2 = torch.tensor([3.0, 4]) t2 #tensor([3., 4.])t #tensor([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])torch.dist(t1, t2, 2) #tensor(2.8284)torch.sqrt(torch.tensor(8.0)) #tensor(2.8284)'''p取值為1時(shí),計(jì)算街道距離''' torch.dist(t1, t2, 1) #tensor(4.)- 規(guī)約運(yùn)算的維度
??由于規(guī)約運(yùn)算是一個(gè)序列返回一個(gè)結(jié)果,因此若是針對(duì)高維張量,則可指定某維度進(jìn)行計(jì)算。
# 創(chuàng)建一個(gè)3*3的二維張量 t2 = torch.arange(12).float().reshape(3, 4) t2 #tensor([[ 0., 1., 2., 3.], # [ 4., 5., 6., 7.], # [ 8., 9., 10., 11.]])t2.shape #torch.Size([3, 4])# 按照第一個(gè)維度求和(每次計(jì)算三個(gè))、按列求和 torch.sum(t2, dim = 0) #tensor([12., 15., 18., 21.])# 按照第二個(gè)維度求和(每次計(jì)算四個(gè))、按行求和 torch.sum(t2, dim = 1) #tensor([ 6., 22., 38.])# 創(chuàng)建一個(gè)2*3*4的三維張量 t3 = torch.arange(24).float().reshape(2, 3, 4) t3 #tensor([[[ 0., 1., 2., 3.], # [ 4., 5., 6., 7.], # [ 8., 9., 10., 11.]], # # [[12., 13., 14., 15.], # [16., 17., 18., 19.], # [20., 21., 22., 23.]]])t3.shape #torch.Size([2, 3, 4])torch.sum(t3, dim = 0) #tensor([[12., 14., 16., 18.], # [20., 22., 24., 26.], # [28., 30., 32., 34.]]) #. 0+12 1+13...torch.sum(t3, dim = 1) #tensor([[12., 15., 18., 21.], # [48., 51., 54., 57.]])torch.sum(t3, dim = 2) #tensor([[ 6., 22., 38.], # [54., 70., 86.]])理解:dim參數(shù)和shape返回結(jié)果一一對(duì)應(yīng)。
- 二維張量的排序
和上述過程類似,在進(jìn)行排序過程中,二維張量也可以按行或者按列進(jìn)行排序
t22 = torch.randn(3, 4) # 創(chuàng)建二維隨機(jī)數(shù)張量 t22 #tensor([[-0.7781, -2.3530, 1.6711, -0.2056], # [-0.2429, 0.6134, 0.8724, 0.5893], # [ 1.2448, 0.3643, -0.2511, 1.4750]])# 默認(rèn)情況下,是按照行進(jìn)行升序排序 torch.sort(t22) #torch.return_types.sort( #values=tensor([[-2.3530, -0.7781, -0.2056, 1.6711], # [-0.2429, 0.5893, 0.6134, 0.8724], # [-0.2511, 0.3643, 1.2448, 1.4750]]), #indices=tensor([[1, 0, 3, 2], # [0, 3, 1, 2], # [2, 1, 0, 3]]))# 修改dim和descending參數(shù),使得按列進(jìn)行降序排序 torch.sort(t22, dim = 0, descending=True) #torch.return_types.sort( #values=tensor([[ 1.2448, 0.6134, 1.6711, 1.4750], # [-0.2429, 0.3643, 0.8724, 0.5893], # [-0.7781, -2.3530, -0.2511, -0.2056]]), #indices=tensor([[2, 1, 0, 2], # [1, 2, 1, 1], # [0, 0, 2, 0]]))四、比較運(yùn)算
??比較運(yùn)算是一類較為簡(jiǎn)單的運(yùn)算類型,和Python原生的布爾運(yùn)算類似,常用于不同張量之間的邏輯運(yùn)算,最終返回邏輯運(yùn)算結(jié)果(邏輯類型張量)。基本比較運(yùn)算函數(shù)如下所示:
Tensor比較運(yùn)算函數(shù)
t1 = torch.tensor([1.0, 3, 4]) t2 = torch.tensor([1.0, 2, 5])t1 == t2 #tensor([ True, False, False])torch.equal(t1, t2) # 判斷t1、t2是否是相同的張量 #Falsetorch.eq(t1, t2) #tensor([ True, False, False])t1 > t2 #tensor([False, True, False])t1 >= t2 #tensor([ True, True, False])總結(jié)
以上是生活随笔為你收集整理的Lesson 3.张量的广播和科学运算的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LESSON 9.1 随机森林回归器的实
- 下一篇: Lesson 4.张量的线性代数运算