目錄
一、隨機張量的生成
1.1?torch.randn()?函數
1.2 其他隨機函數
1.3 輸出維度測試
二、廣播機制
2.1 廣播機制的規則
2.2 加法的廣播機制
二維張量與一維向量相加
三維張量與二維張量相加
二維張量與標量相加
高維張量與低維張量相加
2.3 乘法的廣播機制
批量矩陣與單個矩陣相乘
批量矩陣與批量矩陣相乘(部分廣播)
三維張量與二維張量相乘(高維廣播)
一、隨機張量的生成
在深度學習中,我們經常需要隨機生成張量,例如用于模型參數的初始化、生成測試數據或模擬輸入特征。PyTorch 提供了多種隨機張量生成函數,其中 torch.randn()
是最常用的一種。
1.1?torch.randn()
?函數
torch.randn()
可以創建一個由標準正態分布(均值為 0,標準差為 1)隨機數填充的張量。它的參數如下:
-
size
:必選參數,表示輸出張量的形狀。 -
dtype
:可選參數,指定張量的數據類型。 -
device
:可選參數,指定張量存儲的設備。 -
requires_grad
:可選參數,是否需要計算梯度。
以下是生成不同維度張量的示例代碼:
import torch# 生成標量(0維張量)
scalar = torch.randn(())
print(f"標量: {scalar}, 形狀: {scalar.shape}")# 生成向量(1維張量)
vector = torch.randn(5) # 長度為5的向量
print(f"向量: {vector}, 形狀: {vector.shape}")# 生成矩陣(2維張量)
matrix = torch.randn(3, 4) # 3行4列的矩陣
print(f"矩陣:{matrix},矩陣形狀: {matrix.shape}")# 生成3維張量(常用于圖像數據的通道、高度、寬度)
tensor_3d = torch.randn(3, 224, 224) # 3通道,高224,寬224
print(f"3維張量形狀: {tensor_3d.shape}")# 生成4維張量(常用于批量圖像數據:[batch, channel, height, width])
tensor_4d = torch.randn(2, 3, 224, 224) # 批量大小為2,3通道,高224,寬224
print(f"4維張量形狀: {tensor_4d.shape}")
1.2 其他隨機函數
除了 torch.randn()
,PyTorch 還提供了其他隨機函數,例如:
-
torch.rand()
:生成在[0, 1)
范圍內均勻分布的隨機數。 -
torch.randint()
:生成指定范圍內的隨機整數。 -
torch.normal()
:生成指定均值和標準差的正態分布隨機數。
以下是示例代碼:
# 生成均勻分布隨機數
x = torch.rand(3, 2) # 生成3x2的張量
print(f"均勻分布隨機數: {x}, 形狀: {x.shape}")# 生成隨機整數
x = torch.randint(low=0, high=10, size=(3,)) # 生成3個0到9之間的整數
print(f"隨機整數: {x}, 形狀: {x.shape}")# 生成正態分布隨機數
mean = torch.tensor([0.0, 0.0])
std = torch.tensor([1.0, 2.0])
x = torch.normal(mean, std) # 生成兩個正態分布隨機數
print(f"正態分布隨機數: {x}, 形狀: {x.shape}")
1.3 輸出維度測試
在實際的深度學習任務中,我們通常需要計算輸入張量經過不同層后的輸出維度。以下是卷積層、池化層、線性層等的維度變化示例:
import torch
import torch.nn as nn# 生成輸入張量 (批量大小, 通道數, 高度, 寬度)
input_tensor = torch.randn(1, 3, 32, 32) # 例如CIFAR-10圖像
print(f"輸入尺寸: {input_tensor.shape}")# 卷積層操作
conv1 = nn.Conv2d(in_channels=3, # 輸入通道數out_channels=16, # 輸出通道數(卷積核數量)kernel_size=3, # 卷積核大小stride=1, # 步長padding=1 # 填充
)
conv_output = conv1(input_tensor) # 由于 padding=1 且 stride=1,空間尺寸保持不變
print(f"卷積后尺寸: {conv_output.shape}")# 池化層操作 (減小空間尺寸)
pool = nn.MaxPool2d(kernel_size=2, stride=2) # 創建一個最大池化層
pool_output = pool(conv_output)
print(f"池化后尺寸: {pool_output.shape}")# 將多維張量展平為向量
flattened = pool_output.view(pool_output.size(0), -1)
print(f"展平后尺寸: {flattened.shape}")# 線性層操作
fc1 = nn.Linear(in_features=4096, # 輸入特征數out_features=128 # 輸出特征數
)
fc_output = fc1(flattened)
print(f"線性層后尺寸: {fc_output.shape}")# 再經過一個線性層(例如分類器)
fc2 = nn.Linear(128, 10) # 假設是10分類問題
final_output = fc2(fc_output)
print(f"最終輸出尺寸: {final_output.shape}")
二、廣播機制
PyTorch 的廣播機制(Broadcasting)是一種強大的張量運算特性,允許在不同形狀的張量之間進行算術運算,而無需顯式地擴展張量維度或復制數據。這種機制使得代碼更簡潔高效,尤其在處理多維數據時非常實用。
2.1 廣播機制的規則
當對兩個形狀不同的張量進行運算時,PyTorch 會按以下規則自動處理維度兼容性:
-
從右向左比較維度:從張量的最后一個維度(最右側)開始向前逐維比較。
-
維度擴展條件:
-
相等維度:若兩個張量在某一維度上大小相同,則繼續比較下一維度。
-
一維擴展:若其中一個張量在某一維度上大小為 1,則該維度會被擴展為另一個張量對應維度的大小。
-
不兼容錯誤:若某一維度大小既不相同也不為 1,則拋出
RuntimeError
。
-
-
維度補全規則:若一個張量的維度少于另一個,則在其左側補 1 直至維度數匹配。
2.2 加法的廣播機制
以下是幾個加法廣播的例子:
二維張量與一維向量相加
a = torch.tensor([[10], [20], [30]]) # 形狀: (3, 1)
b = torch.tensor([1, 2, 3]) # 形狀: (3,)
result = a + bprint("原始張量a:")
print(a)print("\n原始張量b:")
print(b)print("\n加法結果:")
print(result)
三維張量與二維張量相加
a = torch.tensor([[[1], [2]], [[3], [4]]]) # 形狀: (2, 2, 1)
b = torch.tensor([[10, 20]]) # 形狀: (1, 2)
result = a + bprint("原始張量a:")
print(a)print("\n原始張量b:")
print(b)print("\n加法結果:")
print(result)
二維張量與標量相加
a = torch.tensor([[1, 2], [3, 4]]) # 形狀: (2, 2)
b = 10 # 標量,形狀視為 ()
result = a + bprint("原始張量a:")
print(a)print("\n標量b:")
print(b)print("\n加法結果:")
print(result)
高維張量與低維張量相加
a = torch.tensor([[[1, 2], [3, 4]]]) # 形狀: (1, 2, 2)
b = torch.tensor([[5, 6]]) # 形狀: (1, 2)
result = a + bprint("原始張量a:")
print(a)print("\n原始張量b:")
print(b)print("\n加法結果:")
print(result)
2.3 乘法的廣播機制
矩陣乘法(@
)的廣播機制除了遵循通用廣播規則外,還需要滿足矩陣乘法的維度約束:
-
最后兩個維度必須滿足:
A.shape[-1] == B.shape[-2]
(即 A 的列數等于 B 的行數)。 -
其他維度(批量維度):遵循通用廣播規則。
以下是幾個矩陣乘法廣播的例子:
批量矩陣與單個矩陣相乘
A = torch.randn(2, 3, 4) # 形狀: (2, 3, 4)
B = torch.randn(4, 5) # 形狀: (4, 5)
result = A @ B # 結果形狀: (2, 3, 5)print("A形狀:", A.shape)
print("B形狀:", B.shape)
print("結果形狀:", result.shape)
批量矩陣與批量矩陣相乘(部分廣播)
A = torch.randn(3, 2, 4) # 形狀: (3, 2, 4)
B = torch.randn(1, 4, 5) # 形狀: (1, 4, 5)
result = A @ B # 結果形狀: (3, 2, 5)print("A形狀:", A.shape)
print("B形狀:", B.shape)
print("結果形狀:", result.shape)
三維張量與二維張量相乘(高維廣播)
A = torch.randn(2, 3, 4, 5) # 形狀: (2, 3, 4, 5)
B = torch.randn(5, 6) # 形狀: (5, 6)
result = A @ B # 結果形狀: (2, 3, 4, 6)print("A形狀:", A.shape)
print("B形狀:", B.shape)
print("結果形狀:", result.shape)
@浙大疏錦行