快捷键

torch.optim.rmsprop 的源代码

# mypy: 允许未类型化定义
rRMSprop 算法的实现
from 打字 导入 角色, 可选, 联合

导入 火炬
from 火炬 导入 张量

from .优化器 导入 (
    _可捕获文档,
    默认为融合或遍历,
    _可区分文档,
    _如果不受支持则禁用 Dynamo,
    _foreach_doc,
    _获取可捕获的设备,
    _获取标量数据类型,
    _maximize_doc,
    _params_doc,
    _use_grad_for_differentiable,
    真实查看,
    优化器,
    参数 T,
)


全部 = [RMSprop, rmsprop]


[文档] RMSprop(优化器): # noqa: D101 定义 __init__( , 参数: 参数 T, 学习率: 并集[float, 张量] = 0.01, 阿尔法: 浮点数 = 0.99, eps: 浮点数 = 1e-8, 权重衰减: 浮点数 = 0, 动量: 浮点数 = 0, 居中: 布尔值 = 错误, 可捕捉的: 布尔值 = 错误, foreach: 可选[布尔] = , 最大化: 布尔值 = 错误, 可微分的: 布尔值 = 错误, ): # 无需注意:D107 如果 isinstance(学习率, 张量) 学习率.元素数量() != 1: 提升 ValueError("Tensor lr 必须是 1 个元素") 如果 0.0 <= 学习率: 提升 ValueError(f"无效的学习率:"{学习率}") 如果 0.0 <= eps: 提升 ValueError(f"无效的 epsilon 值:"{eps}") 如果 0.0 <= 动量: 提升 ValueError(f"无效的动量值:"{动量}") 如果 0.0 <= 权重衰减: 提升 ValueError(f"无效的 weight_decay 值:"{权重衰减}") 如果 0.0 <= 阿尔法: 提升 ValueError(f"无效的 alpha 值:"{阿尔法}") 默认 = 字典( 学习率=学习率, 动量=动量, 阿尔法=阿尔法, eps=eps, 居中=居中, 权重衰减=权重衰减, 可捕捉的=可捕捉的, foreach=foreach, 最大化=最大化, 可微分的=可微分的, ) 超级().__init__(参数, 默认值) 定义 __setstate__(, 状态): # 无需注意:D105 超级().__setstate__(状态) for .参数组: 群组.setdefault(动量, 0) 群组.setdefault(居中, 错误) 群组.setdefault(foreach, ) 群组.setdefault(最大化, 错误) 群组.setdefault(可微分的, 错误) 群组.setdefault("可捕获的", 错误) for p 群组[参数]: 状态 = .状态.获取(p, [] 如果 长度(状态) != 0 torch.is_tensor(状态[步骤)] 步骤值 = float(状态[步骤]) 状态[步骤] = ( torch.张量( 步值, 数据类型=_获取标量数据类型(), 设备=p.设备 ) 如果 群组["可捕获的"] 否则 torch.张量(步值, 数据类型=_获取标量数据类型()) ) 定义 初始化组( , 群组, 带梯度的参数, 梯度, 平方平均值, 动量缓冲区列表, 梯度平均值, 状态步数, ): 复杂的参数 = for p 群组[参数]: 如果 p.梯度 : continue 复杂的参数 |= torch.是复杂的(p) 带梯度的参数.append(p) 如果 p.研究生.is_sparse: 提升 运行时错误(RMSprop 不支持稀疏梯度) 梯度.append(p.研究生) 状态 = .状态[p] # 状态初始化 如果 长度(状态) == 0: 状态[步骤] = ( torch.零值((), 数据类型=_获取标量数据类型(), 设备=p.设备) 如果 群组["可捕获的"] 否则 torch.零值((), 数据类型=_获取标量数据类型()) ) 状态[平方平均] = torch.等于零的( p, 内存格式=torch.保留格式 ) 如果 群组[动量] > 0: 状态[动量缓冲区] = torch.等于零的( p, 内存格式=torch.保留格式 ) 如果 群组[居中]: 状态[梯度平均值] = torch.等于零的( p, 内存格式=torch.保留格式 ) 平方平均值.append(状态[平方平均]) 状态步数.append(状态[步骤]) 如果 群组[动量] > 0: 动量缓冲区列表.append(状态[动量缓冲区]) 如果 群组[居中]: 梯度平均值.append(状态[梯度平均]) 返回 复杂的参数
[文档] @_use_grad_for_differentiable 定义 步长(, 闭包=): 执行单个优化步骤。 参数: 闭包(Callable,可选):一个重新评估模型并返回损失的闭包 和返回损失。 "文档" ._cuda_graph_capture_health_check() 损失 = 如果 闭包 : torch.启用梯度(): 损失 = 闭包() for .参数组: 带梯度的参数: 列表[张量] = 输入文本为空,请提供需要翻译的文本 梯度: 列表[张量] = 输入文本为空,请提供需要翻译的文本 平方平均值: 列表[张量] = 输入文本为空,请提供需要翻译的文本 梯度平均值: 列表[张量] = 输入文本为空,请提供需要翻译的文本 动量缓冲区列表: 列表[张量] = 输入文本为空,请提供需要翻译的文本 状态步数: 列表[张量] = 输入文本为空,请提供需要翻译的文本 复杂的参数 = .初始化组( 群组, 带梯度的参数, 梯度, 平方平均值, 动量缓冲区列表, 梯度平均值, 状态步数, ) rmsprop( 带梯度的参数, 梯度, 平方平均值, grad_avgs, momentum_buffer_list, 状态步数, 学习率=群组["lr"] 阿尔法=群组["alpha"] eps=群组[eps] 权重衰减=群组[权重衰减] 动量=群组[动量] centered=群组[居中] foreach=群组[foreach] 最大化=群组[最大化] 可微分的=群组[可微分的] 可捕捉的=群组["可捕获的"] 有复杂的=有复杂的, ) 返回 损失
RMSprop.__doc__ = ( r实现 RMSprop 算法。 .. math:: \begin{aligned} &\rule{110mm}{0.4pt} \\ 输入 &\textbf{input} : \alpha \text{ (alpha)}, \: \gamma \text{ (lr)}, θ_0 (参数), f(θ) (目标函数) \\ &\hspace{13mm} λ(权重衰减),μ(动量), 居中,ε(epsilon) 初始化:v_0 ← 0(平方平均值), \textbf{b}_0 \leftarrow 0 \text{(缓冲区)}, \: g^{ave}_0 \leftarrow 0 &\rule{110mm}{0.4pt} \\ for t=1 到 ... do g_t ← ∇_θ f_t (θ_{t-1}) \\ 若 \(\lambda \neq 0\) \(g_t \leftarrow g_t + \lambda \theta_{t-1}\) v_t ← αv_{t-1} + (1 - α)g^2_t \hspace{8mm} \\ 空格 8 毫米 \\ &\hspace{5mm} ˜v_t ← v_t \\ &\hspace{5mm}如果居中 g^{ave}_t ← g^{ave}_{t-1} α + (1-α) g_t &\hspace{10mm} \tilde{v_t} \leftarrow \tilde{v_t} - \big(g^{ave}_{t} \big)^2 \\ 翻译:&\hspace{10mm} \tilde{v_t} \leftarrow \tilde{v_t} - \big(g^{ave}_{t} \big)^2 \\ 如果 μ > 0 &\hspace{10mm} \textbf{b}_t \leftarrow \mu \textbf{b}_{t-1} + g_t/ \big(\sqrt{\tilde{v_t}} + \epsilon \big) \\ g_t/(\sqrt{\tilde{v_t}} + \epsilon ) \\ &\hspace{10mm} θ_t ← θ_{t-1} - γb_t 否则 \\ θ_t ← θ_{t-1} - γ g_t/ (√˜v_t + ε) \hspace{3mm} \\ &\规则{110 毫米}{0.4 点} \\[-1.ex] &\bf{return} \: \theta_t \\[-1.ex] &\规则{110 毫米}{0.4 点} \\[-1.ex] \end{aligned} 有关算法的更多详细信息,请参阅 G. Hinton 的《讲座笔记 `_ 并居中的版本《生成序列 使用循环神经网络 `_。 这里实现的是在计算梯度平均值之前取其平方根 添加 epsilon(请注意,TensorFlow 交换了这两个操作)。有效 学习率因此为::math:`\gamma/(\sqrt{v} + \epsilon)` 其中 :math:`\gamma` 预定的学习率,其中:math:`v` 是加权移动平均 平方梯度的值。 "文档" + rf"" 参数: {_params_doc} lr (float, Tensor, 可选): 学习率(默认:1e-2) alpha (float, 可选): 平滑常数(默认:0.99) eps (float, 可选): 添加到分母中的项,以改善 数值稳定性(默认:1e-8) 权重衰减(float,可选):权重衰减(L2 惩罚)(默认:0) momentum (float, 可选): 动量因子(默认:0) 中心化(bool,可选):如果为 ``True``,则计算中心化 RMSProp, 梯度通过其方差的估计进行归一化 {_可捕获文档} {_foreach_doc} {_maximize_doc} {_可区分文档} "文档" ) 定义 _single_tensor_rmsprop( 参数: 列表[张量] 梯度: 列表[张量] 平方平均值: 列表[张量] grad_avgs: 列表[张量] 动量缓冲区列表: 列表[张量] 状态步数: 列表[张量] *, 学习率: float, 阿尔法: float, eps: float, 权重衰减: float, 动量: float, 居中: 布尔, 最大化: 布尔, 可微分的: 布尔, 可捕捉的: 布尔, 有复杂的: 布尔, ): for i, 参数 列举(参数): 步骤 = 状态步数[i] 如果编译,编译器将处理 cudagraph 检查,参见注释[torch.compile x capturable] 如果 torch.编译器.is_compiling() 可捕捉的: 可捕获支持的设备 = _获取可捕获的设备() 断言 ( 参数.设备.类型 == 步长.设备.类型 参数.设备.类型 可捕获支持的设备 ), f如果 capturable=True,则 params 和 state_steps 必须在支持的设备上:{支持捕获的设备} 梯度 = 梯度[i] 梯度 = 梯度 如果 最大化 否则 -梯度 平方平均值 = 平方平均值[i] 步骤 += 1 如果 权重衰减 != 0: 梯度 = 研究生.添加(参数, 阿尔法=权重衰减) 是否为复杂参数 = torch.是复杂的(参数) 如果 是否为复杂参数: 参数 = torch.真实查看(参数) 梯度 = torch.真实查看(研究生) 平方平均值 = torch.真实查看(平方平均值) 平方平均值.mul_(阿尔法).addcmul_(研究生, 研究生, =1 - 阿尔法) 如果 居中: 平均成绩 = 平均成绩列表[i] 如果 是否为复杂参数: 平均毕业成绩 = torch.真实查看(平均毕业成绩) 平均毕业成绩.线性插值 _(研究生, 1 - 阿尔法) 平均值 = 平方平均值.添加乘法(毕业平均, 毕业平均, =-1).sqrt_() else: 平均值 = 平方平均值.平方根() 如果 可微分的: 平均 = 平均.添加(eps) else: 平均 = 平均.加_(eps) 如果 动量 > 0: 缓冲区 = 动量缓冲列表[i] 如果 是否为复杂参数: 缓冲区 = torch.真实查看(缓冲区) 缓冲区.mul_(动量).addcdiv_(研究生, 平均) 参数.加_(缓冲区, 阿尔法=-学习率) else: 参数.addcdiv_(研究生, 平均, =-学习率) 定义 _多张量 RMSprop( 参数: 列表[张量] 梯度: 列表[张量] 平方平均值: 列表[张量] 梯度平均值: 列表[张量] 动量缓冲区列表: 列表[张量] 状态步数: 列表[张量] *, 学习率: float, 阿尔法: float, eps: float, 权重衰减: float, 动量: float, 居中: 布尔, 最大化: 布尔, 可微分的: 布尔, 可捕捉的: 布尔, 有复杂的: 布尔, ): 如果 长度(参数) == 0: 返回 断言 可微分的, "_foreach 操作不支持自动求导" 如果编译,编译器将处理 cudagraph 检查,参见注释[torch.compile x capturable] 如果 torch.编译器.is_compiling() 可捕捉的: 可捕获支持的设备 = _获取可捕获的设备() 断言 所有( p.设备.类型 == 步长.设备.类型 p.设备.类型 可捕获支持的设备 for p, 步骤 zip(参数, 状态步数) ), f如果 capturable=True,则 params 和 state_steps 必须在支持的设备上:{支持捕获的设备} 分组张量 = 优化器.按设备类型和数据类型分组张量( [参数, 梯度, 平方平均值, 平均梯度, 动量缓冲区列表, 状态步数] # type: ignore[list-item] ) for ( ( 分组参数_, 分组梯度_, 分组平方平均, 分组梯度平均, 分组动量缓冲区列表_, 分组状态步骤_, ) ), _ 分组张量.(): 分组参数 = 角色(列表[张量] 分组参数_) 分组梯度 = 角色(列表[张量] 分组梯度_) 分组平方平均值 = 角色(列表[张量] 分组平方平均值_) 分组状态步骤 = 角色(列表[张量] 分组状态步骤_) 如果 有复杂的: 状态和梯度 = [分组梯度, 分组平方平均值] 如果 动量 > 0: 分组动量缓冲列表 = 角色( 列表[张量] 分组动量缓冲列表_ ) 状态与梯度.append(分组动量缓冲区列表) 如果 居中: 分组梯度平均值 = 角色(列表[张量] 分组梯度平均值_) 状态与梯度.append(分组梯度平均值) 真实查看(分组参数, *状态与梯度) 如果 最大化: 分组梯度 = torch._foreach_neg(分组梯度) # 类型:忽略[赋值] # 更新步骤 # 如果步骤在 CPU 上,foreach 将回退到慢速路径,即通过循环调用 t.add(1) #然后 1 会被反复包裹成 Tensor,这比只包裹一次要慢。 #alpha 是必须的,以确保我们进入正确的重载。 如果 torch.编译器.is_compiling() 分组状态步骤[0].是 CPU: torch._foreach_add_( 分组状态步骤, torch.张量(1.0, 设备="cpu"), 阿尔法=1.0 ) else: torch._foreach_add_(分组状态步骤, 1) 如果 权重衰减 != 0: 重复使用已分配给最大化操作的中间内存(grouped_grads) 如果 最大化: torch._foreach_add_(分组梯度, 分组参数, 阿尔法=权重衰减) else: 分组梯度 = torch._foreach_add_( # 类型:忽略[赋值] 分组梯度, 分组参数, 阿尔法=权重衰减 ) torch._foreach_mul_(分组平方平均值, 阿尔法) torch._foreach_addcmul_( 分组平方平均值, 分组梯度, 分组梯度, =1 - alpha ) 如果 居中: 分组梯度平均值 = 角色(列表[张量] 分组梯度平均值_) torch._foreach_lerp_(分组梯度平均值, 分组梯度, 1 - 阿尔法) 平均值 = torch._foreach_addcmul( 分组平方平均值, 分组梯度平均值, 分组梯度平均值, =-1 ) torch._foreach_sqrt__(平均值) torch._foreach_add_(平均, eps) else: 平均 = torch._foreach 平方根(分组平均平方) torch._foreach_add_(平均, eps) 如果 动量 > 0: 分组动量缓冲区列表 = 角色( 列表[张量] 分组动量缓冲区列表_ ) torch._foreach_mul_(分组动量缓冲区列表, 动量) torch._foreach_addcdiv_(分组动量缓冲区列表, 分组梯度, 平均值) 如果 LR 是一个张量,else 分支将内部调用 item() 这将导致在捕获时出现无声的错误 如果 可捕获的 isinstance(学习率, torch.张量): 动量学习率 = torch._foreach_mul(分组动量缓冲区列表, -学习率) torch._foreach_add_(分组参数, 动量学习率) else: torch._foreach_add_( 分组参数, 分组动量缓冲区列表, 阿尔法=-左右 ) else: 如果 LR 是一个张量,else 分支将内部调用 item() 这将导致在捕获时出现无声的错误 如果 可捕获的 isinstance(学习率, torch.张量): torch._foreach_div_(平均值, -学习率) torch._foreach_addcdiv_(分组参数, 分组梯度, 平均) else: torch._foreach_addcdiv_(分组参数, 分组梯度, 平均, =-学习率) @_disable_dynamo_if_unsupported(单个张量函数=_单张张量_rmsprop) 定义 rmsprop( 参数: 列表[张量] 梯度: 列表[张量] 平方平均值: 列表[张量] 平均梯度: 列表[张量] 动量缓冲区列表: 列表[张量] 状态步数: 列表[张量] 使用 torchscript 编译的函数不支持带默认值的只写关键字参数问题 #70627 现由 torch/distributed/optim 编译的函数 API 参数 foreach: 可选[布尔] = , 最大化: 布尔值 = 错误, 可微分的: 布尔值 = 错误, 可捕捉的: 布尔值 = 错误, 有复杂的: 布尔值 = 错误, *, 学习率: float, 阿尔法: float, eps: float, 权重衰减: float, 动量: float, 居中: 布尔, ): r执行 rmsprop 算法计算的函数式 API。 查看 :class:`~torch.optim.RMSProp` 以获取详细信息。 "文档" 此检查在编译期间较慢,因此我们跳过它。 如果确实需要,我们可以在 dynamo 中添加此检查。 如果 torch.编译器.is_compiling() 所有( isinstance(t, torch.张量) for t 状态步骤 ): 提升 运行时错误( "API 已更改,`state_steps`参数必须包含一个单例张量列表" ) 如果 foreach : _, foreach = 默认为融合或遍历( 参数, 可微分的, 使用融合的= ) 如果 foreach torch.算子.是否正在脚本化(): 提升 运行时错误("torch.jit.script 不支持 foreach 优化器") 如果 foreach torch.算子.是否正在脚本化(): 函数 = 多张量 RMSprop else: 函数 = 单张量 RMSprop 函数( 参数, 梯度, 平方平均值, 梯度平均值, 动量缓冲区列表, 状态步数, 学习率=学习率, 阿尔法=阿尔法, eps=eps, 权重衰减=权重衰减, 动量=动量, 居中=居中, 最大化=最大化, 可捕捉的=可捕捉的, 可微分的=可微分的, 有复杂的=有复杂的, )

© 版权所有 PyTorch 贡献者。

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

文档

查看 PyTorch 的全面开发者文档

查看文档

教程

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

查看教程

资源

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

查看资源