第四十天打卡

@浙大疏锦行

训练和测试的规范写法

知识点回顾:

1.彩色和灰度图片测试和训练的规范写法:封装在函数中

2.展平操作:除第一个维度batchsize外全部展平

3.dropout操作:训练阶段随机丢弃神经元,测试阶段eval模式关闭dropout

python 复制代码
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, Dataset
from torchvision import transforms, datasets
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings("ignore")
torch.manual_seed(42)
device = torch.device("cuda"if torch.cuda.is_available() else"cpu")
print(device)
 
python 复制代码
#1预处理
transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.1307, ), (0.3081,))
]
)
#2加载数据集
train_dataset = datasets.MNIST(
    root="./data",
    train=True,
    download=True,
    transform=transform
)
test_dataset = datasets.MNIST(
    root="./data",
    train=False,
    download=True,
    transform=transform
)
#3创建数据加载器
batch_size = 64
train_loader = torch.utils.data.DataLoader(
    dataset=train_dataset,
    batch_size=batch_size,
    shuffle=True
)
test_loader = torch.utils.data.DataLoader(
    dataset=test_dataset,
    batch_size=batch_size,
    shuffle=False
)
#4定义模型
class MLP(nn.Module):
    def __init__(self):
        super(MLP, self).__init__()
        self.flatten = nn.Flatten()
        self.fc1 = nn.Linear(28*28, 128)
        self.relu = nn.ReLU()
        self.fc2 = nn.Linear(128, 10)
    
    def forward(self, x):
        x = self.flatten(x)
        x = self.fc1(x)
        x = self.relu(x)
        x = self.fc2(x)
        return x
model = MLP()
model = model.to(device)
 
#定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
python 复制代码
#5训练模型(记录每个iteration的loss)
def train(model, train_loader, test_loader, criterion, optimizer, epochs, device):
    model.train() #设置为训练模式
 
    #记录损失
    all_iter_losses = []   #记录所有batch的loss
    iter_indices = [] #记录每个iteration的索引
 
    for epoch in range(epochs):
        running_loss = 0.0 #记录每个epoch的loss
        correct = 0 #记录每个epoch的correct
        total =0 #记录每个epoch的total
 
        for batch_idx, (data, target) in enumerate(train_loader):
            data, target = data.to(device), target.to(device)
 
            optimizer.zero_grad()#梯度清零
            output = model(data)
            loss = criterion(output, target)
            loss.backward()
            optimizer.step()
 
            #记录当前iteration的损失
            iter_loss = loss.item()
            all_iter_losses.append(iter_loss)
            iter_indices.append(epoch * len(train_loader) + batch_idx + 1)
 
            #统计准确率和损失
            running_loss += loss.item()
            #`_`来表示我们不关心第一个返回值(即最大值),只关心第二个返回值(即最大值的索引),这个索引就是模型预测的类别。
            _, predicted = torch.max(output.data, 1)
            total += target.size(0)
            correct += predicted.eq(target).sum().item()
 
            #每100个batch打印一次训练状态
            if (batch_idx + 1) % 100 == 0:
                print(f"Epoch:{epoch + 1}/{epochs}|Batch:{batch_idx + 1}/{len(train_loader)}",
                      f"|单batch损失:{iter_loss:.4f}|累计平均损失:{running_loss/(batch_idx + 1):.4f}|")
        
        #测试,打印结果
        epoch_train_loss = running_loss / len(train_loader)
        epoch_train_acc = 100. * correct / total
        epoch_test_loss, epoch_test_acc = test(model, test_loader, criterion,device)
        print(f"Epoch{epoch + 1}/{epochs}完成|训练准确率:{epoch_train_acc:.2f}|测试准确率:{epoch_test_acc:.2f}")
 
    #绘制所有iteration损失函数
    plot_iter_losses(all_iter_losses, iter_indices)
 
    return epoch_test_acc
 
python 复制代码
#6测试模型
def test(model, test_loader, criterion, device):
    model.eval() # 设置为评估模式
    test_loss = 0
    correct = 0
    total = 0
    with torch.no_grad():#测试时关闭梯度计算
        for data, target in test_loader:
            data, target = data.to(device), target.to(device)
            output = model(data)
            test_loss += criterion(output, target).item()
            _, predicted = output.max(1)
            total += target.size(0)
            correct += predicted.eq(target).sum().item()
    avg_loss = test_loss / len(test_loader)
    accuracy = 100. * correct / total
    return avg_loss, accuracy
python 复制代码
#7绘制损失曲线
def plot_iter_losses(losses, indices):
    plt.figure(figsize=(10, 5))
    plt.plot(indices, losses, 'b-', alpha=0.7, label='Iteration Loss')
    plt.xlabel('Iteration(Batch)序号')
    plt.ylabel('Loss')
    plt.title('Iteration Loss Curve')
    plt.legend()
    plt.grid(True)
    plt.tight_layout()
    plt.show()
python 复制代码
#8执行训练和测试(epochs=2 验证结果)
epochs = 2
print("开始训练")
final_accuracy = train(model, train_loader, test_loader, criterion, optimizer, epochs, device)
print(f"训练结束,最终准确率为{final_accuracy:.4f}")    
相关推荐
学测绘的小杨5 小时前
CompassFusion:一个从 GNSS 到 GNSS/INS 组合导航的独立工程包
python
武子康9 小时前
调查研究-191 SenseVoice 不只是 ASR:把语音从“转文字“升级成“理解状态“
人工智能·深度学习·openai
zzzzzz31012 小时前
当产品经理说这个很简单:我用Python自动化处理奇葩需求的实战指南
python·pycharm·产品经理
雪隐12 小时前
个人电脑玩AI-06让5060 Ti给你打工——不光能画画,Qwen3-TTS还能学人说话,连我老板都信了!
人工智能·后端·python
兵慌码乱1 天前
面向桌面端的资产管理系统分层架构设计与核心模块实现
python·系统架构·sqlite·pyqt5·数据库设计·桌面应用开发·mvc架构
hboot1 天前
AI工程师第三课 - 机器学习基础
python·scikit-learn·kaggle
顾林海1 天前
Agent入门阶段-编程基础-Python:流程控制
python·agent·ai编程
呱呱复呱呱1 天前
Django CBV 源码解读:一个请求是怎么找到你的 get() 方法的
python·django
曲幽2 天前
刚部署的 LibreTranslate 频频翻车?我掏出了 20 年前的 StarDict 词典,用 FastAPI 搭了个本地词典翻译 API
python·fastapi·web·translate·goldendict·libretranslate·stardict·pystardict