torch.optim优化算法理解之optim.Adam()解读

下面是对于“torch.optim优化算法理解之optim.Adam()解读”的完整攻略。

1. 优化算法概述

在神经网络训练的过程中,我们需要选择一个好的优化算法来更新模型中的参数,这个过程就是优化算法。优化算法可以通过最小化损失函数来更新参数,以便更好地拟合数据。

目前常用的优化算法有SGD、Adam、RMSprop等,每个算法都有自己的优缺点,选用不同的算法会对训练效果产生不同的影响。

2. Adam算法介绍

Adam算法是一种自适应优化算法,可以根据每个参数的历史梯度和动量对学习率进行自适应调整,同时避免了梯度下降中的局部最小值问题。

Adam算法的更新公式如下:

$v_t=\beta_1v_{t-1}+(1-\beta_1)g_t$

$s_t=\beta_2s_{t-1}+(1-\beta_2)g_t^2$

$\hat{v}_t=\frac{v_t}{1-\beta_1^t}$

$\hat{s}_t=\frac{s_t}{1-\beta_2^t}$

$\theta_{t+1}=\theta_t-\frac{\alpha\hat{v}_t}{\sqrt{\hat{s}_t}+\epsilon}$

其中,$g_t$为梯度,$\theta_t$为当前参数,$\alpha$为学习率,$\beta_1$和$\beta_2$为两个可调参数,$v_t$和$s_t$是梯度的一阶矩估计和二阶矩估计,通过对这两个估计的校正可以减小偏差,防止梯度估计的不准确。$\epsilon$是为了防止分母为0而添加的一个极小常数。

3. optim.Adam()函数用法

在Pytorch中,可以使用torch.optim中的Adam函数来实现Adam算法的优化器。Adam函数的定义如下:

torch.optim.Adam(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=0, amsgrad=False)

其中,params是需要优化的参数,lr为学习率,betas是计算一阶和二阶矩估计的指数衰减率,eps是分母中的极小常数,用于避免除数为0的情况,weight_decay是L2正则化项的权重,amsgrad是一种变体Adam算法,可以减小训练过程中的波动。

4. 案例说明

在下面的两个案例中,我们将使用optim.Adam()来优化两个不同的模型。

案例1:手写数字识别

在这个案例中,我们将使用Pytorch内置的手写数字数据集来训练一个简单的卷积神经网络。我们的目标是优化模型的准确率。

import torch
import torch.nn as nn
import torch.optim as optim
import torchvision.datasets as datasets
import torchvision.transforms as transforms

# 定义模型
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, 10, kernel_size=5)
        self.conv2 = nn.Conv2d(10, 20, kernel_size=5)
        self.dropout = nn.Dropout()
        self.fc1 = nn.Linear(320, 50)
        self.fc2 = nn.Linear(50, 10)

    def forward(self, x):
        x = nn.functional.relu(nn.functional.max_pool2d(self.conv1(x), 2))
        x = nn.functional.relu(nn.functional.max_pool2d(self.dropout(self.conv2(x)), 2))
        x = x.view(-1, 320)
        x = nn.functional.relu(self.fc1(x))
        x = self.fc2(x)
        return nn.functional.log_softmax(x, dim=1)

# 数据预处理
train_transforms = transforms.Compose([transforms.ToTensor(),
                                       transforms.Normalize((0.1307,), (0.3081,))])

# 加载数据集
train_dataset = datasets.MNIST(root='./data', train=True, transform=train_transforms, download=True)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True)

# 设置优化器和损失函数
model = Net()
optimizer = optim.Adam(model.parameters(), lr=0.001)
criterion = nn.NLLLoss()

# 训练模型
for epoch in range(10):
    running_loss = 0.0
    for i, data in enumerate(train_loader):
        inputs, labels = data
        optimizer.zero_grad()

        outputs = model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        running_loss += loss.item()
        if i % 100 == 99:    
            print('[%d, %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss / 100))
            running_loss = 0.0

在上面的代码中,我们定义了一个简单的卷积神经网络,使用Adam优化器进行模型训练。最终的结果可以达到95%左右的准确率。

案例2:LSTM情感分析

在这个案例中,我们使用LSTM对IMDb情感分析数据集进行分类,从而比较SGD和Adam两种优化算法的差异。

import torch
import torch.nn as nn
import torch.optim as optim
import torchtext.datasets as datasets
import torchtext.data as data

# 定义LSTM模型
class LSTM(nn.Module):
    def __init__(self, input_dim, embedding_dim, hidden_dim, output_dim):
        super().__init__()

        self.embedding = nn.Embedding(input_dim, embedding_dim)
        self.rnn = nn.LSTM(embedding_dim, hidden_dim, num_layers=2, bidirectional=True)
        self.fc = nn.Linear(hidden_dim * 2, output_dim)

    def forward(self, text):
        # text: [sent len, batch size]
        embedded = self.embedding(text)
        # embedded: [sent len, batch size, emb dim]
        output, (hidden, cell) = self.rnn(embedded)
        # output: [sent len, batch size, hid dim * num directions]
        # hidden: [num layers * num directions, batch size, hid dim]
        # cell: [num layers * num directions, batch size, hid dim]
        hidden = torch.cat((hidden[-2,:,:], hidden[-1,:,:]), dim=1)
        # hidden: [batch size, hid dim * num directions]
        return self.fc(hidden)

# 加载数据集
TEXT = data.Field(tokenize='spacy')
LABEL = data.LabelField(dtype=torch.float)

train_data, test_data = datasets.IMDB.splits(TEXT, LABEL)
TEXT.build_vocab(train_data, max_size=25000, vectors="glove.6B.100d")
LABEL.build_vocab(train_data)

train_loader, test_loader = data.BucketIterator.splits((train_data, test_data), batch_size=32)

# 定义模型和优化器
input_dim = len(TEXT.vocab)
embedding_dim = 100
hidden_dim = 256
output_dim = 1
model = LSTM(input_dim, embedding_dim, hidden_dim, output_dim)
optimizer1 = optim.Adam(model.parameters(), lr=1e-3)
optimizer2 = optim.SGD(model.parameters(), lr=1e-3)

# 定义损失函数
criterion = nn.BCEWithLogitsLoss()

# 训练模型
for epoch in range(5):
    train_loss1, train_loss2, train_acc1, train_acc2 = 0.0, 0.0, 0.0, 0.0
    model.train()
    for batch in train_loader:
        optimizer1.zero_grad()
        optimizer2.zero_grad()
        text, label = batch.text, batch.label
        preds = model(text).squeeze(1)
        loss1 = criterion(preds, label)
        loss2 = criterion(preds, label)
        loss1.backward()
        loss2.backward()
        optimizer1.step()
        optimizer2.step()
        train_loss1 += loss1.item()
        train_loss2 += loss2.item()
        train_acc1 += ((preds>0).float() == label).sum().item()
        train_acc2 += ((preds>0).float() == label).sum().item()
    train_loss1 /= len(train_loader)
    train_loss2 /= len(train_loader)
    train_acc1 /= len(train_loader)
    train_acc2 /= len(train_loader)
    print(f'Epoch {epoch+1}: Adam loss {train_loss1:.3f} / SGD loss {train_loss2:.3f}, Adam acc {train_acc1*100:.2f}% / SGD acc {train_acc2*100:.2f}%')

在上面的代码中,我们定义了一个LSTM模型,并使用Adam和SGD两种优化算法进行比较。最终的结果表明,Adam算法的收敛速度比较快,而SGD算法的准确率稍高。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:torch.optim优化算法理解之optim.Adam()解读 - Python技术站

(2)
上一篇 2023年6月6日
下一篇 2023年6月6日

相关文章

  • Python实现按当前日期(年、月、日)创建多级目录的方法

    以下是实现按当前日期创建多级目录的方法: 1. 获取当前日期 首先,我们需要使用Python内置的datetime模块获取当前的年、月、日。 import datetime # 获取当前的日期 today = datetime.date.today() # 格式化日期 date_str = today.strftime(‘%Y%m%d’) print(dat…

    python 2023年6月2日
    00
  • 解决seaborn在pycharm中绘图不出图的问题

    下面是详细的攻略: 解决seaborn在pycharm中绘图不出图的问题 问题背景 当我们使用 seaborn 库在 Pycharm 中绘图时,有可能会出现绘图不出图的问题。 分析解决 环境准备 为了演示该问题以及解决方案,我们需要准备以下环境: Python 环境:安装 anaconda 并创建虚拟环境。可以使用以下命令: shell conda crea…

    python 2023年5月18日
    00
  • 用Python做一个久坐提醒小助手的示例代码

    下面就为大家讲解一下用Python做一个久坐提醒小助手的攻略: 确定需求 首先确定需求,即我们想要做一个能够提醒久坐的小助手,能够在一定的时间间隔内提醒我们起身活动,还能够记录每次提醒的时间和次数,方便后续查阅。考虑到我们需要一定的程序联网能力,我们选用Python编写。 安装依赖包 在编写程序前,需要安装一些Python第三方库,包括Win10toast(…

    python 2023年6月13日
    00
  • Python使用try except处理程序异常的三种常用方法分析

    Python使用try except处理程序异常的三种常用方法分析 在Python的程序开发中,错误是无法避免的。当代码在运行过程中出现异常时,如果不进行处理,整个程序可能会崩溃。因此,我们需要使用try…except语句来捕获和处理程序中的异常。在这篇文章中,我们将讨论Python使用try except处理程序异常的三种常用方法。 方法一:捕获所有异…

    python 2023年5月13日
    00
  • python numpy之np.random的随机数函数使用介绍

    标题:Python NumPy之np.random的随机数函数使用介绍 Python NumPy是一个用于科学计算的重要库,其中np.random作为NumPy的一个子模块,在数据处理和机器学习中被广泛应用。在np.random中有许多生成随机数的函数,可以通过这些函数生成一些数字序列,以便模拟、实验和建模等。本篇攻略将详细介绍np.random中主要随机数…

    python 2023年6月3日
    00
  • python打印n位数“水仙花数”(实例代码)

    下面是关于“python打印n位数‘水仙花数’(实例代码)”的完整攻略,包括示例说明: 什么是水仙花数 所谓“水仙花数”,是指一个n位数(n >= 3),它的每个位上数字的n次幂之和等于它本身。例如,153是一个3位的水仙花数,因为$1^3 + 5^3 + 3^3 = 153$。要注意的是,本题需要输出所有n位的水仙花数。 思路分析 要完成这个任务,我…

    python 2023年6月5日
    00
  • Python中POST调用Restful接口示例

    在Python中,我们可以使用requests库调用Restful接口。POST请求是一种常见的HTTP请求方法,用于向服务器提交数据。本文将介绍如何使用requests库调用Restful接口,并提供两个示例。 1. 使用requests库调用Restful接口 使用requests库调用Restful接口非常简单。我们只需要使用requests库的pos…

    python 2023年5月15日
    00
  • python中range()与xrange()用法分析

    Python中range()与xrange()用法分析 在Python中,有两个可用于生成整数序列的函数:range()和xrange()。本文将详细介绍这两个函数的用法及区别,并提供相应示例说明。 range()函数 range()函数是Python内置函数之一,用于生成一个整数序列,通常用于for循环中进行迭代。使用方法如下: range(stop) r…

    python 2023年6月3日
    00
合作推广
合作推广
分享本页
返回顶部