3. 人工智能学习-PyTorch框架学习

一、PyTorch 环境准备(前置条件)

确保已完成 Anaconda 虚拟环境和 GPU 环境配置(参考前文),激活环境后安装 PyTorch:​

bash 复制代码
# 激活虚拟环境​
conda activate ai-dev​
# 安装 PyTorch(GPU 版本,自动适配 CUDA,国内镜像加速)​
conda install pytorch torchvision torchaudio pytorch-cuda=12.1 -c pytorch -c nvidia -c conda-forge​
# 验证安装(终端执行 Python 代码)​
python -c "import torch; print(torch.__version__); print(torch.cuda.is_available())"​
# 输出示例:2.2.0 + True(True 表示 GPU 可用)

二、核心模块 1:张量(Tensor)操作(PyTorch 基础)​

张量是 PyTorch 的核心数据结构,类比 NumPy 数组,但支持 GPU 加速和自动求导,是模型输入、参数存储的基础。

1. 张量创建(常用方式)​

bash 复制代码
import torch
import numpy as np

# 1. 从 Python 列表/元组创建
tensor1 = torch.tensor([[1, 2, 3], [4, 5, 6]], dtype=torch.float32)  # 2×3 张量,float32 节省显存
print("列表创建张量:\n", tensor1, "\n形状:", tensor1.shape, "\n数据类型:", tensor1.dtype)

# 2. 从 NumPy 数组创建(共享内存,高效转换)
np_arr = np.array([[0.1, 0.2], [0.3, 0.4]])
tensor2 = torch.from_numpy(np_arr)
print("\nNumPy 转换张量:\n", tensor2, "\nNumPy 数组修改后张量变化:")
np_arr[0,0] = 10.0  # 修改 NumPy 数组
print(tensor2)  # 张量同步变化(如需独立,用 tensor2 = torch.tensor(np_arr))

# 3. 创建特殊张量(实战高频)
tensor3 = torch.zeros((3, 4))  # 3×4 全0张量
tensor4 = torch.ones((2, 2, 3))  # 2×2×3 全1张量(3维,适配批量数据)
tensor5 = torch.randn((3, 3))  # 3×3 正态分布张量(均值0,方差1,模型初始化常用)
tensor6 = torch.arange(0, 10, step=2)  # 0-10 步长2:[0,2,4,6,8]
print("\n全0张量:\n", tensor3, "\n3维全1张量:\n", tensor4, "\n正态分布张量:\n", tensor5)

2. 张量核心操作(实战必备)​

bash 复制代码
# 1. 形状操作(适配模型输入输出维度)
tensor = torch.randn(2, 3)  # 2×3 张量
print("原始张量:\n", tensor)
# 重塑形状(需保持元素总数一致)
tensor_reshape = tensor.reshape(3, 2)  # 3×2
# 展平(模型全连接层输入常用)
tensor_flatten = tensor.flatten()  # 1维张量:[x1,x2,x3,x4,x5,x6]
# 增加维度(批量维度,实战高频:(C,H,W)→(1,C,H,W))
tensor_unsqueeze = tensor.unsqueeze(0)  # 1×2×3(第0维增加批量维度)
print("\n重塑后:\n", tensor_reshape, "\n展平后:\n", tensor_flatten, "\n增加批量维度后:\n", tensor_unsqueeze.shape)

# 2. 索引与切片(数据筛选)
tensor = torch.tensor([[1,2,3],[4,5,6],[7,8,9]], dtype=torch.float32)
# 取第0行
row0 = tensor[0, :]
# 取第1列
col1 = tensor[:, 1]
# 取前2行、后2列(切片左闭右开)
slice_tensor = tensor[:2, 1:]
print("\n第0行:", row0, "\n第1列:", col1, "\n切片结果:\n", slice_tensor)

# 3. 数学运算(模型计算核心)
a = torch.tensor([1, 2, 3], dtype=torch.float32)
b = torch.tensor([4, 5, 6], dtype=torch.float32)
# 元素-wise 运算
add = a + b  # 等价于 torch.add(a,b)
mul = a * b  # 等价于 torch.mul(a,b)
pow = a ** 2  # 平方
# 矩阵乘法(模型权重与特征计算)
mat_a = torch.randn(2, 3)
mat_b = torch.randn(3, 4)
mat_mul = torch.matmul(mat_a, mat_b)  # 2×4 矩阵乘法,等价于 mat_a @ mat_b
print("\n元素加法:", add, "\n元素乘法:", mul, "\n矩阵乘法形状:", mat_mul.shape)

# 4. 设备迁移(CPU ↔ GPU,加速关键)
tensor_cpu = torch.randn(3, 3)
if torch.cuda.is_available():
    tensor_gpu = tensor_cpu.cuda()  # 迁移到 GPU
    tensor_back_cpu = tensor_gpu.cpu()  # 迁回 CPU
    print("\nGPU 张量设备:", tensor_gpu.device, "\n迁回 CPU 后:", tensor_back_cpu.device)
else:
    print("\nGPU 不可用,使用 CPU 训练")

# 5. 自动求导(模型训练核心)
x = torch.tensor([2.0], requires_grad=True)  # 开启自动求导
y = x ** 2 + 3 * x + 1  # 计算图:y = x² + 3x +1
y.backward()  # 反向传播求导
print("\nx 的梯度(dy/dx = 2x+3,x=2 时为7):", x.grad)  # 输出:tensor([7.])

3. 张量与 NumPy 互转(数据处理兼容)​

bash 复制代码
# 张量 → NumPy
tensor = torch.tensor([[1,2],[3,4]], dtype=torch.float32)
np_arr = tensor.numpy()
print("张量转 NumPy:\n", np_arr, "\n类型:", type(np_arr))

# NumPy → 张量(独立内存,避免同步修改)
np_arr2 = np.array([[5,6],[7,8]])
tensor2 = torch.tensor(np_arr2)  # 独立内存,修改 np_arr2 不影响 tensor2
np_arr2[0,0] = 100
print("\nNumPy 转张量(独立内存):\n", tensor2)

三、核心模块 2:数据加载器(DataLoader)(实战输入核心)​

PyTorch 提供 torch.utils.data 模块,用于批量加载、预处理数据,适配大规模训练场景,核心是 Dataset(数据集定义)和 DataLoader(批量加载)。​

1. 自定义数据集(Dataset 类)

以 "模拟回归任务数据" 为例,自定义数据集类(实战中可替换为 CSV / 图片数据):​

bash 复制代码
import torch
from torch.utils.data import Dataset, DataLoader

# 自定义数据集类(必须继承 Dataset,重写 __len__ 和 __getitem__)
class MyRegressionDataset(Dataset):
    def __init__(self, data_size=1000, transform=None):
        """
        Args:
            data_size: 数据集大小
            transform: 数据预处理函数(可选)
        """
        # 生成模拟数据:y = 2x1 + 3x2 + 0.5(带噪声)
        self.x = torch.randn(data_size, 2)  # 特征:x1, x2(1000个样本)
        self.y = 2 * self.x[:, 0] + 3 * self.x[:, 1] + 0.5 + torch.randn(data_size) * 0.1  # 标签(含噪声)
        self.transform = transform

    def __len__(self):
        # 返回数据集总样本数(DataLoader 需用到)
        return len(self.x)

    def __getitem__(self, idx):
        # 根据索引返回单个样本((特征, 标签))
        sample = (self.x[idx], self.y[idx])
        if self.transform:
            sample = self.transform(sample)
        return sample

# 实例化数据集
dataset = MyRegressionDataset(data_size=1000)
print("数据集大小:", len(dataset))
print("第0个样本(特征, 标签):", dataset[0])

2. 批量加载数据(DataLoader 类)​

DataLoader 封装数据集,支持批量加载、打乱数据、多线程读取,是训练时的核心数据输入工具:

bash 复制代码
# 定义 DataLoader
dataloader = DataLoader(
    dataset,
    batch_size=32,  # 每次加载32个样本(批量大小,根据GPU显存调整)
    shuffle=True,   # 训练时打乱数据(提升泛化能力)
    num_workers=2   # 多线程读取(加速,根据CPU核心数调整)
)

# 迭代 DataLoader(训练时循环读取)
for batch_idx, (batch_x, batch_y) in enumerate(dataloader):
    print(f"第 {batch_idx+1} 个批次:")
    print(f"批量特征形状:{batch_x.shape}(32个样本,每个2个特征)")
    print(f"批量标签形状:{batch_y.shape}(32个标签)")
    # 模拟训练步骤(后续模型搭建后替换)
    if batch_idx == 2:  # 仅打印前3个批次
        break

3. 数据预处理(Transform)​

通过自定义 Transform 对数据进行标准化、归一化等预处理(实战必备,提升模型训练稳定性):​

bash 复制代码
# 定义预处理函数(标准化:(x - 均值) / 标准差)
class StandardizeTransform:
    def __init__(self, mean, std):
        self.mean = mean
        self.std = std

    def __call__(self, sample):
        x, y = sample
        x = (x - self.mean) / self.std  # 特征标准化
        return (x, y)

# 计算特征均值和标准差(基于整个数据集)
feature_mean = dataset.x.mean(dim=0)  # 按列(特征维度)计算均值
feature_std = dataset.x.std(dim=0)    # 按列计算标准差
print("特征均值:", feature_mean)
print("特征标准差:", feature_std)

# 实例化预处理类,创建带预处理的数据集
transformed_dataset = MyRegressionDataset(
    data_size=1000,
    transform=StandardizeTransform(mean=feature_mean, std=feature_std)
)

# 带预处理的 DataLoader
transformed_dataloader = DataLoader(
    transformed_dataset,
    batch_size=32,
    shuffle=True,
    num_workers=2
)

# 验证预处理效果
for batch_x, batch_y in transformed_dataloader:
    print("预处理后批量特征均值(接近0):", batch_x.mean(dim=0))
    print("预处理后批量特征标准差(接近1):", batch_x.std(dim=0))
    break

四、核心模块 3:模型搭建(nn.Module 类)​

PyTorch 用 torch.nn 模块构建神经网络,所有模型需继承 nn.Module,重写 __init__(定义层)和 forward(前向传播,计算输出)。

1. 搭建简单回归模型(全连接网络)​

以 "预测上述自定义数据集标签" 为例,搭建 2 层全连接网络:

bash 复制代码
import torch
import torch.nn as nn

# 定义回归模型(继承 nn.Module)
class SimpleRegressionModel(nn.Module):
    def __init__(self, input_dim=2, hidden_dim=16, output_dim=1):
        """
        Args:
            input_dim: 输入特征维度(本文数据集为2)
            hidden_dim: 隐藏层神经元数(可调参数)
            output_dim: 输出维度(回归任务为1)
        """
        super(SimpleRegressionModel, self).__init__()  # 必须调用父类初始化
        # 定义网络层(nn.Linear 为全连接层)
        self.fc1 = nn.Linear(input_dim, hidden_dim)  # 输入层→隐藏层:2→16
        self.relu = nn.ReLU()  # 激活函数(引入非线性,提升模型表达能力)
        self.fc2 = nn.Linear(hidden_dim, output_dim)  # 隐藏层→输出层:16→1

    def forward(self, x):
        """前向传播(模型计算逻辑,必须重写)"""
        x = self.fc1(x)      # 第一层全连接
        x = self.relu(x)     # 激活函数
        output = self.fc2(x) # 第二层全连接(输出预测值)
        return output

# 实例化模型
model = SimpleRegressionModel(input_dim=2, hidden_dim=16, output_dim=1)
print("回归模型结构:")
print(model)  # 打印模型层结构

# 验证模型输出(输入批量特征,查看输出形状)
batch_x, _ = next(iter(transformed_dataloader))  # 从 DataLoader 取一个批次特征
model_output = model(batch_x)
print(f"\n模型输入形状:{batch_x.shape}")
print(f"模型输出形状:{model_output.shape}")  # 输出:torch.Size([32, 1])(32个样本,每个1个预测值)

2. 搭建简单分类模型(CNN 示例)​

以 "MNIST 手写数字分类" 为例,搭建简单 CNN 模型(拓展实战,理解卷积层用法):

bash 复制代码
class SimpleCNN(nn.Module):
    def __init__(self, input_channels=1, num_classes=10):
        super(SimpleCNN, self).__init__()
        # 卷积层(提取空间特征)
        self.conv1 = nn.Conv2d(input_channels, 32, kernel_size=3, stride=1, padding=1)
        self.relu = nn.ReLU()
        self.pool = nn.MaxPool2d(kernel_size=2, stride=2)  # 下采样,减少参数
        self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1)
        # 全连接层(分类)
        self.fc1 = nn.Linear(64 * 7 * 7, 128)  # MNIST图片28×28,经过两次池化后7×7
        self.fc2 = nn.Linear(128, num_classes)

    def forward(self, x):
        # 卷积→激活→池化
        x = self.conv1(x)
        x = self.relu(x)
        x = self.pool(x)  # 输出:(batch_size, 32, 14, 14)
        # 第二次卷积→激活→池化
        x = self.conv2(x)
        x = self.relu(x)
        x = self.pool(x)  # 输出:(batch_size, 64, 7, 7)
        # 展平(卷积层输出→全连接层输入)
        x = x.view(-1, 64 * 7 * 7)  # 输出:(batch_size, 64*7*7)
        # 全连接层分类
        x = self.fc1(x)
        x = self.relu(x)
        output = self.fc2(x)  # 输出:(batch_size, 10)(10个类别概率)
        return output

# 实例化 CNN 模型
cnn_model = SimpleCNN(input_channels=1, num_classes=10)
print("CNN 模型结构:")
print(cnn_model)

# 验证输入输出(MNIST 图片形状:(batch_size, 1, 28, 28))
dummy_input = torch.randn(32, 1, 28, 28)  # 模拟32个MNIST样本
cnn_output = cnn_model(dummy_input)
print(f"\nCNN 输入形状:{dummy_input.shape}")
print(f"CNN 输出形状:{cnn_output.shape}")  # 输出:torch.Size([32, 10])

3. 模型参数与设备迁移​

bash 复制代码
# 查看模型参数(训练时需优化的权重/偏置)
print("模型参数列表:")
for name, param in model.named_parameters():
    print(f"参数名:{name},形状:{param.shape},是否需要梯度:{param.requires_grad}")

# 模型迁移到 GPU(加速训练)
if torch.cuda.is_available():
    model = model.cuda()  # 模型权重迁移到 GPU
    batch_x = batch_x.cuda()  # 输入数据也需迁移到 GPU
    model_output = model(batch_x)
    print(f"\nGPU 训练:模型设备={next(model.parameters()).device},输出设备={model_output.device}")

五、实战总结与后续拓展​

1. 核心要点回顾​

  • 张量:PyTorch 基础数据结构,支持 GPU 加速和自动求导,核心操作需掌握 "形状调整、设备迁移、自动求导";
  • DataLoader:批量加载数据的核心工具,需配合 Dataset 自定义数据集,预处理(标准化)是提升模型效果的关键;
  • 模型搭建:继承 nn.Module,重写 __init__(定义层)和 forward(前向传播),激活函数(ReLU)和池化层(CNN)是提升模型能力的重要组件。

2. 后续实战拓展​

  • 模型训练:结合损失函数(nn.MSELoss 回归 /nn.CrossEntropyLoss 分类)和优化器(torch.optim.Adam),实现完整训练循环;
  • 数据加载进阶:加载真实数据集(如 CSV 表格数据、图片数据),使用 torchvision.datasets 加载公开数据集(MNIST、CIFAR-10);
  • 模型保存与加载:训练完成后保存模型权重(torch.save(model.state_dict(), "model.pth")),后续复用训练结果。
相关推荐
handler011 小时前
进程状态流转的本质:Linux 内核队列与底层数据结构解密
linux·运维·c语言·数据结构·c++·笔记·学习
jinanwuhuaguo1 小时前
反熵共同体——OpenClaw的宇宙热力学本体论(第十七篇)
大数据·人工智能·安全·架构·kotlin·openclaw
Shan12051 小时前
大学计算机初学者之学习课程推荐
学习
新加坡内哥谈技术1 小时前
OpenAI 在冲刺首次公开募股(IPO)关键阶段所面临的增长放缓与战略分歧问题
人工智能
智慧物业老杨1 小时前
物业数智化转型实战:从单一服务到综合解决方案的技术落地路径
人工智能·算法·ai
tobias.b1 小时前
03安装人工智能基础软件
人工智能
网瘾新之助1 小时前
Claude Code 插件解密
人工智能
水如烟1 小时前
孤能子视角:意识孤能子,从创生到解耦
人工智能
风巽·剑染春水1 小时前
【World Models综述】理解世界还是预测未来?(ACM CS-2025)
人工智能·生成式ai·扩散模型·综述·智能体·世界模型