1. 引言
在深度學習和科學計算領域,張量(Tensor)?是最基礎的數據結構。PyTorch 作為當前最流行的深度學習框架之一,其核心計算單元就是張量。與 NumPy 的?
ndarray
?類似,PyTorch 張量支持高效的數值計算,但額外提供了?GPU 加速?和?自動微分(Autograd)?功能,使其成為構建和訓練神經網絡的理想選擇。本文將全面介紹 PyTorch 張量的核心概念、基本操作、高級特性及實際應用,幫助讀者掌握張量的使用方法,并理解其在深度學習中的作用。
2. 什么是張量?
張量是多維數組的泛化,可以表示不同維度的數據:
0D 張量(標量):單個數值,如?
torch.tensor(5)
1D 張量(向量):一維數組,如?
torch.tensor([1, 2, 3])
2D 張量(矩陣):二維數組,如?
torch.tensor([[1, 2], [3, 4]])
3D+ 張量(高階張量):如 RGB 圖像(3D)、視頻數據(4D)等
PyTorch 張量的主要特點:
支持 GPU 加速:可無縫切換 CPU/GPU 計算。
自動微分:用于神經網絡的反向傳播。
動態計算圖:更靈活的模型構建方式(與 TensorFlow 1.x 的靜態計算圖不同)。
3. 張量的創建與初始化
3.1 從 Python 列表或 NumPy 數組創建
import torch
import numpy as np# 從列表創建
t1 = torch.tensor([1, 2, 3]) # 1D 張量
t2 = torch.tensor([[1, 2], [3, 4]]) # 2D 張量# 從 NumPy 數組創建
arr = np.array([1, 2, 3])
t3 = torch.from_numpy(arr) # 共享內存(修改一個會影響另一個)
3.2 特殊初始化方法
# 全零張量
zeros = torch.zeros(2, 3) # 2x3 的零矩陣# 全一張量
ones = torch.ones(2) # [1., 1.]# 隨機張量
rand_uniform = torch.rand(2, 2) # 0~1 均勻分布
rand_normal = torch.randn(2, 2) # 標準正態分布# 類似現有張量的形狀
x = torch.tensor([[1, 2], [3, 4]])
x_like = torch.rand_like(x) # 形狀與 x 相同,值隨機
4. 張量的基本屬性
每個 PyTorch 張量都有以下關鍵屬性:
x = torch.rand(2, 3, dtype=torch.float32, device="cuda")print(x.shape) # 形狀: torch.Size([2, 3])
print(x.dtype) # 數據類型: torch.float32
print(x.device) # 存儲設備: cpu / cuda
print(x.requires_grad) # 是否啟用梯度計算(用于 Autograd)
4.1 數據類型(dtype)
PyTorch 支持多種數據類型:
torch.float32
(默認)torch.int64
torch.bool
(布爾張量)
可以通過?.to()
?方法轉換:
x = torch.tensor([1, 2], dtype=torch.float32)
y = x.to(torch.int64) # 轉換為整型
4.2 設備(CPU/GPU)
PyTorch 允許張量在 CPU 或 GPU 上運行:
if torch.cuda.is_available():device = torch.device("cuda")x = x.to(device) # 移動到 GPUy = y.to("cuda") # 簡寫方式
5. 張量的基本運算
5.1 算術運算
a = torch.tensor([1, 2])
b = torch.tensor([3, 4])# 加法
c = a + b # 等價于 torch.add(a, b)# 乘法(逐元素)
d = a * b # [3, 8]# 矩陣乘法
mat_a = torch.rand(2, 3)
mat_b = torch.rand(3, 2)
mat_c = torch.matmul(mat_a, mat_b) # 或 mat_a @ mat_b
5.2 形狀操作
x = torch.rand(4, 4)# 改變形狀(類似 NumPy 的 reshape)
y = x.view(16) # 展平為一維張量
z = x.view(2, 8) # 調整為 2x8# 轉置
x_t = x.permute(1, 0) # 行列交換# 擴維 / 壓縮
x_expanded = x.unsqueeze(0) # 增加一個維度(1x4x4)
x_squeezed = x_expanded.squeeze() # 去除大小為1的維度
5.3 索引與切片
x = torch.rand(3, 4)# 取第一行
row = x[0, :]# 取前兩列
cols = x[:, :2]# 布爾索引
mask = x > 0.5
filtered = x[mask] # 返回滿足條件的元素
6. 自動微分(Autograd)
PyTorch 的?autograd
?模塊支持自動計算梯度,適用于反向傳播:
x = torch.tensor(2.0, requires_grad=True)
y = x ** 2 + 3 * x # 計算圖構建
y.backward() # 反向傳播
print(x.grad) # dy/dx = 2x + 3 → 7.0
6.1 禁用梯度計算
with torch.no_grad():y = x * 2 # 不記錄梯度
7. 張量與 NumPy 的互操作
PyTorch 張量可以無縫轉換為 NumPy 數組:
# Tensor → NumPy
a = torch.rand(2, 2)
b = a.numpy() # 共享內存(修改一個會影響另一個)# NumPy → Tensor
c = np.array([1, 2])
d = torch.from_numpy(c) # 共享內存
8. 實際應用示例
8.1 線性回歸(手動實現)
# 數據準備
X = torch.rand(100, 1)
y = 3 * X + 2 + 0.1 * torch.randn(100, 1)# 初始化參數
w = torch.randn(1, requires_grad=True)
b = torch.zeros(1, requires_grad=True)# 訓練
lr = 0.01
for epoch in range(100):y_pred = w * X + bloss = ((y_pred - y) ** 2).mean()loss.backward() # 計算梯度with torch.no_grad():w -= lr * w.gradb -= lr * b.gradw.grad.zero_()b.grad.zero_()print(f"w: {w.item()}, b: {b.item()}")
8.2 張量在 CNN 中的應用
import torch.nn as nn# 模擬輸入(batch_size=1, channels=3, height=32, width=32)
input_tensor = torch.rand(1, 3, 32, 32)# 定義一個簡單的 CNN
model = nn.Sequential(nn.Conv2d(3, 16, kernel_size=3),nn.ReLU(),nn.MaxPool2d(2),nn.Flatten(),nn.Linear(16 * 15 * 15, 10) # 假設輸出 10 類
)output = model(input_tensor)
print(output.shape) # torch.Size([1, 10])
9. 總結
PyTorch 張量是深度學習的基礎數據結構,支持:
多維數組計算(類似 NumPy)
GPU 加速(大幅提升計算速度)
自動微分(簡化神經網絡訓練)
動態計算圖(靈活調試模型)
掌握張量的基本操作是學習 PyTorch 的關鍵步驟。建議讀者通過官方文檔和實際項目加深理解,逐步掌握張量的高級用法(如廣播機制、高級索引等)。