5分鐘玩轉(zhuǎn)PyTorch |為什么線代在人工智能中被廣泛應用?
AI因你而升溫,記得加星標哦!
↑?關(guān)注 + 星標?,每天學Python新技能
后臺回復【大禮包】送你Python自學大禮包
在機器學習建模過程中,經(jīng)常會使用矩陣運算以提升效率,在深度學習中,往往會涉及矩陣的集合運算,就是三維或四維數(shù)據(jù)的計算。
它們的基礎(chǔ)就是線性代數(shù)理論,而線代的核心是矩陣,矩陣的本質(zhì)其實是線性方程,就是一個個基礎(chǔ)神經(jīng)元,所以被廣泛應用,是不是很神奇?本文首先介紹矩陣的構(gòu)造,然后詳解矩陣的運算與本質(zhì)意義。
一、矩陣形變的構(gòu)造
矩陣的形變與構(gòu)造的方法與二維張量的方法相同。
#?創(chuàng)建一個2*3的矩陣
t1?=?torch.arange(6).reshape(2,?3).float()
t1
#?tensor([[0.,?1.,?2.],
#?????????[3.,?4.,?5.]])
1.1 t:轉(zhuǎn)置
torch.t(t1)
#?tensor([[0.,?3.],
#?????????[1.,?4.],
#?????????[2.,?5.]])
矩陣的轉(zhuǎn)置是每個元素行列位置進行互換。
1.2 eye:單位矩陣
torch.eye(3)
#?tensor([[1.,?0.,?0.],
#?????????[0.,?1.,?0.],
#?????????[0.,?0.,?1.]])
1.3 diag:對角矩陣
注意參數(shù)的數(shù)據(jù)類型必須是張量。
t?=?torch.arange(1,?4)
t
#?tensor([1,?2,?3])
torch.diag(t)
#?tensor([[1,?0,?0],
#?????????[0,?2,?0],
#?????????[0,?0,?3]])
對角線向上偏移一位
torch.diag(t,?1)
#?tensor([[0,?1,?0,?0],
#?????????[0,?0,?2,?0],
#?????????[0,?0,?0,?3],
#?????????[0,?0,?0,?0]])
對角線向下偏移一位
torch.diag(t,?-1)
#?tensor([[0,?0,?0,?0],
#?????????[1,?0,?0,?0],
#?????????[0,?2,?0,?0],
#?????????[0,?0,?3,?0]])
1.4 triu:取上三角矩陣
t2?=?torch.arange(1,?10).reshape(3,?3)
t2
#?tensor([[1,?2,?3],
#?????????[4,?5,?6],
#?????????[7,?8,?9]])
取上三角矩陣
torch.triu(t2)
#?tensor([[1,?2,?3],
#?????????[0,?5,?6],
#?????????[0,?0,?9]])
上三角矩陣向左下偏移一位
torch.triu(t2,?-1)
#?tensor([[1,?2,?3],
#?????????[4,?5,?6],
#?????????[0,?8,?9]])
1.5 tril:取下三角矩陣
torch.tril(t2)
#?tensor([[1,?0,?0],
#?????????[4,?5,?0],
#?????????[7,?8,?9]])
二、矩陣的基本運算與意義
矩陣的線性代數(shù)含義主要體現(xiàn)在它的基本運算上。
2.1 dot\vdot:點積計算
在PyTorch中,dot和vdot只能用于一維張量。兩種函數(shù)只在進行復數(shù)運算時有區(qū)別。
t?=?torch.arange(1,?4)
t
#?tensor([1,?2,?3])
torch.dot(t,?t)
#?tensor(14)
torch.vdot(t,?t)
#?tensor(14)
2.2 mm:矩陣乘法
t1?=?torch.arange(1,?7).reshape(2,?3)
t1
#?tensor([[1,?2,?3],
#?????????[4,?5,?6]])
t2?=?torch.arange(1,?10).reshape(3,?3)
t2
#?tensor([[1,?2,?3],
#?????????[4,?5,?6],
#?????????[7,?8,?9]])
矩陣對應位置元素相乘,要求兩個矩陣的形狀相同。
t1?*?t1
#?tensor([[?1,??4,??9],
#?????????[16,?25,?36]])
而矩陣乘法兩個矩陣的形狀可以不同。
torch.mm(t1,?t2)
#?tensor([[?30,??36,??42],
#?????????[66,?81,?96]])
計算過程如下所示:
規(guī)律總結(jié)如下:
左邊矩陣的列數(shù)要和右邊矩陣的行數(shù)相等,左邊矩陣每行與右邊矩陣每列對應位置元素相乘后相加 左邊矩陣的行數(shù)決定了結(jié)果矩陣的行數(shù),右邊矩陣的列數(shù)決定了結(jié)果矩陣的列數(shù)
矩陣相乘需要注意:
不滿足交換律:
A?=?torch.tensor([1,?1,?-1,?-1])..reshape(2,?2)
A
#?tensor([[?1,??1],
#?????????[-1,?-1]])
????????
B?=?torch.tensor([1,?-1,?-1,?1]).reshape(2,?2)
B
#?tensor([[?1,?-1],
#?????????[-1,??1]])
torch.mm(A,?B)
#?tensor([[0,?0],
#?????????[0,?0]])
torch.mm(B,?A)
#?tensor([[?2,??2],
#?????????[-2,?-2]])
不滿足消去律:
C?=?torch.tensor([0,?0,?0,?0]).reshape(2,?2)
C
#?tensor([[0,?0],
#?????????[0,?0]])
torch.mm(A,?B)
#?tensor([[0,?0],
#?????????[0,?0]])
????????
torch.mm(A,?C)
#?tensor([[0,?0],
#?????????[0,?0]])
2.3 mv:矩陣與向量相乘
矩陣和向量相乘的過程中,需要矩陣的列數(shù)和向量的元素個數(shù)相同。
m?=?torch.arange(1,?7).reshape(2,?3)
m
#?tensor([[1,?2,?3],
#?????????[4,?5,?6]])
v?=?torch.arange(1,?4)
v
#?tensor([1,?2,?3])
torch.mv(m,?v)
#?tensor([14,?32])
矩陣和向量相乘的過程我們可以看成是先將向量轉(zhuǎn)化為列向量然后再相乘。
#?轉(zhuǎn)化為列向量
v.reshape(3,?1)?????
#?tensor([[1],
#?????????[2],
#?????????[3]])
torch.mm(m,?v.reshape(3,?1))
#?tensor([[14],
#?????????[32]])
????????
torch.mm(m,?v.reshape(3,?1)).flatten()
#?tensor([14,?32])
2.4 矩陣的本質(zhì)是線性方程
mv函數(shù)本質(zhì)上提供了一種二維張量和一維張量相乘的方法,在線性代數(shù)運算過程中,有很多矩陣乘向量的場景,典型的如線性回歸的求解過程。
矩陣的最初目的,只是為線性方程組提供一個簡寫形式。
通常情況下我們需要將行向量(x,y)轉(zhuǎn)化為列向量然后進行計算,但PyTorch中單獨設(shè)置了一個矩陣和向量相乘的方法,從而簡化了將向量轉(zhuǎn)化為列向量的轉(zhuǎn)化過程。
2.5 bmm:批量矩陣相乘
批量矩陣相乘指的是三維張量的矩陣乘法,本質(zhì)是三維張量內(nèi)部各對應位置的矩陣相乘,在深度學習中有非常多的應用場景。
t3?=?torch.arange(1,?13).reshape(3,?2,?2)
t3
#?tensor([[[?1,??2],
#??????????[?3,??4]],
#?????????[[?5,??6],
#??????????[?7,??8]],
#?????????[[?9,?10],
#??????????[11,?12]]])
?????????
t4?=?torch.arange(1,?19).reshape(3,?2,?3)
t4
#?tensor([[[?1,??2,??3],
#??????????[?4,??5,??6]],
#?????????[[?7,??8,??9],
#??????????[10,?11,?12]],
#?????????[[13,?14,?15],
#??????????[16,?17,?18]]])
torch.bmm(t3,?t4)
#?tensor([[[??9,??12,??15],
#??????????[?19,??26,??33]],
#?????????[[?95,?106,?117],
#??????????[129,?144,?159]],
#?????????[[277,?296,?315],
#??????????[335,?358,?381]]])
需要注意:
三維張量包含的矩陣個數(shù)需要相同 每個內(nèi)部矩陣,需要滿足左乘矩陣的列數(shù)要等于右乘矩陣的行數(shù)
2.6 addmm:矩陣相乘后相加
addmm函數(shù)結(jié)構(gòu):
addmm(input, mat1, mat2, beta=1, alpha=1)輸出結(jié)果:
beta * input + alpha * (mat1 * mat2)相當于
y = ax + b中加偏置的過程,就是線性方程或基本的神經(jīng)元
t1
#?tensor([[1,?2,?3],
#?????????[4,?5,?6]])
????????
t2
#?tensor([[1,?2,?3],
#?????????[4,?5,?6],
#?????????[7,?8,?9]])
t?=?torch.arange(3)
t
#?tensor([0,?1,?2]
#?矩陣乘法
torch.mm(t1,?t2)
#?tensor([[30,?36,?42],
#?????????[66,?81,?96]])
#?先乘法后相加
torch.addmm(t,?t1,?t2)
#?tensor([[30,?37,?44],
#?????????[66,?82,?98]])
torch.addmm(t,?t1,?t2,?beta?=?0,?alpha?=?10)
#?tensor([[300,?360,?420],
#?????????[660,?810,?960]])
2.7 addbmm:批量矩陣相乘后相加
不同的是addbmm是批量矩陣相乘,并且在相加的過程中也是矩陣相加,而非向量加矩陣。
t?=?torch.arange(6).reshape(2,?3)
t
#?tensor([[0,?1,?2],
#?????????[3,?4,?5]])
????????
t3
#?tensor([[[?1,??2],
#??????????[?3,??4]],
#?????????[[?5,??6],
#??????????[?7,??8]],
#?????????[[?9,?10],
#??????????[11,?12]]])
?????????
t4
#?tensor([[[?1,??2,??3],
#??????????[?4,??5,??6]],
#?????????[[?7,??8,??9],
#??????????[10,?11,?12]],
#?????????[[13,?14,?15],
#??????????[16,?17,?18]]])
?????????
torch.bmm(t3,?t4)
#?tensor([[[??9,??12,??15],
#??????????[?19,??26,??33]],
#?????????[[?95,?106,?117],
#??????????[129,?144,?159]],
#?????????[[277,?296,?315],
#??????????[335,?358,?381]]])
?????????
torch.addbmm(t,?t3,?t4)
#?tensor([[381,?415,?449],
#?????????[486,?532,?578]])
addbmm會在原來三維張量基礎(chǔ)之上,對其內(nèi)部矩陣進行求和,而不是矩陣和向量相加。
推薦閱讀
