PyTorch 入门学习笔记(实战篇)二

PyTorch实战:基于新冠数据的阳性病例占比预测

大家好,今天给大家带来一个超实用的PyTorch实战项目------利用美国新冠调查数据预测阳性病例占比。整个流程从数据加载、预处理,到模型搭建、训练,全程代码+详细解析,新手也能轻松上手,话不多说,开整!

一、任务背景与数据集解析

1. 任务目标

本次任务是一个典型的回归预测问题:使用美国特定州过去5天的新冠调查数据,预测未来5天的新增新冠检测阳性病例占比。

2. 数据集详情

先给大家看一下我整理的数据集核心信息,这是后续代码的基础:

数据格式:CSV文件存储,每行对应一个样本

特征维度:共117维有效特征,包含37个州的独热编码、16类特征的5天数据

标签信息:每行最后一列是预测目标------阳性病例占比

样本规模:训练集共2699个样本,特征维度 (2699, 117),标签维度 (2699,)

二、完整代码实现与逐行精讲

1. 环境与库导入

第一步先导入需要的库,都是深度学习的老朋友了,注释里给大家讲清楚用途:

python 复制代码
# 数据处理三剑客之两剑客:Pandas加载CSV,NumPy处理数值计算
import pandas as pd
import numpy as np
# PyTorch核心库:构建模型、处理张量
import torch
import torch.nn as nn
from torch.utils.data import Dataset, DataLoader
# 优化器与可视化:Adam优化模型参数,Matplotlib画训练曲线
from torch.optim import Adam
import matplotlib.pyplot as plt

2. 数据加载与预处理

数据是模型的血液,这一步的核心是加载数据→分离特征标签→转换为张量,直接上代码:

python 复制代码
def load_and_preprocess_data(csv_path):
    # 1. 加载CSV数据,删除全为NaN的无效列
    train_data = pd.read_csv(csv_path).dropna(axis=1, how='all')
    # 2. 分离特征和标签:特征取前117列,标签取最后1列
    X_train = train_data.iloc[:, :-1].values  # 特征数组 (2699, 117)
    y_train = train_data.iloc[:, -1].values    # 标签数组 (2699,)
    # 3. 转换为PyTorch浮点型张量,标签升维适配模型输出
    X_train = torch.tensor(X_train, dtype=torch.float32)
    y_train = torch.tensor(y_train, dtype=torch.float32).unsqueeze(1)  # 升维为(2699,1)
    return X_train, y_train

# 调用函数(记得替换成你的数据集路径!)
X_train, y_train = load_and_preprocess_data("covid-train.csv")
# 打印维度验证:确保数据处理正确
print("特征维度:", X_train.shape)  # 预期输出 (2699, 117)
print("标签维度:", y_train.shape)  # 预期输出 (2699, 1)

关键解析:

dropna(axis=1, how='all'):清理无效列,避免脏数据干扰模型训练

iloc[:, :-1]:按列索引切片,精准分离特征和标签

unsqueeze(1):给标签升维,因为模型输出是二维张量 (batch_size, 1),维度匹配才能计算损失

3. 自定义Dataset类

PyTorch加载数据的标准操作是自定义Dataset,必须实现三个核心方法,代码如下:

python 复制代码
class CovidDataset(Dataset):
	def _init_(self,features,labels=None):
	if y in None:
		self.labels = labels
	else:
		self = torch.FloatTensor(labels)
	self.features = torch.FloatTensor(features)
    
    def __getitem__(self, idx):
        # 按索引取样本:返回单个样本的特征和标签
        return self.features[idx], self.labels[idx]
    
    def __len__(self):
        # 返回数据集总长度:供DataLoader计算批次
        return len(self.features)

# 实例化数据集
train_dataset = CovidDataset(X_train, y_train)

关键解析:
init :接收特征和标签张量,完成初始化
getitem :DataLoader加载数据时会调用这个方法,按索引获取样本
len:告诉DataLoader数据集有多少个样本,是批量加载的基础

4. 构建DataLoader

有了Dataset,下一步就是用DataLoader实现批量加载+数据打乱,提升训练效率:

python 复制代码
# 超参数:批次大小,可根据显存调整,常用32/64/128
batch_size = 32
train_loader = DataLoader(
    dataset=train_dataset,
    batch_size=batch_size,
    shuffle=True  # 训练时打乱数据,避免模型学顺序
)

# 验证DataLoader是否正常工作
for batch_X, batch_y in train_loader:
    print("批次特征维度:", batch_X.shape)  # 预期输出 (32, 117)
    print("批次标签维度:", batch_y.shape)  # 预期输出 (32, 1)
    break  # 只看第一个批次就够了

关键解析:

batch_size=32:每次训练喂给模型32个样本,平衡训练速度和显存占用

shuffle=True:训练集必须打乱,否则模型会学习到数据的顺序规律,泛化能力变差

5. 定义神经网络模型

本次任务是回归预测,我们搭建一个简单的全连接神经网络,代码如下:

python 复制代码
class CovidPredictor(nn.Module):
    def __init__(self, input_dim=117, hidden_dim=64, output_dim=1):
        super(CovidPredictor, self).__init__()
        # 定义三层全连接层
        self.fc1 = nn.Linear(input_dim, hidden_dim)  # 输入层→隐藏层
        self.fc2 = nn.Linear(hidden_dim, hidden_dim//2)  # 隐藏层→次隐藏层
        self.fc3 = nn.Linear(hidden_dim//2, output_dim)  # 次隐藏层→输出层
        # 激活函数:ReLU解决线性模型表达能力不足的问题
        self.relu = nn.ReLU()
    
    def forward(self, x):
        # 前向传播:数据流过网络的路径
        x = self.relu(self.fc1(x))  # 第一层+激活
        x = self.relu(self.fc2(x))  # 第二层+激活
        x = self.fc3(x)  # 输出层无激活!回归任务直接输出数值
        return x

# 实例化模型
model = CovidPredictor()
print("模型结构:")
print(model)

关键解析:

输入维度input_dim=117:对应我们的特征维度

隐藏层设计:64→32,逐层压缩特征,提取核心信息

输出层output_dim=1:对应预测的阳性病例占比,回归任务输出层不加激活函数

6. 模型训练与可视化

万事俱备,最后一步就是训练模型了!核心步骤是定义损失函数+优化器+训练循环:

python 复制代码
# 1. 定义损失函数:回归任务用均方误差MSE
criterion = nn.MSELoss()
# 2. 定义优化器:Adam优化器,学习率1e-3是常用值
optimizer = Adam(model.parameters(), lr=1e-3)
# 3. 训练超参数
epochs = 50  # 训练轮数
train_losses = []  # 存储每轮损失,用于可视化

# 训练循环
for epoch in range(epochs):
    model.train()  # 切换到训练模式
    epoch_loss = 0.0  # 累计本轮损失
    
    for batch_X, batch_y in train_loader:
        # 梯度清零:必须操作,否则梯度会累加
        optimizer.zero_grad()
        # 前向传播:模型预测结果
        outputs = model(batch_X)
        # 计算损失:预测值和真实值的差距
        loss = criterion(outputs, batch_y)
        # 反向传播:计算梯度
        loss.backward()
        # 优化器更新参数:梯度下降
        optimizer.step()
        # 累计损失:乘以批次大小,避免批次影响
        epoch_loss += loss.item() * batch_X.size(0)
    
    # 计算本轮平均损失
    avg_loss = epoch_loss / len(train_dataset)
    train_losses.append(avg_loss)
    
    # 每5轮打印一次损失,方便观察训练进度
    if (epoch+1) % 5 == 0:
        print(f"Epoch [{epoch+1}/{epochs}], Loss: {avg_loss:.4f}")

# 可视化训练损失曲线
plt.figure(figsize=(10, 6))
plt.plot(train_losses, label="Training Loss", color="#1f77b4")
plt.xlabel("Epochs", fontsize=12)
plt.ylabel("MSE Loss", fontsize=12)
plt.title("Training Loss Curve", fontsize=14)
plt.legend()
plt.grid(True, linestyle="--", alpha=0.7)
plt.show()

关键解析:

损失函数nn.MSELoss():回归任务的标配,计算预测值和真实值的均方误差

优化器Adam:比传统SGD收敛更快,学习率lr=1e-3是经验值
训练循环四步走:梯度清零→前向传播→反向传播→参数更新,这是PyTorch训练的固定流程

损失可视化:通过损失曲线可以判断模型是否收敛,曲线下降并趋于平稳就是训练有效的标志。

三、总结

本文完整实现了基于PyTorch的新冠阳性病例占比预测任务,从数据预处理到模型训练的每一步都有详细解析。这个项目不仅适合新手入门PyTorch,还可以在此基础上拓展优化,形成更深入的技术博客。

四、数据集

相关推荐
HuDie3409 小时前
因果推断与AB实验
笔记
小当家.1059 小时前
JVM八股详解(上部):核心原理与内存管理
java·jvm·学习·面试
逑之9 小时前
C语言笔记8:操作符
c语言·开发语言·笔记
IRevers9 小时前
【目标检测】深度学习目标检测损失函数总结
人工智能·pytorch·深度学习·目标检测·计算机视觉
知识分享小能手9 小时前
Ubuntu入门学习教程,从入门到精通,Ubuntu 22.04 中的大数据 —— 知识点详解 (24)
大数据·学习·ubuntu
幽络源小助理9 小时前
逆向工程系统学习资源图谱(2026):从 Windows 内核、安卓安全到游戏协议分析的全栈教程清单
学习·安全·游戏·逆向工程
Larry_Yanan9 小时前
Qt多进程(九)命名管道FIFO
开发语言·c++·qt·学习·ui
ybb_ymm9 小时前
尝试新版idea及免费学习使用
java·学习·intellij-idea
优雅的潮叭9 小时前
c++ 学习笔记之 模板元编程
c++·笔记·学习