损失函数与反向传播 小土堆pytorch记录

发布于:2025-08-19 ⋅ 阅读:(22) ⋅ 点赞:(0)

视频代码

import torch
import torchvision
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
from torch.utils.data import DataLoader

# 加载CIFAR10测试集
dataset = torchvision.datasets.CIFAR10(
    root="./P_10_dataset",
    train=False,  # 使用测试集
    transform=torchvision.transforms.ToTensor(),  # 转换为Tensor
    download=True
)

# 创建数据加载器,batch_size=1表示每次处理一个样本
dataloader = DataLoader(dataset, batch_size=1, drop_last=True)

# 定义神经网络
class Test_net(nn.Module):
    def __init__(self):
        super(Test_net, self).__init__()
        self.model_1 = Sequential(
            Conv2d(3, 32, 5, padding=2),  # 输入3通道,输出32通道,5x5卷积
            MaxPool2d(2),  # 2x2最大池化
            Conv2d(32, 32, 5, padding=2),
            MaxPool2d(2),
            Conv2d(32, 64, 5, padding=2),
            MaxPool2d(2),
            Flatten(),  # 展平多维特征图
            Linear(1024, 64),  # 全连接层(1024输入,64输出)
            Linear(64, 10)  # 输出层(64输入,10输出对应10个类别)
        )

    def forward(self, x):
        return self.model_1(x)  # 顺序通过所有层

# 创建交叉熵损失函数实例
loss = nn.CrossEntropyLoss()

# 创建网络实例
test_net = Test_net()

# 遍历数据集
for data in dataloader:
    imgs, targets = data  # 解包数据
    outputs = test_net(imgs)  # 前向传播,获取预测输出
    
    # 计算损失:比较预测输出(outputs)和真实标签(targets)
    result_loss = loss(outputs, targets)
    
    # 反向传播:计算梯度并存储在参数中
    result_loss.backward()
    
    print("ok")  # 表示完成一次迭代

算是前面的一个综合

后续优化器章节也是

视频代码

import torch
import torchvision
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
from torch.utils.data import DataLoader


# 加载CIFAR10数据集
dataset = torchvision.datasets.CIFAR10(root="./P_10_dataset",
                                         train=True,
                                         transform=torchvision.transforms.ToTensor(),  # 转换为Tensor
                                         download=True)
dataloader = DataLoader(dataset, batch_size=64, shuffle=True, drop_last=True)


class Test_net(nn.Module):
    def __init__(self):
        super(Test_net, self).__init__()
        self.model_1 = Sequential(
            # 第一层卷积:输入通道3(RGB),输出通道32,5x5卷积核,填充2保持尺寸
            Conv2d(3, 32, 5, padding=2),
            # 2x2最大池化,步长2(默认等于池化核大小)
            MaxPool2d(2),
            # 第二层卷积:输入32通道,输出32通道
            Conv2d(32, 32, 5, padding=2),
            # 再次池化
            MaxPool2d(2),
            # 第三层卷积:输入32通道,输出64通道
            Conv2d(32, 64, 5, padding=2),
            # 第三次池化
            MaxPool2d(2),
            # 展平层:将多维特征图转换为一维向量
            Flatten(),
            # 全连接层:输入1024维,输出64维
            Linear(1024, 64),
            # 输出层:输入64维,输出10维(对应CIFAR-10的10个类别)
            Linear(64, 10)
        )

    def forward(self, x):  # 顺序通过所有层
        x = self.model_1(x)
        return x

# 创建交叉熵损失函数实例
loss = nn.CrossEntropyLoss()
test_net = Test_net()

optim = torch.optim.SGD(test_net.parameters(), lr=0.001)

for epoch in range(20):
    running_loss = 0.0
    for data in dataloader:
        imgs, targets = data
        

        outputs = test_net(imgs)
        result_loss = loss(outputs, targets)  # 计算损失:比较预测输出(outputs)和真实标签(targets)
        optim.zero_grad()
        result_loss.backward()  # 反向传播:计算梯度并存储在参数中
        optim.step()
        running_loss = running_loss + result_loss

    print(running_loss)

按照土堆视频的敲了一遍,笔记本带不起来,换了个写法

import torch
import torchvision
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
from torch.utils.data import DataLoader

# 加载CIFAR10数据集 - 使用训练集
train_dataset = torchvision.datasets.CIFAR10(
    root="./P_10_dataset",
    train=True,  # 使用训练集
    transform=torchvision.transforms.ToTensor(),
    download=True
)

# 创建训练数据加载器 - 适当批量大小
train_dataloader = DataLoader(train_dataset, batch_size=64, shuffle=True, drop_last=True)

# 定义神经网络
class TestNet(nn.Module):
    def __init__(self):
        super(TestNet, self).__init__()
        self.model = Sequential(
            Conv2d(3, 32, 5, padding=2),
            nn.ReLU(),  # 添加激活函数
            MaxPool2d(2),
            Conv2d(32, 32, 5, padding=2),
            nn.ReLU(),  # 添加激活函数
            MaxPool2d(2),
            Conv2d(32, 64, 5, padding=2),
            nn.ReLU(),  # 添加激活函数
            MaxPool2d(2),
            Flatten(),
            Linear(1024, 64),
            nn.ReLU(),  # 添加激活函数
            Linear(64, 10)
        )

    def forward(self, x):
        return self.model(x)

# 创建模型、损失函数和优化器
model = TestNet()
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.001)  # 降低学习率

# 添加学习率调度器
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=5, gamma=0.1)

# 训练循环
for epoch in range(20):
    running_loss = 0.0
    correct = 0
    total = 0
    
    # 训练阶段
    model.train()  # 设置为训练模式
    for i, (imgs, targets) in enumerate(train_dataloader):
        optimizer.zero_grad()  # 清空梯度
        
        outputs = model(imgs)  # 前向传播
        loss = criterion(outputs, targets)  # 计算损失
        loss.backward()  # 反向传播
        
        optimizer.step()  # 更新参数
        
        # 累加损失(使用.item()避免计算图累积)
        running_loss += loss.item()
        
        # 计算准确率
        _, predicted = torch.max(outputs.data, 1)
        total += targets.size(0)
        correct += (predicted == targets).sum().item()
        
        # 每100批次打印一次进度
        if i % 100 == 99:
            print(f'Epoch [{epoch+1}/20], Batch [{i+1}/{len(train_dataloader)}], '
                  f'Loss: {running_loss/100:.4f}, Acc: {100*correct/total:.2f}%')
            running_loss = 0.0
            correct = 0
            total = 0
    
    # 更新学习率
    scheduler.step()
    
    # 每个epoch结束后打印平均损失和准确率
    epoch_loss = running_loss / len(train_dataloader)
    epoch_acc = 100 * correct / total
    print(f'Epoch [{epoch+1}/20] completed, Loss: {epoch_loss:.4f}, Acc: {epoch_acc:.2f}%')

print("训练完成!")


网站公告

今日签到

点亮在社区的每一天
去签到