一.前言
前面我們介紹了一下pytorch還有張量的創建,而本章節我們就來介紹一下張量的計算,類型轉換以及操作,這個是十分重要的,我們的學習目標是:掌握張量基本運算、掌握阿達瑪積、點積運算 掌握PyTorch指定運算設備。
PyTorch 計算的數據都是以張量形式存在, 我們需要掌握張量各種運算. 并且, 我們可以在 CPU 中運算, 也可 以在 GPU 中運算.
二.張量基本運算
基本運算中,包括 add、sub、mul、div、neg 等函數, 以及這些函數的帶下劃線的版本 add、sub、mul、 div、neg_,其中帶下劃線的版本為修改原數據。
import numpy as np
import torchdef test():data = torch.randint(0, 10, [2, 3])print(data)print('-' * 50)# 1. 不修改原數據new_data = data.add(10) # 等價 new_data = data + 10print(new_data)print('-' * 50)# 2. 直接修改原數據# 注意: 帶下劃線的函數為修改原數據本身data.add_(10) # 等價 data += 10print(data)# 3. 其他函數print(data.sub(100))print(data.mul(100))print(data.div(100))print(data.neg())if __name__ == '__main__':test()
結果展示,大家對著結果就能理解每個函數的意思了。?
tensor([[3, 2, 4],
[5, 2, 6]])
--------------------------------------------------
tensor([[13, 12, 14],
[15, 12, 16]])
--------------------------------------------------
tensor([[13, 12, 14],
[15, 12, 16]])
tensor([[-87, -88, -86],
[-85, -88, -84]])
tensor([[1300, 1200, 1400],
[1500, 1200, 1600]])
tensor([[0.1300, 0.1200, 0.1400],
[0.1500, 0.1200, 0.1600]])
tensor([[-13, -12, -14],
[-15, -12, -16]])
三.阿達瑪積?
阿達瑪積指的是矩陣對應位置的元素相乘.
import numpy as np
import torchdef test():data1 = torch.tensor([[1, 2], [3, 4]])data2 = torch.tensor([[5, 6], [7, 8]])# 第?種?式data = torch.mul(data1, data2)print(data)print('-' * 50)# 第?種?式data = data1 * data2print(data)print('-' * 50)if __name__ == '__main__':test()
?結果展示:
tensor([[ 5, 12],
[21, 32]])
--------------------------------------------------
tensor([[ 5, 12],
[21, 32]])
--------------------------------------------------
四.點積運算
點積運算要求第?個矩陣 shape: (n, m),第?個矩陣 shape: (m, p), 兩個矩陣點積運算 shape 為: (n, p)。
1. 運算符 @ ?于進?兩個矩陣的點乘運算
2. torch.mm ?于進?兩個矩陣點乘運算, 要求輸?的矩陣為2維
3. torch.bmm ?于批量進?矩陣點乘運算, 要求輸?的矩陣為3維
4. torch.matmul 對進?點乘運算的兩矩陣形狀沒有限定.
????????1. 對于輸?都是?維的張量相當于 mm 運算.
????????2. 對于輸?都是三維的張量相當于 bmm 運算
????????3. 對數輸?的 shape 不同的張量, 對應的最后?個維度必須符合矩陣運算規則
import numpy as np
import torch# 1. 點積運算
def test01():data1 = torch.tensor([[1, 2], [3, 4], [5, 6]])data2 = torch.tensor([[5, 6], [7, 8]])# 第?種?式data = data1 @ data2print(data)print('-' * 50)# 第?種?式data = torch.mm(data1, data2)print(data)print('-' * 50)# 第三種?式data = torch.matmul(data1, data2)print(data)print('-' * 50)# 2. torch.mm 和 torch.matmull 的區別
def test02():# matmul 可以兩個維度可以不同# 第?個張量: (3, 4, 5)# 第?個張量: (5, 4)# torch.mm 不可以相乘,? matmul 則可以相乘print(torch.matmul(torch.randn(3, 4, 5), torch.randn(5, 4)).shape)print(torch.matmul(torch.randn(5, 4), torch.randn(3, 4, 5)).shape)# 3. torch.mm 函數的?法def test03():# 批量點積運算# 第?個維度為 batch_size# 矩陣的?三維要滿?矩陣乘法規則data1 = torch.randn(3, 4, 5)data2 = torch.randn(3, 5, 8)data = torch.bmm(data1, data2)print(data.shape)if __name__ == '__main__':test01()test02()test03()
?結果展示:
tensor([[19, 22],
[43, 50],
[67, 78]])
--------------------------------------------------
tensor([[19, 22],
[43, 50],
[67, 78]])
--------------------------------------------------
tensor([[19, 22],
[43, 50],
[67, 78]])
--------------------------------------------------
torch.Size([3, 4, 4])
torch.Size([3, 5, 5])
torch.Size([3, 4, 8])
五.指定設備運算
PyTorch 默認會將張量創建在 CPU 控制的內存中, 即: 默認的運算設備為 CPU。我們也可以將張量創建在 GPU 上, 能夠利?對于矩陣計算的優勢加快模型訓練。將張量移動到 GPU 上有兩種?法: ???????
????????1. 使? cuda ?法
????????2. 直接在 GPU 上創建張量
????????3. 使? to ?法指定設備??
import torch# 1. 使? cuda ?法
def test01():data = torch.tensor([10, 20, 30])print('存儲設備:', data.device)# 如果安裝的不是 gpu 版本的 PyTorch# 或電腦本身沒有 NVIDIA 卡的計算環境# 下?代碼可能會報錯data = data.cuda()print('存儲設備:', data.device)# 使? cpu 函數將張量移動到 cpu 上data = data.cpu()print('存儲設備:', data.device)# 輸出結果:# 存儲設備: cpu# 存儲設備: cuda:0# 存儲設備: cpu# 2. 直接將張量創建在 GPU 上
def test02():data = torch.tensor([10, 20, 30], device='cuda:0')print('存儲設備:', data.device)# 使? cpu 函數將張量移動到 cpu 上data = data.cpu()print('存儲設備:', data.device)# 輸出結果:# 存儲設備: cuda:0# 存儲設備: cpu# 3. 使? to ?法
def test03():data = torch.tensor([10, 20, 30])print('存儲設備:', data.device)data = data.to('cuda:0')print('存儲設備:', data.device)# 輸出結果:# 存儲設備: cpu# 存儲設備: cuda:0# 4. 存儲在不同設備的張量不能運算def test04():data1 = torch.tensor([10, 20, 30], device='cuda:0')data2 = torch.tensor([10, 20, 30])print(data1.device, data2.device)# RuntimeError: Expected all tensors to be on the same device,# but found at least two devices, cuda:0 and cpu!data = data1 + data2print(data)if __name__ == '__main__':test03()
六.總結
在本?節中,我們主要學習的主要內容如下:
????????1. 張量基本運算函數 add、sub、mul、div、neg 等函數, add、sub、mul、div、neg_ 等 inplace 函數
????????2. 張量的阿達瑪積運算 mul 和運算符 * 的?法
????????3. 點積運算:
????????????????1. 運算符 @ ?于進?兩個矩陣的點乘運算
????????????????2. torch.mm ?于進?兩個矩陣點乘運算, 要求輸?的矩陣為2維
????????????????3. torch.bmm ?于批量進?矩陣點乘運算, 要求輸?的矩陣為3維
????????????????4. torch.matmul 對進?點乘運算的兩矩陣形狀沒有限定.
????????????????????????1. 對于輸?都是?維的張量相當于 mm 運算.
????????????????????????2. 對于輸?都是三維的張量相當于 bmm 運算
????????????????????????3. 對數輸?的 shape 不同的張量, 對應的最后?個維度必須符合矩陣運算規則
????????4. 將變量移動到 GPU 設備的?法,例如: cuda ?法、直接在 GPU 上創建張量、使? to ?法指定設備?
?
?
?
?