快捷键

torch.optim.sparse_adam 的源代码

# mypy: 允许未类型化定义
from 打字 导入 联合

导入 火炬
from 火炬 导入 张量

from . 导入 _functional  F
from .优化器 导入 _maximize_doc, _params_doc, 优化器, ParamsT


全部 = [SparseAdam]


[文档] SparseAdam(优化器): 定义 __init__( , 参数: 参数 T, 学习率: 联盟[float, 张量] = 0.001, betas: 元组[float, float] = (0.9, 0.999), eps: 浮点数 = 1e-8, 最大化: 布尔 = 错误, ): 如果 isinstance(学习率, 张量) 学习率.元素数量() != 1: raise ValueError("Tensor lr 必须是 1 个元素") 如果 0.0 < 学习率: raise ValueError(f"无效的学习率:"{学习率}") 如果 0.0 < eps: raise ValueError(f"无效的 epsilon 值:"{eps}") 如果 0.0 betas[0] < 1.0: raise ValueError(f"在索引 0 处的无效 beta 参数:"{betas[0]}") 如果 0.0 betas[1] < 1.0: raise ValueError(f"无效的 beta 参数,索引为 1:"{betas[1]}") 默认 = 字典(学习率=学习率, betas=betas, eps=eps, 最大化=最大化) 超级().__init__(参数, 默认值) sparse_params = 输入文本为空,请提供需要翻译的文本 复杂参数 = 输入文本为空,请提供需要翻译的文本 for 索引, 参数组 列举(.参数组): 断言 isinstance( 参数组, 字典 ), f"param_groups 必须是一个字典列表,但得到了"{类型(参数组)}" # 对于给定的参数组,在迭代之前先将给定的参数转换为列表 for d_index, d_param 列举(参数组[参数)] 如果 d_param.is_sparse: 稀疏参数.append[索引, d_index]) 如果 d_param.是复杂的(): complex_params.append[索引, d_index]) 如果 sparse_params: raise ValueError( f索引处的稀疏参数{sparse_params}SparseAdam 需要密集的参数张量 ) 如果 complex_params: raise ValueError( f"在索引处的复杂参数"{complex_params}: SparseAdam 不支持复杂数据参数 )
[文档] @torch.不梯度() 定义 步长(, 闭包=): 执行单个优化步骤。 参数: 闭包(Callable,可选):一个重新评估模型并返回损失的闭包 和返回损失。 "文档" 损失 = 如果 闭包 : torch.启用梯度(): 损失 = 闭包() for .参数组: 带梯度的参数: 列表[张量] = 输入文本为空,请提供需要翻译的文本 梯度: 列表[张量] = 输入文本为空,请提供需要翻译的文本 实验平均值: 列表[张量] = 输入文本为空,请提供需要翻译的文本 实验平均平方值: 列表[张量] = 输入文本为空,请提供需要翻译的文本 状态步数: 列表[整数] = 输入文本为空,请提供需要翻译的文本 beta1, beta2 = 群组[贝塔] 最大化 = 群组.获取(最大化, 错误) for p 群组[参数]: 如果 p.梯度 : 带梯度的参数.append(p) 如果 p.研究生.is_sparse: raise 运行时错误( "SparseAdam 不支持稠密梯度,请考虑使用 Adam" ) 梯度.append(p.研究生) 状态 = .状态[p] # 状态初始化 如果 长度(状态) == 0: 状态[步骤] = 0 指数移动平均的梯度值 状态[平均值] = torch.等于零的( p, 内存格式=torch.保留格式 ) 平方梯度值的指数移动平均 状态["exp_avg_sq"] = torch.等于零的( p, 内存格式=torch.保留格式 ) 实验平均值.append(状态[平均值]) 实验平均平方值.append(状态["exp_avg_sq"]) 更新每个参数组的步骤 状态[步骤] += 1 记录步骤更新后的步骤 状态步数.append(状态[步骤]) F.sparse_adam( 带梯度的参数, 梯度, 实验平均值, 实验平均平方值, 状态步数, eps=群组[eps] beta1=beta1, beta2=beta2, 学习率=群组["lr"] 最大化=最大化, ) 返回 损失
SparseAdam.__doc__ = rf稀疏 Adam 实现了 Adam 算法的掩码版本 适用于稀疏梯度。目前,由于实现限制(解释如下) 以下),SparseAdam 仅适用于狭窄的用例子集,具体 密集布局的参数以及稀疏布局的渐变。这种现象发生在 特殊情况,其中模块反向生成已经处于稀疏布局的梯度。 一个表现如此行为的 NN 模块示例是 `nn.Embedding(sparse=True)`。 稀疏 Adam 通过屏蔽参数和动量来近似 Adam 算法 更新对应梯度中零值的操作。而 Adam 算法 将根据所有值更新第一时刻、第二时刻和参数 SparseAdam 只更新梯度非零值对应的动量和参数。 关于`intended`实现的简化思考方式如下: 可以这样简单地思考`intended`实现的意图: 1. 创建稀疏梯度的非零值掩码。例如, 如果你的梯度看起来像[0, 5, 0, 0, 9],那么掩码将是[0, 1, 0, 0, 1]。 2. 将此掩码应用于运行时的矩,并对非零值进行计算。 4. 仅对非零值进行计算。 在参数上应用此掩码,并且仅在非零值上应用更新。 实际上,我们使用稀疏布局张量来优化这个近似,这意味着 被掩码且未实际化的梯度越多,优化性能就越好。 由于我们依赖于使用稀疏布局张量,我们推断出任何实际化的值在 稀疏布局非零,我们实际上并不验证所有值都不是零! 重要的是不要混淆语义稀疏张量(一个许多元素语义上稀疏的张量) 其值均为零的稀疏布局张量(一个`.is_sparse` 返回 `True`。SparseAdam 近似旨在用于 `语义` 稀疏 张量以及稀疏布局只是实现细节。更清晰的实现方式是使用 MaskedTensors,但这些是实验性的。 如果您怀疑您的梯度在语义上是稀疏的(但没有稀疏布局),这个变体可能不适合您。理想情况下,您希望避免 .. 注意:: 如果您怀疑您的梯度在语义上是稀疏的(但不是稀疏布局),这个变体可能不适合您。理想情况下,您希望避免 如果您怀疑您的梯度在语义上是稀疏的(但不是稀疏布局),这个变体可能不适合您。理想情况下,您希望避免 将任何一开始就被怀疑是稀疏的东西具体化,因为 需要将所有梯度从密集布局转换为稀疏布局的必要性可能超过 性能提升。在这里,使用 Adam 可能是最佳替代方案,除非你 可以轻松设置您的模块以输出类似于稀疏梯度的输出 nn.Embedding(sparse=True) 如果您坚持转换您的梯度,您可以 因此,通过手动覆盖您的参数的 `.grad` 字段以它们的稀疏 在调用 `.step()` 之前设置等效值。 参数: {_params_doc} lr(浮点数,张量,可选):学习率(默认:1e-3) betas (Tuple[float, float], 可选): 用于计算系数 运行平均梯度及其平方(默认:(0.9, 0.999)) eps (float, 可选): 添加到分母中的项,以改善 数值稳定性(默认:1e-8) {_maximize_doc} .. _Adam:随机优化的方法: https://arxiv.org/abs/1412.6980 "文档"

© 版权所有 PyTorch 贡献者。

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

文档

查看 PyTorch 的全面开发者文档

查看文档

教程

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

查看教程

资源

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

查看资源