快捷键

torch.optim.adamax 的源代码

# mypy: 允许未类型化定义
from 打字 导入 角色, 可选, 联合

导入 火炬
from 火炬 导入 张量

from .优化器 导入 (
    _capturable_doc,
    默认为融合或遍历,
    _可微分文档,
    _如果不受支持则禁用 Dynamo,
    _foreach 文档,
    _获取可捕获支持的设备,
    _获取标量数据类型,
    _获取值,
    _maximize_doc,
    _params_doc,
    _use_grad_for_differentiable,
    _以真实视图,
    优化器,
    ParamsT,
)


全部 = ["Adamax", "adamax"]


[文档] Adamax(优化器): def __init__( , 参数: ParamsT, 学习率: 并集[float, 张量] = 0.002, beta 参数: 元组[float, float] = (0.9, 0.999), eps: 浮点数 = 1e-8, 权重衰减: 浮点数 = 0, foreach: 可选[布尔] = , *, 最大化: 布尔值 = 错误, 可微分的: 布尔值 = 错误, 可捕获的: 布尔值 = 错误, ): 如果 isinstance(学习率, 张量) 学习率.元素数量() != 1: 提升 ValueError("张量学习率必须为 1 个元素") 如果 0.0 <= 学习率: 提升 ValueError(f"无效的学习率:"{学习率}") 如果 0.0 <= eps: 提升 ValueError(f"无效的 epsilon 值:"{eps}") 如果 0.0 <= β测试[0] < 1.0: 提升 ValueError(f"在索引 0 处的无效 beta 参数:"{β测试[0]}") 如果 0.0 <= β测试[1] < 1.0: 提升 ValueError(f"在索引 1 处的无效 beta 参数:"{β测试[1]}") 如果 0.0 <= 权重衰减: 提升 ValueError(f"无效的权重衰减值:"{权重衰减}") 默认 = 字典( 学习率=学习率, β测试=β测试, eps=eps, 权重衰减=权重衰减, foreach=foreach, 最大化=最大化, 可微分的=可微分的, 可捕获的=可捕获的, ) 超级().__init__(参数, 默认值) def __setstate__(, 状态): 超级().__setstate__(状态) 群组 .参数组: 群组.setdefault(foreach, ) 群组.setdefault(最大化, 错误) 群组.setdefault("可区分的", 错误) 群组.setdefault("可捕获的", 错误) p 群组[参数]: p 状态 = .状态.获取(p, [] 如果 长度(状态) != 0 火炬.is_tensor(状态[步骤)] 步骤值 = float(状态[步骤]) 状态[步骤] = ( 火炬.张量( 步长值, 数据类型=_获取标量数据类型(), 设备=p.设备 ) 如果 群组["可捕获的"] 否则 火炬.张量(步长值, 数据类型=_获取标量数据类型()) ) def _init_group( , 群组, params_with_grad, 梯度, 实验平均值, 演练信息, 状态步骤 ): 具有复杂 = p 群组[参数]: 如果 p.梯度 is : continue 具有复杂 |= 火炬.是复杂的(p) params_with_grad.append(p) 如果 p.研究生.is_sparse: 提升 运行时错误(Adamax 不支持稀疏梯度) 梯度.append(p.研究生) 状态 = 自身.状态[p] # 状态初始化 如果 长度(状态) == 0: 状态["步骤"] = ( 火炬.零值((), 数据类型=获取标量数据类型(), 设备=p.设备) 如果 群组["可捕获的"] 否则 火炬.张量(0.0, 数据类型=获取标量数据类型()) ) 状态["exp_avg"] = 火炬.等于零的( p, 内存格式=火炬.保留格式 ) 状态["指数无穷"] = 火炬.等于零的( p, 内存格式=火炬.保留格式 ) 期望平均值.append(状态["exp_avg"]) 指数无穷 s.append(状态["指数无穷"]) 状态步数.append(状态[步骤]) 返回 具有复杂性
[文档] @_use_grad_for_differentiable def 步长(, 闭包=): 执行单次优化步骤。 参数: 闭包(Callable,可选):一个重新评估模型并返回损失的闭包。 并返回损失。 "文档" .CUDA 图捕获健康检查() 损失 = 如果 闭包 is : 火炬.启用梯度(): 损失 = 闭包() 群组 .参数组: 带梯度的参数: 列表[张量] = 输入文本为空,请提供需要翻译的文本 梯度: 列表[张量] = 输入文本为空,请提供需要翻译的文本 期望平均值: 列表[张量] = 输入文本为空,请提供需要翻译的文本 指数: 列表[张量] = 输入文本为空,请提供需要翻译的文本 状态步骤: 列表[张量] = 输入文本为空,请提供需要翻译的文本 beta1, beta2 = 群组[贝塔] eps = 群组["eps"] lr = 群组["lr"] 权重衰减 = 群组["权重衰减"] 遍历 = 群组[foreach] 最大化 = 群组[最大化] 可微分的 = 群组["可区分的"] 可捕获的 = 群组["可捕获的"] 具有复杂性 = .初始化组( 群组, 带梯度的参数, 梯度, 期望平均值, 指数衰减, 状态步骤 ) adamax( 带梯度的参数, 梯度, 期望平均值, 指数衰减, 状态步数, eps=eps, beta1=beta1, beta2=beta2, lr=lr, 权重衰减=权重衰减, foreach=foreach, 最大化=最大化, 可微分的=可微分的, 可捕获的=可捕获的, 具有复杂的=具有复杂的, ) 返回 损失
Adamax.__doc__ = ( r实现 Adamax 算法(基于无穷范数的 Adam 变体)。 .. math:: \begin{aligned} &\rule{110mm}{0.4pt} \\ &\textbf{输入} : \gamma \text{ (学习率)}, \beta_1, \beta_2 \text{(beta)},\theta_0 \text{(参数)},f(\theta) \text{(目标函数)}, \: \lambda \text{(权重衰减)} \\ &\hspace{13mm} \epsilon \text{(epsilon)} \\ &\textbf{initialize} : m_0 \leftarrow 0 \text{ ( 首矩)} u_0 \leftarrow 0 \text{ ( 无穷范数)} \\[-1.ex] &\rule{110mm}{0.4pt} \\ &\textbf{for} \: t=1 \: \textbf{to} \: \ldots \: \textbf{do} \\ &\hspace{5mm}g_t \leftarrow \nabla_{\theta} f_t (\theta_{t-1}) \\ 若 \(\lambda \neq 0\) \(g_t \leftarrow g_t + \lambda \theta_{t-1}\) \(m_t \leftarrow \beta_1 m_{t-1} + (1 - \beta_1) g_t\) \(u_t \leftarrow \mathrm{max}(\beta_2 u_{t-1}, |g_{t}|+\epsilon)\) &\hspace{5mm}\theta_t \leftarrow \theta_{t-1} - \frac{\gamma m_t}{(1-\beta^t_1) u_t} \\ &\rule{110mm}{0.4pt} \\[-1.ex] &\bf{return} \: \theta_t \\[-1.ex] &\rule{110mm}{0.4pt} \\[-1.ex] \end{aligned} 有关算法的更多详细信息,请参阅《Adam:一种随机优化方法》_。 "文档" + rf"" 参数: {参数文档} lr (float, Tensor, 可选): 学习率(默认:2e-3) betas (Tuple[float, float], 可选): 用于计算系数 梯度和其平方的运行平均值 eps(浮点数,可选):添加到分母中的项,以提高数值稳定性(默认:1e-6)。 数值稳定性(默认:1e-8) weight_decay (浮点数,可选): 权重衰减(L2 惩罚)(默认:0) {_foreach 文档} {最大化文档} {_可微分文档} {_capturable_doc} .. _Adam:一种随机优化的方法: https://arxiv.org/abs/1412.6980 "文档" ) def _single_tensor_adamax( 参数: 列表[张量] 梯度: 列表[张量] 期望平均值: 列表[张量] exp_infs: 列表[张量] 状态步数: 列表[张量] *, eps: float, beta1: float, beta2: float, lr: float, 权重衰减: float, 最大化: 布尔, 可微分的: 布尔, 可捕获的: 布尔, 具有复杂的: 布尔, ): i, 参数 列举(参数): 梯度 = 梯度[i] 梯度 = 梯度 如果 最大化 否则 -梯度 指数平均值 = 期望平均值[i] 指数 = 指数们[i] step_t = 状态步骤[i] 如果编译,编译器将处理 cudagraph 检查,参见注释[torch.compile x capturable] 如果 火炬.编译器.编译中() 可捕获的: 可捕获支持的设备 = _获取可捕获支持的设备() 断言 ( 参数.设备.类型 == step_t.设备.类型 参数.设备.类型 可捕获支持的设备 ), f如果 capturable=True,则 params 和 state_steps 必须在支持的设备上:{支持捕获的设备} # 更新步骤 step_t += 1 如果 权重衰减 != 0: 梯度 = 研究生.添加(参数, 阿尔法=权重衰减) 如果 火炬.是复杂的(参数): 参数 = 火炬.真实查看(参数) 梯度 = 火炬.真实查看(研究生) 指数平均值 = 火炬.真实查看(指数平均) 指数无穷 = 火炬.真实查看(指数无穷) 更新偏置的第一矩估计。 指数平均.线性插值 _(研究生, 1 - beta1) 更新指数加权无穷范数。 如果 可微分的: 火炬.最大值( 指数无穷.mul_(beta2), 研究生.绝对值().加_(eps), 输出=指数无穷, ) else: 正态缓冲区 = 火炬.( [指数无穷.mul_(beta2).展平(0), 研究生.绝对值().加_(eps).unsqueeze_ (未翻译,因为这不是一个完整的英文单词或短语)(0)], 0, ) 指数函数.复制_(火炬.amax(正态缓冲区, 0, 保持维度=错误)) 如果 可捕获的: # 为什么要跳过额外的步骤并取消偏置校正?查看 #121238 # 修复后,我们应该使用带有 addcdiv 值为 -1 的偏置校正以提高可读性 负偏置校正 = beta1**step_t - 1 负偏差校正.div_(学习率) 分母 = 指数无穷 * 负偏差校正 参数.addcdiv_(指数平均, 分母) else: 偏差校正 = 1 - beta1 ** 获取值(step_t) 清除 = lr / 偏差校正 参数.addcdiv_(指数平均, 指数无穷, =-clr) def _多张量 Adamax( 参数: 列表[张量] 梯度: 列表[张量] 实验平均值: 列表[张量] 指数无穷大: 列表[张量] 状态步骤: 列表[张量] *, eps: float, beta1: float, beta2: float, 学习率: float, 权重衰减: float, 最大化: 布尔, 可微分的: 布尔, 可捕获的: 布尔, 具有复杂的: 布尔, ): 断言 可微分的, "_foreach 操作不支持自动求导" 如果 长度(参数) == 0: 返回 如果编译,编译器将处理 cudagraph 检查,参见注释[torch.compile x capturable] 如果 火炬.编译器.编译中() 可捕获的: 可捕获支持的设备 = _获取可捕获支持的设备( 支持 XLA= ) 断言 所有( p.设备.类型 == 步长.设备.类型 p.设备.类型 可捕获支持的设备 p, 步骤 zip(参数, 状态步骤) ), f如果 capturable=True,则 params 和 state_steps 必须在支持的设备上:{支持捕获的设备} 分组张量 = 优化器.按设备类型和数据类型分组张量( [参数, 梯度, 实验平均值, 指数, 状态步骤] # type: ignore[list-item] ) ( 分组参数_, 分组梯度_, 分组指数平均值_, 分组经验信息_, 分组状态步骤_, ), _ 分组张量.(): 分组参数 = 角色(列表[张量] 分组参数_) 分组梯度 = 角色(列表[张量] 分组梯度_) 分组实验平均值 = 角色(列表[张量] 分组实验平均值_) 分组实验下限 = 角色(列表[张量] 分组实验下限_) 分组状态步骤 = 角色(列表[张量] 分组状态步骤_) 如果 具有复杂: _以真实视图( 分组参数, 分组梯度, 分组实验平均值, 分组实验下限 ) 如果 最大化: 分组梯度 = 火炬._foreach_neg(分组梯度) # 类型:忽略[赋值] # 更新步骤 # 如果步骤在 CPU 上,foreach 将回退到慢速路径,即通过循环调用 t.add(1) #然后 1 会被反复包裹成 Tensor,这比只包裹一次要慢。 #alpha 是必须的,以确保我们进入正确的重载。 如果 火炬.编译器.编译中() 分组状态步数[0].是 CPU: 火炬._foreach_add_( 分组状态步数, 火炬.张量(1.0, 设备="cpu"), 阿尔法=1.0 ) else: 火炬._foreach_add_(分组状态步骤, 1) 如果 权重衰减 != 0: 如果 最大化: 重复使用已分配给最大化操作的中间内存(grouped_grads) 火炬._foreach_add_(grouped_grads, grouped_params, 阿尔法=权重衰减) else: 分组梯度 = 火炬._foreach_add_( # 类型:忽略[赋值] 分组梯度, 分组参数, 阿尔法=权重衰减 ) 更新偏置的第一矩估计。 火炬._foreach_lerp_(分组平均, 分组梯度, 1 - beta1) 更新指数加权无穷范数。 火炬._foreach_mul_(grouped_exp_infs, beta2) 在这种情况下,我们需要引入 grads 的一个副本 因为之前还没有引入 如果 最大化 权重衰减 == 0: 分组梯度 = 火炬._foreach_abs(分组梯度) # 类型:忽略[赋值] else: 火炬._foreach_abs_(分组梯度) 火炬._foreach_add_(分组梯度, eps) 火炬._foreach_maximum_(分组经验信息, 分组梯度) 偏差校正: 并集[元组[张量, ...] 列表[张量]] 如果 可捕获的: 偏差校正 = 火炬._foreach_pow(beta1, 分组状态步骤) 不允许将标量作为 foreach_sub 的第一个参数 火炬._foreach_sub_(偏差校正, 1) 火炬._foreach_div_(偏差校正, 学习率) 分母 = 火炬._foreach_mul(分组经验无穷, 偏差校正) 火炬._foreach_addcdiv_(分组参数, 分组经验平均值, 分母) else: 偏差校正 = [ 1 - beta1 ** _获取值(步长) 步骤 分组状态步骤 ] 步长大小 = [_获取值(学习率) / bc) * -1 bc 偏差校正] 火炬._foreach_addcdiv_( 分组参数, 分组实验平均值, 分组实验下限, 步长大小 ) @_disable_dynamo_if_unsupported(单个张量函数=_单个张量 Adamax) def 自适应动量( 参数: 列表[张量] 梯度: 列表[张量] 实验平均值: 列表[张量] exp_infs: 列表[张量] 状态步数: 列表[张量] 使用 torchscript 编译的函数不支持带默认值的只写关键字参数问题 #70627 # 现在将其设置为 kwarg,因为功能 API 由 torch/distributed/optim 编译 foreach: 可选[布尔] = , 最大化: 布尔值 = 错误, 可微分的: 布尔值 = 错误, 可捕获的: 布尔值 = 错误, 具有复杂结构: 布尔值 = 错误, *, eps: float, beta1: float, beta2: float, 学习率: float, 权重衰减: float, ): r功能性 API,执行 adamax 算法计算。 详细信息请参阅 :class:`~torch.optim.Adamax`。 "文档" 如果 火炬.编译器.编译中() 所有( isinstance(t, 火炬.张量) t 状态步骤 ): 提升 运行时错误( "API 已更改,`state_steps`参数必须包含一个单例张量列表" ) 如果 遍历 is : _, 遍历 = 默认为融合或遍历( 参数, 可微分的, 使用融合= ) 如果 遍历 火炬.算子.是否正在脚本化(): 提升 运行时错误("torch.jit.script 不支持与 foreach 优化器一起使用") 如果 遍历 火炬.算子.是否正在脚本化(): 函数 = 多张张量 Adamax else: 函数 = 单张张量 Adamax 函数( 参数, 梯度, 实验平均值, 指数无穷, 状态步数, eps=eps, beta1=beta1, beta2=beta2, 学习率=学习率, 权重衰减=权重衰减, 最大化=最大化, 可微分的=可微分的, 具有复杂结构=具有复杂结构, 可捕获的=可捕获的, )

© 版权所有 PyTorch 贡献者。

使用 Sphinx 构建,并使用 Read the Docs 提供的主题。

文档

查看 PyTorch 的全面开发者文档

查看文档

教程

深入了解初学者和高级开发者的教程

查看教程

资源

查找开发资源,获取您的疑问解答

查看资源