PyTorch深度学习——Anaconda和PyTorch安装
Pytorch深度学习-----数据模块Dataset类
Pytorch深度学习------TensorBoard的使用
Pytorch深度学习------Torchvision中Transforms的使用(ToTensor,Normalize,Resize ,Compose,RandomCrop)
Pytorch深度学习------torchvision中dataset数据集的使用(CIFAR10)
Pytorch深度学习-----DataLoader的用法
Pytorch深度学习-----神经网络的基本骨架-nn.Module的使用
Pytorch深度学习-----神经网络的卷积操作
Pytorch深度学习-----神经网络之卷积层用法详解
Pytorch深度学习-----神经网络之池化层用法详解及其最大池化的使用
Pytorch深度学习-----神经网络之非线性激活的使用(ReLu、Sigmoid)
Pytorch深度学习-----神经网络之线性层用法
Pytorch深度学习-----神经网络之Sequential的详细使用及实战详解
Pytorch深度学习-----损失函数(L1Loss、MSELoss、CrossEntropyLoss)
在PyTorch中,优化器(Optimizer)是用于更新神经网络参数的工具
。它根据计算得到的损失函数的梯度来调整模型的参数
,以最小化损失函数并改善模型的性能
。
即优化器是一种特定的机器学习算法
,通常用于在训练深度学习模型时调整权重和偏差
。是用于更新神经网络参数
以最小化某个损失函数的方法。
SGD(随机梯度下降)优化器: SGD是最基本的优化器之一,它使用负梯度来更新权重和偏差。
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
Adam(自适应矩估计)优化器: Adam是一种自适应学习率优化器,它结合了Momentum和RMSProp两种方法的优点。
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
RMSprop(均方根传播)优化器: 它使用比例常数来调整梯度的平方的指数移动平均值。
optimizer = torch.optim.RMSprop(model.parameters(), lr=learning_rate)
注意:在上述代码各个参数中,model.parameters()用于获取模型的可学习参数
,lr表示学习率(learning rate),即每次参数更新的步长
。
由上述可以知道,使用优化器的时候需要使用到torch.optim模块,而torch.optim模块的核心类是Optimizer,所有的优化算法都基于它来实现。一般来说,要使用torch.optim,需要完成以下几个步骤:
定义神经网络模型,并初始化模型参数。
选择合适的优化算法,并将模型的参数传递给优化器
选择合适的损失函数,用于评估模型性能。
在每个训练批次中,需要执行以下操作。
进行前向传播
。计算损失
。zero_grad()
方法清零之前的梯度。backward()
方法进行反向传播,计算梯度。step()
方法更新模型参数。下面根据步骤上面的各个步骤,写出如下的模型代码:
import torch
import torch.optim as optim
# Step 1: 定义模型
model = ...
# Step 2: 定义优化器
optimizer = optim.SGD(model.parameters(), lr=0.01)
# Step 3: 定义损失函数
criterion = ...
# Step 4: 训练循环
for inputs, labels in dataloader:
# 前向传播
outputs = model(inputs)
# 计算损失
loss = criterion(outputs, labels)
# 清零梯度
optimizer.zero_grad()
# 反向传播
loss.backward()
# 更新参数
optimizer.step()
解析:
在上述模型代码中,我们使用optim.SGD作为优化器,学习率为0.01。可以根据需求选择其他优化器,例如optim.Adam、optim.RMSprop等。最后,记得根据具体任务选择适合的损失函数,例如交叉熵损失函数torch.nn.CrossEntropyLoss、均方误差损失函数torch.nn.MSELoss等。
以CIFAR10数据集为例,选取交叉熵函数为损失函数(torch.nn.CrossEntropyLoss),选择SGD优化器(torch.optim.SGD()),搭建神经网络,并计算其损失值,用优化器优化各个参数,使其朝梯度下降的方向调整。
代码如下:
import torch
import torch.optim as optim
import torchvision
from torch.utils.data import DataLoader
# 准备数据集
dataset = torchvision.datasets.CIFAR10(root="dataset", train=False, transform=torchvision.transforms.ToTensor(),download=True)
# 加载器
dataloader = DataLoader(dataset,batch_size=1)
# 搭建自己的神经网络模型
class Lgl(torch.nn.Module):
def __init__(self):
super(Lgl, self).__init__()
self.seq = torch.nn.Sequential(
torch.nn.Conv2d(in_channels=3, out_channels=32, kernel_size=5, padding=2),
torch.nn.MaxPool2d(kernel_size=2),
torch.nn.Conv2d(in_channels=32, out_channels=32, kernel_size=5, padding=2),
torch.nn.MaxPool2d(kernel_size=2),
torch.nn.Conv2d(in_channels=32, out_channels=64, kernel_size=5, padding=2),
torch.nn.MaxPool2d(kernel_size=2),
torch.nn.Flatten(),
torch.nn.Linear(1024, 64),
torch.nn.Linear(64, 10)
)
def forward(self, x):
x = self.seq(x)
return x
# Step 1: 定义模型
model = Lgl()
# Step 2: 定义优化器
optimizer = optim.SGD(model.parameters(), lr=0.01)
# Step 3: 定义损失函数
criterion = torch.nn.CrossEntropyLoss()
# Step 4: 训练循环
for inputs, labels in dataloader:
# 前向传播
outputs = model(inputs)
# 计算损失
loss = criterion(outputs, labels)
# 清零梯度
optimizer.zero_grad()
# 反向传播
loss.backward()
# 更新参数
optimizer.step()
# 打印经过优化器后的结果
print(loss)
打印结果:
tensor(2.3362, grad_fn=<NllLossBackward0>)
tensor(2.2323, grad_fn=<NllLossBackward0>)
tensor(2.1653, grad_fn=<NllLossBackward0>)
tensor(2.2348, grad_fn=<NllLossBackward0>)
tensor(2.2929, grad_fn=<NllLossBackward0>)
tensor(2.2374, grad_fn=<NllLossBackward0>)
tensor(2.4351, grad_fn=<NllLossBackward0>)
......
从上述可以知道,梯度下降并不明显,因为我们只进行一次循环优化。
下面进行多次优化训练,再观察结果。
代码如下:
import torch
import torch.optim as optim
import torchvision
from torch.utils.data import DataLoader
# 准备数据集
dataset = torchvision.datasets.CIFAR10(root="dataset", train=False, transform=torchvision.transforms.ToTensor(),download=True)
# 加载器
dataloader = DataLoader(dataset,batch_size=1)
# 搭建自己的神经网络模型
class Lgl(torch.nn.Module):
def __init__(self):
super(Lgl, self).__init__()
self.seq = torch.nn.Sequential(
torch.nn.Conv2d(in_channels=3, out_channels=32, kernel_size=5, padding=2),
torch.nn.MaxPool2d(kernel_size=2),
torch.nn.Conv2d(in_channels=32, out_channels=32, kernel_size=5, padding=2),
torch.nn.MaxPool2d(kernel_size=2),
torch.nn.Conv2d(in_channels=32, out_channels=64, kernel_size=5, padding=2),
torch.nn.MaxPool2d(kernel_size=2),
torch.nn.Flatten(),
torch.nn.Linear(1024, 64),
torch.nn.Linear(64, 10)
)
def forward(self, x):
x = self.seq(x)
return x
# Step 1: 定义模型
model = Lgl()
# Step 2: 定义优化器
optimizer = optim.SGD(model.parameters(), lr=0.01)
# Step 3: 定义损失函数
criterion = torch.nn.CrossEntropyLoss()
# Step 4: 训练循环
for i in range(20):
end_loos = 0.0
for inputs, labels in dataloader:
# 前向传播
outputs = model(inputs)
# 计算损失
loss = criterion(outputs, labels)
# 清零梯度
optimizer.zero_grad()
# 反向传播
loss.backward()
# 更新参数
optimizer.step()
# 打印经过优化器后的结果
end_loos = end_loos + loss
print(loss)
结果如下:
tensor(0.8429, grad_fn=<NllLossBackward0>)
tensor(0.2361, grad_fn=<NllLossBackward0>)
tensor(0.0777, grad_fn=<NllLossBackward0>)
tensor(0.7095, grad_fn=<NllLossBackward0>)
......
可见多次训练后下降效果比之前较明显。
声明:本篇文章,未经许可,谢绝转载。