损失函数与反向传播 小土堆pytorch记录
视频代码
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(), # 转换为Tensordownload=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(), # 转换为Tensordownload=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.0for data in dataloader:imgs, targets = dataoutputs = test_net(imgs)result_loss = loss(outputs, targets) # 计算损失:比较预测输出(outputs)和真实标签(targets)optim.zero_grad()result_loss.backward() # 反向传播:计算梯度并存储在参数中optim.step()running_loss = running_loss + result_lossprint(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.0correct = 0total = 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.0correct = 0total = 0# 更新学习率scheduler.step()# 每个epoch结束后打印平均损失和准确率epoch_loss = running_loss / len(train_dataloader)epoch_acc = 100 * correct / totalprint(f'Epoch [{epoch+1}/20] completed, Loss: {epoch_loss:.4f}, Acc: {epoch_acc:.2f}%')print("训练完成!")