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可能导致训练过程提前停止,尤其是在处理非平稳目标函数时,这可能会使得模型无法充分学习。

相关推荐
武子康8 分钟前
大数据-207 数据挖掘 机器学习理论 - 多重共线性 矩阵满秩 线性回归算法
大数据·人工智能·算法·决策树·机器学习·矩阵·数据挖掘
小邓的技术笔记8 分钟前
20241106,LeetCode 每日一题,用 Go 实现整数回文数判断
算法·leetcode·golang
IronmanJay10 分钟前
【LeetCode每日一题】——802.找到最终的安全状态
数据结构·算法·leetcode··拓扑排序·802.找到最终的安全状态·反向图
兔兔爱学习兔兔爱学习32 分钟前
leetcode328. Odd Even Linked List
算法
£suPerpanda1 小时前
牛客周赛 Round65 补题DEF
开发语言·数据结构·c++·算法·深度优先·动态规划·图论
ao_lang1 小时前
剑指offer第五天
python·算法·cpp
付宇轩1 小时前
leetcode 173.二叉搜索树迭代器
算法·leetcode·职场和发展
L_cl1 小时前
数据结构与算法——Java实现 54.力扣1008题——前序遍历构造二叉搜索树
算法·leetcode
KeithTsui1 小时前
ZFC in LEAN 之 前集的等价关系(Equivalence on Pre-set)详解
开发语言·其他·算法·binder·swift