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 官网提供了大量高质量的教程,从基础到高级应用应有尽有,是最好的学习资源。