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 元编程

    作者:袁首京 原创文章,转载时请保留此声明,并给出原文连接。 元编程并不象它听起来那么时髦和新奇。常用的 decorator 就可以认为是一种元编程。简单来说,元编程就是编写操作代码的代码。 有点绕,是吧?别着急,咱们一点一点来讨论。 注意:本文中的代码适用于 Python 3.3 及以上。 元类 多数编程语言中,一切东西都有类型。Python 也不例外,我…

    python 2023年4月18日
    00
  • python爬不同图片分别保存在不同文件夹中的实现

    下面针对该话题给出完整的攻略,包括流程和示例说明。 流程说明 要实现python爬不同图片分别保存在不同文件夹中,大致的流程可以概括为以下几个步骤: 定位需要爬取的目标页面,了解其URL及HTML结构; 使用Python爬虫库(比如requests、BeautifulSoup等),获取目标页面的HTML代码; 从HTML代码中获取所需的图像URL、标题或标签…

    python 2023年5月19日
    00
  • Python中zipfile压缩包模块的使用

    使用Python的zipfile模块可以很方便地压缩、解压缩、读取zip文件的内容。本文将详细介绍zipfile模块的使用方法。 压缩文件 使用zipfile模块中的ZipFile类可以创建、添加、修改zip文件。以下是创建一个zip文件的示例代码: import zipfile zipname = "example.zip" with …

    python 2023年6月3日
    00
  • 手把手教你怎么用Python实现zip文件密码的破解

    现在我来为你详细讲解如何用Python实现zip文件密码的破解。 1. 准备工作 在开始之前,你需要安装 pyzipper 库来对 zip 文件进行操作,以及 argparse 库来处理命令行参数。你可以使用以下命令来安装这两个库: pip3 install argparse pyzipper 2. 破解过程 2.1 密码破解函数 我们将使用一个名为 bru…

    python 2023年6月3日
    00
  • python获得两个数组交集、并集、差集的方法

    在Python中,可以使用set集合来实现两个数组的交集、并集、差集等操作。下面是详细的讲解和示例说明。 两个数组的交集 可以使用set集合的intersection()方法来获取两个数组的交集。该方法会返回一个新的set集合,包含两个数组中共同的元素。下面是一个示例: # 定义两个数组 arr1 = [1, 2, 3, 4, 5] arr2 = [3, 4…

    python 2023年5月13日
    00
  • 13个你可能未使用过的Python特性分享

    13个你可能未使用过的Python特性分享 在Python语言中,拥有许多许多强大且有用的特性,很多人很少使用或依旧不了解。本篇文章将分享13个你可能未使用过的Python特性,这些特性可能会极大地提升你的编码效率,让你的代码更加优雅。 1. 列表推导式 列表推导式是一种用于创建列表的快速方式,它可以让你使用更少的代码创建一个新的列表。它的语法非常简单,用一…

    python 2023年5月13日
    00
  • Python程序设计入门(5)类的使用简介

    Python程序设计入门(5)类的使用简介 一、什么是类? 类是面向对象编程(Object Oriented Programming,OOP)中的一种概念,是对一组对象的共同特征进行抽象形成的模板或者蓝图。类可以看做是对具体对象的抽象,它提供了一个封装数据和行为的模板,可以通过实例化为一个具体的对象。 举个例子,我们可以把一个人看做是一个对象,而人的属性和方…

    python 2023年5月31日
    00
  • python爬虫之场内ETF基金获取

    本攻略将介绍如何使用Python爬虫获取场内ETF基金数据。我们将使用requests库和BeautifulSoup库获取基金数据,并使用pandas库将数据保存到CSV文件中。我们将提供两个示例代码,分别用于获取单个基金和多个基金的数据。 安装所需库 在开始前,我们需要安装requests、BeautifulSoup和pandas库。我们可以使用以下命令在…

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