24/11/5 算法笔记adagrad 自适应学习率

AdaGrad(Adaptive Gradient Algorithm)是一种用于随机优化的算法,它通过适应每个参数的学习率来优化目标函数。

  1. 自适应学习率: AdaGrad算法的核心特点是为每个参数自适应地调整学习率。这意味着每个参数都有自己的学习率,这取决于该参数的梯度历史信息。这种自适应性使得算法能够根据参数的重要性和变化频率来调整学习率,从而提高优化效率。

  2. 二阶动量: AdaGrad算法引入了二阶动量的概念,通过累积所有过去的梯度平方和来调整学习率。对于每个参数,算法维护一个累积梯度平方和的变量,这个变量随着时间的推进而增加,导致学习率逐渐减小。

  3. 更新规则 : AdaGrad的参数更新规则如下: 其中,θt​ 是时间步 t 的参数,η 是初始学习率,Gt​ 是累积梯度平方和,gt​ 是当前步的梯度,ϵ是为了避免除以零而加上的一个小常数(通常取 10^-10)。

  4. 对稀疏数据的鲁棒性: AdaGrad倾向于给不频繁更新的特征分配更大的学习率,这使得它在处理稀疏数据时特别有效。对于那些很少更新的参数,AdaGrad能够给予更大的更新步长,从而确保这些参数有足够的机会进行调整。

  5. 缺点: 尽管AdaGrad在某些情况下表现良好,但它的一个主要缺点是累积梯度平方和会导致学习率迅速减小,这可能会导致训练过程在后期几乎停止。

  6. 对Adam算法的影响: AdaGrad算法是Adam算法的前身之一,它对后续的优化算法发展产生了重要影响,特别是在自适应学习率的设计理念上。

下面是adagrad的代码

import torch

class AdaGrad(torch.optim.Optimizer): 
    def __init__(self, params, lr=1e-3, lr_decay=0, weight_decay=0): #检查参数范围
        if not 0.0 <= lr < 1.0:
            raise ValueError("Invalid learning rate: {}".format(lr))
        if not 0.0 <= lr_decay < 1.0:
            raise ValueError("Invalid lr_decay value: {}".format(lr_decay))
        if not 0.0 <= weight_decay < 1.0:
            raise ValueError("Invalid weight_decay value: {}".format(weight_decay))
        defaults = dict(lr=lr, lr_decay=lr_decay, weight_decay=weight_decay)
        super(AdaGrad, self).__init__(params, defaults)

    def step(self, closure=None):  
        loss = None
        if closure is not None:
            loss = closure() #返回损失

        for group in self.param_groups: #优化器可以对不同参数应用不同的优化设置,这些设置被组织在不同的组(param_groups)中。
            for p in group['params']: 
                if p.grad is None:
                    continue
                grad = p.grad.data 
                if grad.is_sparse:  #梯度稀疏性检查
                    raise RuntimeError('AdaGrad does not support sparse gradients, please consider SparseAdam instead')

                state = self.state[p]  #状态字典

                # State initialization
                if len(state) == 0:
                    state['step'] = 0
                    state['sum'] = torch.zeros_like(p.data)

                state['step'] += 1   #更新迭代步数
  
                state['sum'].add_(grad.pow(2))

                if group['weight_decay'] != 0: #如果设置了权重衰减(group['weight_decay']),则将参数 p 的数据乘以权重衰减系数加到梯度 grad 上。
                    grad.add_(p.data, alpha=group['weight_decay'])

                clr = group['lr'] / (1 + state['step'] * group['lr_decay']) #计算学习率

                denom = state['sum'].sqrt().add_(group['eps'])  # 分母,即累积梯度平方和的平方根加上一个小常数以避免除零
                p.data.addcdiv_(grad, denom, value=-clr)

        return loss

缺点

  1. 学习率持续衰减:AdaGrad算法会累积所有过去的梯度平方和,这导致分母不断增大,从而使学习率持续减小。在训练的后期,学习率可能会变得非常小,导致模型难以继续学习,几乎停止收敛。

  2. 存储梯度平方和:AdaGrad需要为每个参数存储一个累积的梯度平方和,这在参数数量很多时会占用较多的内存,增加内存开销。

  3. 对稀疏数据的过度适应:虽然AdaGrad能够自动提高稀疏特征的学习率,但在某些情况下,这可能导致对这些稀疏特征的过度适应,从而影响模型的泛化能力。

  4. 可能导致训练提前停止:由于学习率的快速下降,AdaGrad可能导致训练过程提前停止,尤其是在处理非平稳目标函数时,这可能会使得模型无法充分学习。

相关推荐
The_Ticker5 分钟前
CFD平台如何接入实时行情源
java·大数据·数据库·人工智能·算法·区块链·软件工程
爪哇学长41 分钟前
双指针算法详解:原理、应用场景及代码示例
java·数据结构·算法
风尚云网1 小时前
风尚云网前端学习:一个简易前端新手友好的HTML5页面布局与样式设计
前端·css·学习·html·html5·风尚云网
Dola_Pan1 小时前
C语言:数组转换指针的时机
c语言·开发语言·算法
繁依Fanyi1 小时前
简易安卓句分器实现
java·服务器·开发语言·算法·eclipse
烦躁的大鼻嘎1 小时前
模拟算法实例讲解:从理论到实践的编程之旅
数据结构·c++·算法·leetcode
熙曦Sakura1 小时前
完全竞争市场
笔记
C++忠实粉丝2 小时前
计算机网络socket编程(4)_TCP socket API 详解
网络·数据结构·c++·网络协议·tcp/ip·计算机网络·算法
用户37791362947552 小时前
【循环神经网络】只会Python,也能让AI写出周杰伦风格的歌词
人工智能·算法
福大大架构师每日一题2 小时前
文心一言 VS 讯飞星火 VS chatgpt (396)-- 算法导论25.2 1题
算法·文心一言