深度學習基礎框架 張量 Tensor
- 張量
- 數據操作
- 導入
- 創建張量
- 獲取張量信息
- 改變張量
- 張量運算
- 張量與內存
張量
Pytorch 是一個深度學習框架,用于開發和訓練神經網絡模型。
而其核心數據結構,則是張量 Tensor,類似于 Numpy 數組,但是可以支持在 GPU 上加速運算,顯著加速模型訓練過程,更適用于深度學習和神經網絡模型的構建和學習。
張量是多維數組的泛化,可以是:
- 標量(零維張量)
- 向量(一維張量)
- 矩陣(二維張量)
- 或更高維度的數組;
- e . g . e.g. e.g. RGB 圖像可以表示為三維張量,其中一個維度表示高度,另一個維度表示寬度,最后一個維度表示顏色通道:
[[[255, 0, 0], [0, 255, 0], [0, 0, 255]],
[[0, 255, 255], [255, 255, 0], [255, 0, 255]]]
此外,后期讀者會接觸到梯度下降與反向傳播,而張量非常重要一點,即可以自動求導,方便計算梯度并更新模型參數。
數據操作
導入
首先,導入 torch,需要注意的是,雖然稱為 Pytorch,但是我們應該導入 torch 而不是 Pytorch;
import torch
創建張量
張量 tensor 表示一個數值組成的數組,
x = torch.arange(12)
print(x)
# >>> 表示結果輸出
>>> tensor([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
通過 zeros
函數與 ones
函數創建全0、全1元素,
torch.zeros((2, 3, 4))>>> 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.]]])
張量同樣支持邏輯運算符構建,
x = torch.tensor([[1, 2, 4, 8], [1, 3, 9, 27]])
y = torch.tensor([[2, 2, 2, 2], [3, 3, 3, 3]])
x == y>>> tensor([[False, True, False, False],[False, True, False, False]])
獲取張量信息
通過 shape
屬性來訪問張量的形狀和張量中元素的總數,
# 張量的形狀
x.shape>>> torch.Size([12])
# 張量中元素的總數
x.numel()>>> 12
對張量中所有元素進行求和會產生一個只有一個元素的張量,
x = torch.tensor([[1, 2, 4, 8], [1, 3, 9, 27]])
x.sum()>>> tensor(55)
通過用切片方法訪問張量內指定位置元素,
x = torch.tensor([[1, 2, 4, 8], [1, 3, 9, 27]])
x[-1], x[1][1:3]>>> (tensor([1, 3, 9, 27]), tensor([3, 9]))
改變張量
通過 reshape
函數改變一個張量的形狀而不改變元素數量和元素值,
x.reshape(3, 4)>>> tensor([[ 0, 1, 2, 3],[ 4, 5, 6, 7],[ 8, 9, 10, 11]])
通過 cat
函數把多個張量連結在一起,支持按指定維度 dim
拼接,
x = torch.tensor([[1, 2, 4, 8], [1, 3, 9, 27]])
y = torch.tensor([[2, 2, 2, 2], [3, 3, 3, 3]])
torch.cat((x, y), dim=0), torch.cat((x, y), dim=1)>>> (tensor([[ 1, 2, 4, 8],[ 1, 3, 9, 27],[ 2, 2, 2, 2],[ 3, 3, 3, 3]]),tensor([[ 1, 2, 4, 8, 2, 2, 2, 2],[ 1, 3, 9, 27, 3, 3, 3, 3]]))
通過指定索引將元素寫入張量,
x = torch.tensor([[1, 2, 4, 8], [1, 3, 9, 27]])
x[1, 2] = 1111>>> tensor([[1, 2, 4, 8],[1, 3, 1111, 27]])
x = torch.tensor([[1, 2, 4, 8], [1, 3, 9, 27]])
x[1, :] = 12>>> tensor([[ 1, 2, 4, 8],[12, 12, 12, 12]])
張量運算
張量支持按元素運算,
x = torch.tensor([1.0, 2, 4, 8])
y = torch.tensor([2, 2, 2, 2])
x + y, x - y, x * y, x / y, x ** y>>> (tensor([ 3., 4., 6., 10.]),tensor([-1., 0., 2., 6.]),tensor([ 2., 4., 8., 16.]),tensor([0.5000, 1.0000, 2.0000, 4.0000]),tensor([ 1., 4., 16., 64.]))
張量加法中,即使形狀不同,我們仍然可以通過調用廣播機制來執行張量加法,
a = torch.arange(3).reshape((3, 1))
b = torch.arange(2).reshape((1, 2))
a + b>>> tensor([[0, 1],[1, 2],[2, 3]])
張量與內存
雖然 Python 中很少涉及到內存處理,但是如果矩陣很大,就需要考慮到內存方面。
在運行一些操作時,可能會導致為新結果分配內存,
before = id(Y)
Y = Y + X
id(Y) == before>>> False # 說明新內存地址不等同于原內存地址
如果我們的矩陣 Y 非常大,為了效率考慮,不更換內存地址,減少操作的內存開銷,怎么做?
before = id(Y)
Y += X
id(Y) == before>>> True # 說明沒有新分配內存空間
Numpy 是 Python 里最基礎的多元數組運算框架,所以也要多關注 Numpy 與 Tensor 之間的轉化。