文章目錄
- 什么是張量?
- 張量初始化方法
- 1. 直接從數據創建
- 2. 從 NumPy 數組轉換
- 3. 基于現有張量創建
- 4. 使用隨機值或常量
- 張量屬性
- 張量操作
- 設備轉移
- 索引和切片
- 連接張量
- 算術運算
- 單元素張量轉換
- 原地操作(In-place Operations)
- PyTorch 與 NumPy 互操作
- 張量轉 NumPy 數組
- NumPy 數組轉張量
- 張量操作總結表
- 最佳實踐與注意事項
什么是張量?
張量(Tensors)是 PyTorch 中的核心數據結構,類似于數組和矩陣,但具有更強大的功能。在深度學習中,我們使用張量來表示:
- 模型的輸入和輸出數據
- 模型的參數(權重和偏置)
- 中間計算過程中的數據
張量與 NumPy 的 ndarrays 類似,但有兩大關鍵優勢:
- GPU 加速:可在 GPU 或其他硬件加速器上運行
- 自動微分:支持自動求導,這對深度學習至關重要
import torch
import numpy as np
張量初始化方法
1. 直接從數據創建
data = [[1, 2], [3, 4]]
x_data = torch.tensor(data)
2. 從 NumPy 數組轉換
np_array = np.array(data)
x_np = torch.from_numpy(np_array)
3. 基于現有張量創建
x_ones = torch.ones_like(x_data) # 保留原始張量屬性
x_rand = torch.rand_like(x_data, dtype=torch.float) # 覆蓋數據類型print(f"Ones Tensor:\n{x_ones}")
print(f"Random Tensor:\n{x_rand}")
4. 使用隨機值或常量
shape = (2, 3)
rand_tensor = torch.rand(shape)
ones_tensor = torch.ones(shape)
zeros_tensor = torch.zeros(shape)print(f"Random Tensor:\n{rand_tensor}")
print(f"Ones Tensor:\n{ones_tensor}")
print(f"Zeros Tensor:\n{zeros_tensor}")
張量屬性
每個張量都有三個關鍵屬性:
tensor = torch.rand(3, 4)print(f"Shape: {tensor.shape}") # 形狀
print(f"Datatype: {tensor.dtype}") # 數據類型
print(f"Device: {tensor.device}") # 存儲設備 (CPU/GPU)
張量操作
設備轉移
# 轉移到GPU(如果可用)
device = "cuda" if torch.cuda.is_available() else "cpu"
tensor = tensor.to(device)
print(f"Device after transfer: {tensor.device}")
索引和切片
tensor = torch.ones(4, 4)
print(f"First row: {tensor[0]}")
print(f"First column: {tensor[:, 0]}")
print(f"Last column: {tensor[..., -1]}")tensor[:, 1] = 0 # 修改第二列
print(tensor)
連接張量
t1 = torch.cat([tensor, tensor, tensor], dim=1)
print(f"Concatenated tensor:\n{t1}")
算術運算
# 矩陣乘法(三種等效方式)
y1 = tensor @ tensor.T
y2 = tensor.matmul(tensor.T)
y3 = torch.rand_like(y1)
torch.matmul(tensor, tensor.T, out=y3)# 逐元素乘法(三種等效方式)
z1 = tensor * tensor
z2 = tensor.mul(tensor)
z3 = torch.rand_like(tensor)
torch.mul(tensor, tensor, out=z3)
單元素張量轉換
agg = tensor.sum()
agg_item = agg.item() # 轉換為Python標量
print(f"Sum value: {agg_item}, Type: {type(agg_item)}")
原地操作(In-place Operations)
原地操作直接修改張量內容,使用 _
后綴表示:
print("Original tensor:")
print(tensor)tensor.add_(5) # 原地加5
print("\nAfter in-place addition:")
print(tensor)
注意:雖然原地操作節省內存,但在自動微分中可能導致梯度計算問題,應謹慎使用。
PyTorch 與 NumPy 互操作
張量轉 NumPy 數組
t = torch.ones(5)
n = t.numpy()
print(f"Tensor: {t}\nNumPy: {n}")# 修改張量會影響NumPy數組
t.add_(1)
print(f"\nAfter modification:\nTensor: {t}\nNumPy: {n}")
NumPy 數組轉張量
n = np.ones(5)
t = torch.from_numpy(n)
print(f"NumPy: {n}\nTensor: {t}")# 修改NumPy數組會影響張量
np.add(n, 1, out=n)
print(f"\nAfter modification:\nNumPy: {n}\nTensor: {t}")
張量操作總結表
操作類型 | 方法示例 | 說明 |
---|---|---|
創建 | torch.tensor() , torch.rand() , torch.zeros() | 多種初始化方式 |
屬性 | .shape , .dtype , .device | 獲取張量元數據 |
索引 | tensor[0] , tensor[:, 1] | 類似NumPy的索引 |
運算 | torch.matmul() , tensor.sum() | 矩陣運算和歸約 |
連接 | torch.cat() , torch.stack() | 合并多個張量 |
轉換 | .numpy() , torch.from_numpy() | 與NumPy互轉 |
最佳實踐與注意事項
- 設備管理:明確張量所在的設備(CPU/GPU),避免不必要的設備間傳輸
- 數據類型:注意操作中的數據類型一致性,使用
.dtype
檢查 - 內存共享:PyTorch 和 NumPy 數組共享內存,修改一個會影響另一個
- 自動微分:避免在需要梯度的計算圖中使用原地操作
- 性能優化:對大規模數據使用 GPU 加速,對小規模操作可能 CPU 更高效
# 高效設備轉移示例
if torch.cuda.is_available():tensor = tensor.to('cuda')# 保持數據類型一致
float_tensor = torch.rand(3, dtype=torch.float32)
int_tensor = torch.tensor([1, 2, 3], dtype=torch.int32)
result = float_tensor + int_tensor.float() # 顯式轉換
掌握張量操作是使用 PyTorch 進行深度學習的基礎。通過本文介紹的各種方法,您可以高效地創建、操作和轉換張量,為構建復雜模型奠定堅實基礎!
官方文檔:https://docs.pytorch.org/tutorials/beginner/basics/tensorqs_tutorial.html