目录
一、损失函数
作用:
🟢计算输出值和目标的差距
🟢为更新输出、调整参数提供依据
理论阶段
L1Loss :输入任意维度,输出相同维度
MSELoss:均方误差损失函数
CrossEntropyLoss:交叉熵,训练分类问题时使用,公式如下
实战阶段
首先加载数据集,构建神经网络
import torch
import torchvision.datasets
from torch.nn import Conv2d, MaxPool2d, Linear, Flatten
from torch import nn
from torch.utils.data import DataLoader
dataset = torchvision.datasets.CIFAR10(root='./dataset', train=False, transform=torchvision.transforms.ToTensor(), download=True)
loader = DataLoader(dataset, batch_size=1)
class deep_nn(nn.Module):
def __init__(self):
super().__init__()
# 第一个卷积层输入通道为3,输出通道为32,卷积核5×5,计算得padding=2
self.conv1 = Conv2d(3, 32, 5, padding=2)
# 池化层不改变通道数,默认不填充
self.maxpool1 = MaxPool2d(2)
self.conv2 = Conv2d(32, 32, 5, padding=2)
self.maxpool2 = MaxPool2d(2)
self.conv3 = Conv2d(32, 64, 5, padding=2)
self.maxpool3 = MaxPool2d(2)
self.flatten = Flatten()
self.liner1 = Linear(1024, 64)
self.liner2 = Linear(64, 10)
def forward(self, x):
x = self.conv1(x)
x = self.maxpool1(x)
x = self.conv2(x)
x = self.maxpool2(x)
x = self.conv3(x)
x = self.maxpool3(x)
x = self.flatten(x)
x = self.liner1(x)
x = self.liner2(x)
return x
Mynn = deep_nn()
for data in loader:
imgs, targets = data
output = Mynn(imgs)
print(output)
print(targets)
接着定义损失函数
Myloss = CrossEntropyLoss()
for data in loader:
imgs, targets = data
output = Mynn(imgs)
res_loss = Myloss(output, targets)
print(res_loss)
运用损失函数获得的梯度进行反向传播
res_loss.backward()
二、优化器
作用:利用损失函数所获得的梯度对各个神经节点进行调参优化
官方文档在torch.opim中,首先先构建一个优化器,传入模型和学习速率,接着调用step()方法进行调参,在每一个batch-size训练过程中,需将上一个batch-size训练的梯度参数进行清0.
利用第一节中的损失函数加入优化器,训练10轮
import torch
import torchvision.datasets
from torch.nn import Conv2d, MaxPool2d, Linear, Flatten, CrossEntropyLoss
from torch import nn
from torch.utils.data import DataLoader
dataset = torchvision.datasets.CIFAR10(root='./dataset', train=False, transform=torchvision.transforms.ToTensor(), download=True)
loader = DataLoader(dataset, batch_size=64)
class deep_nn(nn.Module):
def __init__(self):
super().__init__()
# 第一个卷积层输入通道为3,输出通道为32,卷积核5×5,计算得padding=2
self.conv1 = Conv2d(3, 32, 5, padding=2)
# 池化层不改变通道数,默认不填充
self.maxpool1 = MaxPool2d(2)
self.conv2 = Conv2d(32, 32, 5, padding=2)
self.maxpool2 = MaxPool2d(2)
self.conv3 = Conv2d(32, 64, 5, padding=2)
self.maxpool3 = MaxPool2d(2)
self.flatten = Flatten()
self.liner1 = Linear(1024, 64)
self.liner2 = Linear(64, 10)
def forward(self, x):
x = self.conv1(x)
x = self.maxpool1(x)
x = self.conv2(x)
x = self.maxpool2(x)
x = self.conv3(x)
x = self.maxpool3(x)
x = self.flatten(x)
x = self.liner1(x)
x = self.liner2(x)
return x
Mynn = deep_nn()
Myloss = CrossEntropyLoss()
# 构建优化器,学习速率设置为0.01,太大模型不稳定,太小模型训练过慢
optim = torch.optim.SGD(Mynn.parameters(), lr=0.01)
for epoch in range(10):
total_loss = 0
for data in loader:
imgs, targets = data
output = Mynn(imgs)
res_loss = Myloss(output, targets)
# 梯度调为0
optim.zero_grad()
# 获取梯度
res_loss.backward()
# 进行调优
optim.step()
total_loss += res_loss
print(total_loss)
可以看出损失在减小