PyTorch 從 0 到 1:超詳細的安裝與入門實戰指南
PyTorch 是一個由 Meta (Facebook) AI 研究實驗室主導開發的開源機器學習庫。它以其靈活性、易用性和強大的GPU加速功能而聞名,已成為學術界和工業界進行深度學習研究和應用開發的首選框架之一。
PyTorch 的兩大核心特性:
- 張量 (Tensor) 計算:類似于 NumPy 的多維數組,但提供了強大的 GPU 加速能力,使得大規模數值計算變得極其高效。
- 自動微分 (Automatic Differentiation):PyTorch 內置了名為 torch.autograd的自動微分引擎,可以自動計算神經網絡中參數的梯度,這是訓練深度學習模型的關鍵。
第一部分:PyTorch 安裝
安裝 PyTorch 最可靠的方式是遵循其官網的指導。因為不同的操作系統、包管理器和硬件(CPU/GPU)組合需要不同的命令。
步驟 1: 確認你的環境
在安裝前,你需要明確以下幾點:
(1) 操作系統 (OS):Windows, macOS, 還是 Linux?
(2) 包管理器 (Package Manager):你習慣使用pip還是conda?
- Conda:強烈推薦。Conda 不僅能管理 Python 包,還能管理 Python 解釋器本身和復雜的非 Python 依賴(如 CUDA 工具包),可以創建隔離的環境,避免版本沖突。
- Pip:Python 官方的包管理器,如果你不打算使用 GPU 或能自行管理好 CUDA 環境,Pip 也是一個不錯的選擇。
(3) 硬件 (Compute Platform):你打算只使用 CPU 還是利用 NVIDIA GPU 進行加速?
- CPU:所有電腦都支持。
- GPU (CUDA):如果你有 NVIDIA 顯卡,并且想利用它來加速訓練,就需要安裝支持 CUDA 的 PyTorch 版本。你需要先確認你的顯卡驅動和 CUDA Toolkit 版本。可以在終端(或 Windows 的 cmd/PowerShell)中輸入 nvidia-smi 命令來查看。
步驟 2: 訪問 PyTorch 官網生成安裝命令
(1) 開PyTorch 官網的安裝頁面:https://pytorch.org/get-started/locally/
(2) 在頁面上,你會看到一個交互式的配置工具。請根據你的環境依次選擇:
① 如果你的電腦沒有 NVIDIA 顯卡,或者你暫時不想配置 GPU,請選擇 CPU。
② 如果你有 NVIDIA 顯卡并想使用它,請選擇一個 CUDA 版本。通常選擇與你 nvidia-smi 命令顯示的 CUDA 版本最接近或稍低的版本(PyTorch 的 CUDA 版本是其編譯時依賴的,通常能向后兼容較新的驅動)。
- PyTorch Build: 選擇 Stable (穩定版),適合絕大多數用戶。
- Your OS: 選擇你的操作系統。
- Package: 選擇 Conda 或 Pip。
- Language: 選擇 Python。
- Compute Platform: 這是最關鍵的一步。
③ 復制生成的命令。網站會根據你的選擇自動生成一行安裝命令。
步驟 3: 執行安裝命令
強烈建議在一個新的虛擬環境中安裝 PyTorch,以避免與系統中其他 Python 包沖突。
使用 Conda (推薦):
# 1. 創建一個新的 conda 環境 (例如,名為 'pytorch_env'),并指定 Python 版本
conda create -n pytorch_env pythnotallow=3.9
# 2. 激活這個新環境
conda activate pytorch_env
# 3. 粘貼并執行從官網復制的命令。以下是一些示例:
# 示例 1: Conda, Linux/Windows, 只用 CPU
# conda install pytorch torchvision torchaudio cpuonly -c pytorch
# 示例 2: Conda, Linux/Windows, 使用 CUDA 11.8
# conda install pytorch torchvision torchaudio pytorch-cuda=11.8 -c pytorch -c nvidia
使用 Pip:
# 1. 創建一個新的虛擬環境 (例如,名為 'pytorch_venv')
python -m venv pytorch_venv
# 2. 激活環境
# Windows
# pytorch_venv\Scripts\activate
# Linux/macOS
# source pytorch_venv/bin/activate
# 3. 粘貼并執行從官網復制的命令。以下是一些示例:
# 示例 1: Pip, Linux/Windows, 只用 CPU
# pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu
# 示例 2: Pip, Linux/Windows, 使用 CUDA 11.8
# pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
步驟 4: 驗證安裝
安裝完成后,在你的終端(確保虛擬環境已激活)中啟動 Python 解釋器,然后輸入以下代碼:
import torch
# 1. 打印 PyTorch 版本
print(f"PyTorch Version: {torch.__version__}")
# 2. 檢查一個張量是否可以被創建
x = torch.rand(5, 3)
print(x)
# 3. (關鍵) 檢查 CUDA 是否可用
is_cuda_available = torch.cuda.is_available()
print(f"CUDA Available: {is_cuda_available}")
if is_cuda_available:
# 4. 打印 CUDA 版本
print(f"CUDA Version: {torch.version.cuda}")
# 5. 打印 GPU 數量
print(f"GPU Count: {torch.cuda.device_count()}")
# 6. 打印當前 GPU 名稱
print(f"GPU Name: {torch.cuda.get_device_name(0)}")
我的電腦是CPU處理器,顯示如下。
如果以上代碼都能順利運行,并且 CUDA Available 的狀態符合你的預期,那么恭喜你,PyTorch 已經成功安裝!
第二部分:PyTorch 基礎使用
現在我們來學習 PyTorch 的核心組件。
1. 張量 (Tensors)
張量是 PyTorch 中最基本的數據結構,可以看作是多維數組。
import torch
import numpy as np
# --- 創建張量 ---
# 從 Python 列表創建
data = [[1, 2], [3, 4]]
x_data = torch.tensor(data)
print(f"Tensor from list:\n {x_data}\n")
# 從 NumPy 數組創建 (共享內存,修改一個會影響另一個)
np_array = np.array(data)
x_np = torch.from_numpy(np_array)
print(f"Tensor from NumPy:\n {x_np}\n")
# 創建一個全為1的張量,形狀與 x_data 相同
x_ones = torch.ones_like(x_data)
print(f"Ones Tensor:\n {x_ones}\n")
# 創建一個隨機張量,形狀與 x_data 相同,值在 [0, 1) 之間
x_rand = torch.rand_like(x_data, dtype=torch.float) # 重載數據類型
print(f"Random Tensor:\n {x_rand}\n")
# 直接指定形狀創建
shape = (2, 3,)
rand_tensor = torch.rand(shape)
ones_tensor = torch.ones(shape)
zeros_tensor = torch.zeros(shape)
print(f"Random tensor of shape {shape}:\n {rand_tensor}\n")
# --- 張量屬性 ---
tensor = torch.rand(3, 4)
print(f"Shape of tensor: {tensor.shape}")
print(f"Datatype of tensor: {tensor.dtype}")
print(f"Device tensor is stored on: {tensor.device}") # 默認是 'cpu'
# --- 將張量移動到 GPU ---
# 只有在 CUDA 可用時才能成功
if torch.cuda.is_available():
tensor_gpu = tensor.to("cuda")
print(f"Device tensor is now stored on: {tensor_gpu.device}")
# --- 張量操作 ---
tensor = torch.ones(4, 4)
tensor[:, 1] = 0 # 類似 NumPy 的索引和切片
print(f"Tensor after slicing:\n {tensor}\n")
# 拼接張量
t1 = torch.cat([tensor, tensor, tensor], dim=1) # 按列拼接
print(f"Concatenated tensor:\n {t1}\n")
# 算術運算
# 矩陣乘法
mat_mul = tensor.matmul(tensor.T) # .T 是轉置
# 或者使用 @ 符號
mat_mul_alt = tensor @ tensor.T
print(f"Matrix multiplication:\n {mat_mul}\n")
# 元素級乘法
elem_mul = tensor.mul(tensor)
# 或者使用 * 符號
elem_mul_alt = tensor * tensor
print(f"Element-wise multiplication:\n {elem_mul}\n")
# 單元素張量轉為 Python 數值
agg = tensor.sum()
agg_item = agg.item()
print(f"Sum as a tensor: {agg}, Sum as a Python number: {agg_item}")
2. torch.autograd:自動微分
這是 PyTorch 的魔力所在。當你創建一個張量時,可以設置 requires_grad=True 來追蹤對它的所有操作。完成計算后,你可以調用 .backward() 來自動計算所有梯度。
# 創建需要計算梯度的張量 (例如模型的權重)
w = torch.randn(1, requires_grad=True)
b = torch.randn(1, requires_grad=True)
# 創建輸入數據張量 (不需要計算梯度)
x = torch.tensor([2.0])
# 定義一個簡單的線性模型
y = w * x + b
# 假設真實值為 5.0,我們計算損失 (loss)
# 損失必須是一個標量 (單個數值)
loss = (y - 5.0).pow(2)
print(f"w: {w.item()}, b: {b.item()}, y: {y.item()}, loss: {loss.item()}")
# --- 關鍵步驟:反向傳播 ---
loss.backward()
# --- 查看梯度 ---
# 梯度被累積在 .grad 屬性中
# d(loss)/dw
print(f"Gradient of w: {w.grad.item()}")
# d(loss)/db
print(f"Gradient of b: {b.grad.item()}")
# 在評估模型或進行預測時,我們不需要梯度,可以使用 torch.no_grad() 來停止追蹤,節省內存和計算資源
with torch.no_grad():
y_pred = w * x + b
print(f"Prediction with no_grad: {y_pred.item()}")
# 在這個代碼塊內,所有計算都不會被追蹤
print(w.requires_grad) # 仍然是 True
print((w * x).requires_grad) # 但是新計算出的張量是 False
3. nn.Module:構建神經網絡
PyTorch 使用 torch.nn.Module 作為所有神經網絡模型的基類。構建一個自定義模型通常需要:
- 創建一個繼承自 nn.Module 的類。
- 在 __init__ 方法中定義網絡的層次結構(如線性層、卷積層等)。
- 在 forward 方法中定義數據如何通過這些層進行前向傳播。
from torch import nn
# 定義一個簡單的神經網絡
class SimpleNet(nn.Module):
def __init__(self):
super(SimpleNet, self).__init__()
# 定義網絡層
# 輸入維度為 10,第一個隱藏層維度為 32
self.layer1 = nn.Linear(10, 32)
# 激活函數
self.relu = nn.ReLU()
# 第二個隱藏層
self.layer2 = nn.Linear(32, 16)
# 輸出層,維度為 2 (例如,一個二分類問題)
self.output_layer = nn.Linear(16, 2)
def forward(self, x):
# 定義數據流
x = self.layer1(x)
x = self.relu(x)
x = self.layer2(x)
x = self.relu(x)
logits = self.output_layer(x)
return logits
# 實例化模型
model = SimpleNet()
print(model)
# 我們可以傳入一個符合輸入尺寸的隨機數據來測試
input_data = torch.randn(1, 10) # 1個樣本,10個特征
output = model(input_data)
print(f"\nModel output for random data:\n {output}")
4. 損失函數 (Loss Functions) 和優化器 (Optimizers)
- 損失函數:衡量模型輸出與真實標簽之間的差距。torch.nn 提供了多種常見的損失函數,如 nn.MSELoss (均方誤差,用于回歸) 和 nn.CrossEntropyLoss (交叉熵損失,用于分類)。
- 優化器:根據損失函數計算出的梯度來更新模型的參數(權重和偏置)。torch.optim 提供了多種優化算法,如 SGD (隨機梯度下降) 和 Adam。
第三部分:一個完整的簡單示例:線性回歸
讓我們把以上所有概念串聯起來,完成一個最簡單的機器學習任務:線性回歸。我們的目標是讓模型學習函數 y = 3x + 2。
import torch
from torch import nn, optim
# 1. 準備數據
# 創建一些帶有噪聲的樣本數據
X = torch.randn(100, 1) * 10 # 100個樣本,1個特征
y_true = 3 * X + 2 + torch.randn(100, 1) * 2 # 真實 y = 3x + 2 + 噪聲
# 2. 定義模型
# 對于線性回歸,一個線性層就足夠了
# 輸入維度是1 (x),輸出維度也是1 (y)
model = nn.Linear(1, 1)
# 我們可以查看模型初始化的隨機參數
print(f"Initial weights: {model.weight.item()}")
print(f"Initial bias: {model.bias.item()}")
# 3. 定義損失函數和優化器
loss_fn = nn.MSELoss()
optimizer = optim.SGD(model.parameters(), lr=0.001) # lr 是學習率
# 4. 訓練循環
epochs = 100 # 訓練輪數
for epoch in range(epochs):
# --- 前向傳播 ---
y_pred = model(X)
# --- 計算損失 ---
loss = loss_fn(y_pred, y_true)
# --- 反向傳播與優化 ---
# 梯度清零 (非常重要!否則梯度會累積)
optimizer.zero_grad()
# 計算梯度
loss.backward()
# 更新參數
optimizer.step()
# 打印訓練過程
if (epoch + 1) % 10 == 0:
print(f'Epoch [{epoch+1}/{epochs}], Loss: {loss.item():.4f}')
# 5. 查看訓練結果
# 訓練結束后,模型參數應該接近 w=3, b=2
print("\n--- Training Finished ---")
print(f"Learned weights: {model.weight.item():.4f}")
print(f"Learned bias: {model.bias.item():.4f}")
# 使用模型進行預測
new_x = torch.tensor([[10.0]])
predicted_y = model(new_x)
print(f"\nPrediction for x=10: {predicted_y.item():.4f} (True value should be around 3*10+2=32)")
Initial weights: -0.006330609321594238
Initial bias: 0.10331559181213379
Epoch [10/100], Loss: 33.0378
Epoch [20/100], Loss: 7.6095
Epoch [30/100], Loss: 6.9261
Epoch [40/100], Loss: 6.8030
Epoch [50/100], Loss: 6.6967
Epoch [60/100], Loss: 6.5947
Epoch [70/100], Loss: 6.4967
Epoch [80/100], Loss: 6.4025
Epoch [90/100], Loss: 6.3120
Epoch [100/100], Loss: 6.2250
--- Training Finished ---
Learned weights: 3.0174
Learned bias: 0.3916
Prediction for x=10: 30.5654 (True value should be around 3*10+2=32)
這個例子展示了 PyTorch 訓練一個模型的核心流程:
定義模型 -> 定義損失和優化器 -> 循環(前向傳播 -> 計算損失 -> 梯度清零 -> 反向傳播 -> 更新參數)
第四部分:進階學習建議
當你掌握了以上基礎后,可以繼續探索以下內容:
(1) Dataset和DataLoader:torch.utils.data中的這兩個類是處理和加載大型數據集的標準工具,可以實現數據批處理 (batching)、打亂 (shuffling) 和并行加載。
(2) 更復雜的網絡結構:
- 卷積神經網絡 (CNNs):用于圖像處理,核心是 nn.Conv2d 和 nn.MaxPool2d。
- 循環神經網絡(RNNs):用于序列數據(如文本、時間序列),核心是 nn.RNN,nn.LSTM,nn.GRU。
(3) 保存和加載模型:使用torch.save()保存模型的狀態字典(model.state_dict()),使用torch.load()和model.load_state_dict() 來加載。
(4) TorchVision, TorchAudio, TorchText:PyTorch 官方的擴展庫,提供了針對計算機視覺、音頻處理和自然語言處理的常用數據集、預訓練模型和轉換工具。
(5) 官方教程:PyTorch 官網提供了大量高質量的教程,從基礎到高級應用應有盡有,是最好的學習資源。