在深度學習中,軸,指的就是張量的層級,一般通過引數axis/dim來設定。很多張量的運算、神經網路的構建,都會涉及到軸,但到底取哪個軸,卻不是那麼容易把握。
下面會針對軸/axis/dim,基於 pytorch 的**和例項,嘗試去理清張量運算中軸/axis/dim的設定。
軸的概念
對於乙個張量,它的shape有幾維,就對應有幾個軸,也就對應著張量的層級,最直觀的可以通過看最前面的方括號數量來判斷。
import torch
a = torch.tensor([[
1,2,
3],[
4,5,
6]])
b = torch.tensor([[
7,8,
9],[
10,11,
12]])
c = torch.tensor([[
[1,2
,3],
[4,5
,6]]
,[[7
,8,9
],[10
,11,12
]]])
print
(a.shape)
# torch.size([2, 3])
上面的張量 a 和 b,都對應兩個軸。axis/dim=0 對應 shape [2, 3] 中的2,axis/dim=1 對應 shape [2, 3] 中的3,而張量 c 有三個軸。
張量運算時對軸引數的設定非常常見,在 numpy 中一般是引數axis,在 pytorch 中一般是引數dim,但它們含義是一樣的。
軸的使用
在做張量的拼接操作時,axis/dim設定了哪個軸,那對應的軸在拼接之後張量數會發生變化
>> torch.cat(
(a,b)
, dim=0)
tensor([[
1.,2
.,3.
],[4
.,5.
,6.]
,[7.
,8.,
9.],
[10.,
11.,12
.]])
>> torch.cat(
(a,b)
, dim=1)
tensor([[
1.,2
.,3.
,7.,
8.,9
.],[
4.,5
.,6.
,10.,
11.,12
.]])
對於上面torch中的cat操作,當設定dim=0時,兩個維度是(2,3)的張量合併成了乙個(4,3)的張量,在第0維,張量數從2變成了4,第1維沒有變化;當設定dim=1時,在第1維,張量數從3變成了6,第0維沒有變化。
在做張量的運算操作時,axis/dim設定了哪個軸,就會遍歷這個軸去做運算,其他軸順序不變
>> torch.softmax(a, dim=0)
tensor([[
0.0474
,0.0474
,0.0474],
[0.9526
,0.9526
,0.9526]]
)>> torch.softmax(a, dim=1)
tensor([[
0.0900
,0.2447
,0.6652],
[0.0900
,0.2447
,0.6652]]
)
對於上面torch中的 softmax 操作,當設定 dim=0 時,就是其他軸不變,單次遍歷 dim=0 軸的所有元素去做運算,上例中就相當於分別取了張量a中的第0列、第1列、第2列去做計算。
換乙個角度,假設用for迴圈去遍歷乙個張量,那運算中設定的dim就是被放在最內層的for迴圈,其它的軸保持正常的順序。
可以用下面的例子作為驗證,這裡tensor c 的shape 是 (m,n,p),用for迴圈去計算 torch.softmax(c, dim=1)
# for迴圈計算方式
c = torch.tensor([[
[1,2
,3],
[4,5
,6]]
,[[7
,8,9
],[10
,11,12
]]])
# shape (2,2,3)
m,n,p = c.shape
res = torch.zeros(
(m,n,p)
)for i in
range
(m):
for j in
range
(p):
res[i,
:,j]
= torch.softmax(torch.tensor(
[c[i,k,j]
for k in
range
(n)]
), dim=0)
#這裡對應最內層的for迴圈
# 庫函式設定軸計算方式
res1 = torch.softmax(c, dim=1)
print
(res.equal(res1)
)# true
axis/dim使用小總結:
在做張量的拼接操作時,axis/dim設定了哪個軸,那對應的軸在拼接之後張量數會發生變化在做張量的運算操作時,axis/dim設定了哪個軸,就會遍歷這個軸去做運算,其他軸順序不變
實際上,第一條拼接操作也可以用第二條去理解,但拼接的軸張量數會發生變化更好理解和記憶。
軸的例項
其實乙個軸設定的變化,會帶來很大的差異,最典型的就是 batchnorm 和 layernorm 了。
batchnorm 和 layernorm 是針對資料的不同軸去做norm,假設輸入資料的維度是(n,c,h,w),分別對應batch數,核數,高,寬,batchnorm 就對應dim=0,layernorm 就對應dim=1,在不考慮移動平均等具體細節問題時,兩者在形式上可以統一,只有乙個dim引數的差別。
pytorch 的實現(簡化版)如下:
class
norm
(nn.module)
:def
__init__
(self, num_features, variance_epsilon=1e-
12):super
(norm, self)
.__init__(
) self.gamma = nn.parameter(torch.ones(num_features)
) self.beta = nn.parameter(torch.zeros(num_features)
) self.variance_epsilon = variance_epsilon # 乙個很小的常數,防止除0
defforward
(self, x, dim)
: u = x.mean(dim, keepdim=
true
) s =
(x - u)
.pow(2
).mean(dim, keepdim=
true
) x_norm =
(x - u)
/ torch.sqrt(s + self.variance_epsilon)
return self.gamma * x_norm + self.beta
當然,不僅僅是在深度學習裡面,在 numpy,pandas中,軸的設定都經常會遇到,但它們都是相通的,希望本文能幫你更好的理解它 —> 軸。 機器學習8 深度學習 全連線
深度模型最直觀的解釋就是多層網路,最簡單的深度模型是全連線。深度網路的每個全連線層其實質就是乙個邏輯回歸模型,每層包括線性函式與啟用函式。如圖所示 通過多層組合,可以得到如下的解析模型 對於模型中的隱藏層,其實質工作就是feature extraction,因此,隱藏層出現了卷積 小波等。以影象為例...
NGUI中深度depth和z軸關係
gui中是用depth來控制sprite顯示順序的,本來這很好用,但碰到上面帖子中的問題時卻不好解決了,於是我試驗了下。以下是一些總結,不對的地方請指正。下面的內容可能看起來比較繞,這樣的話只需實際試驗下就能很容易的知道結果,呵呵 如果還是看不明白,可以先看,那裡有個總結 1,同乙個panel下,同...
深度學習筆記6 全連線層的實現
全連線層的每乙個結點都與上一層的所有結點相連,用來把前邊提取到的特徵綜合起來。由於其全相連的特性,一般全連線層的引數也是最多的。下圖中連線最密集的2個地方就是全連線層,這很明顯的可以看出全連線層的引數的確很多。在前向計算過程,也就是乙個線性的加權求和的過程,全連線層的每乙個輸出都可以看成前一層的每乙...