快捷键

torch.optim.adadelta 的源代码

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

导入 火炬
from 火炬 导入 张量

from .optimizer 导入 (
    _capturable_doc,
    _default_to_fused_or_foreach,
    _可微文档,
    _如果不受支持则禁用 Dynamo,
    _foreach 文档,
    _获取可捕获的受支持设备,
    获取标量数据类型,
    最大化文档,
    参数文档,
    使用梯度进行可微分,
    真实查看,
    优化器,
    参数 T,
)


全部 = ["Adadelta", adadelta]


[文档] Adadelta(优化器): def __init__( , 参数: 参数 T, 学习率: 并集[float, 张量] = 1.0, 拉欧: 浮点数 = 0.9, eps: 浮点数 = 1e-6, 权重衰减: 浮点数 = 0, foreach: 可选[布尔] = , *, 可捕获的: 布尔值 = 错误, 最大化: 布尔值 = 错误, 可微分的: 布尔值 = 错误, ): 如果 isinstance(学习率, 张量) 学习率.元素数量() != 1: 提升 ValueError("Tensor 学习率必须为 1 个元素") 如果 0.0 <= 学习率: 提升 ValueError(f"无效的学习率:"{学习率}") 如果 0.0 <= 拉索 <= 1.0: 提升 ValueError(f"无效的 rho 值:"{拉欧}") 如果 0.0 <= eps: 提升 ValueError(f"无效的 epsilon 值:"{eps}") 如果 0.0 <= 权重衰减: 提升 ValueError(f"无效的权重衰减值:"{权重衰减}") 默认 = 字典( 学习率=lr, 拉欧=拉欧, eps=eps, weight_decay=weight_decay, maximize=最大化, 可捕获的=可捕获的, foreach=foreach, 可区分的=可微的, ) 超级().__init__(参数, 默认值) def __setstate__(, 状态): 超级().__setstate__(状态) 群组 .参数组: 群组.setdefault(foreach, ) 群组.setdefault(最大化, 错误) 群组.setdefault(可微分的, 错误) 群组.setdefault(可捕获的, 错误) p 群组[参数]: 状态变量 = .状态.获取(p, [] 如果 长度(状态) != 0 火炬.is_tensor(状态[步骤)] 步骤值 = float(状态[步骤]) 状态[步骤] = ( 火炬.张量( 步值, 数据类型=获取标量数据类型(), 设备=p.设备 ) 如果 群组[可捕获的] 否则 火炬.张量(步值, 数据类型=获取标量数据类型()) ) def 初始化组( , 群组: 字典[字符串, 任何] 带梯度的参数: 列表[张量] 梯度: 列表[张量] 平方平均值: 列表[张量] acc_deltas: 列表[张量] state_steps: 列表[张量] ): has_complex = p: 张量 p 群组["params"]: 如果 p.梯度 is : continue 复杂的参数 |= 火炬.是复杂的(p) 带梯度的参数.append(p) 如果 p.研究生.is_sparse: 提升 运行时错误(Adadelta 不支持稀疏梯度) 梯度.append(p.研究生) 状态 = .状态[p] 懒惰状态初始化 如果 长度(状态) == 0: 状态[步骤] = ( 火炬.零值((), 数据类型=_获取标量数据类型(), 设备=p.设备) 如果 群组[可捕获的] 否则 火炬.零值((), 数据类型=_获取标量数据类型()) ) 状态["square_avg"] = 火炬.等于零的( p, 内存格式=火炬.保留格式 ) 状态["acc_delta"] = 火炬.等于零的( p, 内存格式=火炬.保留格式 ) 平方平均值.append(状态[平方平均]) 累加差分.append(状态[累加差分值]) 状态步骤.append(状态[步骤]) 返回 具有复杂
[文档] @_use_grad_for_differentiable def 步长(, 闭包=): 执行单个优化步骤。 参数: 闭包(Callable,可选):一个重新评估模型并返回损失的闭包 和返回损失。 "文档" ._cuda_graph_capture_health_check() 损失 = 如果 闭包 is : 火炬.启用梯度(): 损失 = 闭包() 群组 .参数组: 带梯度的参数: 列表[张量] = 输入文本为空,请提供需要翻译的文本 梯度: 列表[张量] = 输入文本为空,请提供需要翻译的文本 平方平均值: 列表[张量] = 输入文本为空,请提供需要翻译的文本 累加差分: 列表[张量] = 输入文本为空,请提供需要翻译的文本 状态步骤: 列表[张量] = 输入文本为空,请提供需要翻译的文本 ( 学习率, 拉欧, eps, 权重衰减, foreach, 最大化, 可微的, 可捕捉的, ) = ( 群组["lr"] 群组["rho"] 群组[eps] 群组[权重衰减] 群组[foreach] 群组[最大化] 群组[可微分的] 群组[可捕获的] ) 具有复杂的 = ._初始化组( 群组, params_with_grad, 梯度, 平方平均值, 累加差分, 状态步数 ) adadelta( 带梯度参数, 梯度, 平方平均值, 累积变化量, 状态步数, lr=lr, 拉欧=拉欧, eps=eps, 权重衰减=权重衰减, foreach=foreach, 最大化=最大化, 可微分的=可微分的, 可捕捉的=可捕捉的, 结构复杂的=具有复杂结构, ) 返回 损失
Adadelta.__doc__ = ( r实现 Adadelta 算法。 .. math:: \begin{aligned} &\rule{110mm}{0.4pt} \\ &\textbf{输入} : \gamma \text{ (lr)}, \: \theta_0 \text{ (参数)}, \: f(\theta) \text{ (目标函数)}, \: \rho \text{ (衰减)}, \: \lambda \text{ (权重衰减)} \\ 初始化:v_0 ← 0(平方平均) \( u_0 \leftarrow 0 \) (累加变量) &\rule{110mm}{0.4pt} \\ for t=1 到 ... do g_t ← ∇_θ f_t (θ_{t-1}) \\ λ ≠ 0 \\ g_t ← g_t + λ θ_{t-1} \\ v_t ← v_{t-1} ρ + g^2_t (1 - ρ) \\ &\hspace{5mm}Δx_t ← \frac{\sqrt{u_{t-1} +}}{}} \epsilon }}{ \sqrt{v_t + \epsilon} }g_t u_t ← u_{t-1} ρ + Δx^2_t (1 - ρ) &\hspace{5mm}\theta_t \leftarrow \theta_{t-1} - \gamma \Delta x_t \\ &\rule{110mm}{0.4pt} \\[-1.ex] &\bf{return} \: \theta_t \\[-1.ex] &\rule{110mm}{0.4pt} \\[-1.ex] \end{aligned} 有关算法的更多详细信息,请参阅《ADADELTA:自适应学习率方法》_。 "文档" + rf"" 参数: {_params_doc} lr (float, Tensor, optional): 系数,用于在应用之前缩放 delta 到参数(默认:1.0) rho (float, 可选): 用于计算移动平均的系数 平方梯度的系数(默认:0.9)。`rho`的值越高, 导致平均速度较慢,这有助于防止学习过程中的振荡。 eps(浮点数,可选):添加到分母中的项,以提高数值稳定性(默认:1e-6)。 eps(浮点数,可选):添加到分母中的项,以提高数值稳定性(默认:1e-6)。 eps(浮点数,可选):添加到分母中的项,以提高数值稳定性(默认:1e-6)。 weight_decay (浮点数,可选): 权重衰减(L2 惩罚)(默认:0) {_foreach_doc} {_capturable_doc} {_maximize_doc} {_可微文档} .. _ADADELTA:自适应学习率方法: https://arxiv.org/abs/1212.5701 "文档" ) def _单张张量_adadelta( 参数: 列表[张量] 梯度: 列表[张量] 平方平均值: 列表[张量] acc_deltas: 列表[张量] 状态步骤: 列表[张量] *, 学习率: float, 拉欧: float, eps: float, 权重衰减: float, 最大化: 布尔, 可微分的: 布尔, 可捕获的: 布尔, 复杂的: 布尔, ): 如果编译,编译器将处理 cudagraph 检查,参见注释[torch.compile x capturable] 如果 火炬.编译器.正在编译() 可捕获的: 可捕获支持的设备 = _获取可捕获支持的设备( 支持_xla= ) 断言 所有( p.设备.类型 == 步长.设备.类型 p.设备.类型 支持捕获的设备 p, 步骤 zip(参数, 状态步骤) ), f如果 capturable=True,则 params 和 state_steps 必须在支持设备上:{可捕获支持的设备} 参数, 研究生, 平均平方, 加速度变化量, 步数 zip( 参数, 梯度, 平方平均值, 累积变化量, 状态步数 ): 步骤 += 1 梯度 = 梯度 如果 最大化 否则 -梯度 如果 权重衰减 != 0: 梯度 = 研究生.添加(参数, 阿尔法=权重衰减) 如果 火炬.是复杂的(参数): 平方平均值 = 火炬.真实查看(平方平均值) 准确度变化量 = 火炬.真实查看(逐差) 梯度 = 火炬.真实查看(研究生) 平方平均值.mul_(拉欧).加减乘(研究生, 研究生, =1 - 拉欧) std = 平方平均值.添加(eps).sqrt_() delta = acc_delta.添加(eps).sqrt_() 如果 differentiable: delta = Δ.克隆() Δ.div_(标准的).mul_(研究生) acc_delta.mul_(拉欧).addcmul_(Δ, Δ, =1 - 拉欧) 如果 火炬.是复杂的(参数): delta = 火炬.以复数视图查看(Δ) 参数.加_(Δ, 阿尔法=-lr) def _多张量 adadelta( 参数: 列表[张量] 梯度: 列表[张量] 平方平均值: 列表[张量] acc_deltas: 列表[张量] 状态步骤: 列表[张量] *, 学习率: float, 拉欧: float, eps: float, 权重衰减: float, 最大化: 布尔, 可微分的: 布尔, 可捕捉的: 布尔, 有复杂的: 布尔, ): 断言 可微, "_foreach 操作不支持自动微分" # 如果正在编译,编译器将处理 cudagraph 检查,参见注解[torch.compile x capturable] 如果 火炬.编译器.正在编译() 可捕获的: 支持的设备 = _获取支持的设备( 支持 XLA= ) 断言 所有( p.设备.类型 == 步长.设备.类型 p.设备.类型 可捕获支持的设备 p, 步骤 zip(参数, 状态步骤) ), f如果 capturable=True,则 params 和 state_steps 必须在支持的设备上:{capturable 支持的设备} 如果 长度(参数) == 0: 返回 分组张量 = 优化器.按设备类型和数据类型分组张量( [参数, 梯度, 平方平均值, 累加差分, 状态步骤] # type: ignore[list-item] ) ( 设备参数_, 设备梯度_, 设备平方平均值_, 设备加速度变化量_, 设备状态步骤_, ), _ 分组张量.(): 设备参数 = 角色(列表[张量] 设备参数_) 设备梯度 = 角色(列表[张量] device_grads_) device_square_avgs = 角色(列表[张量] device_square_avgs_) device_acc_deltas = 角色(列表[张量] 设备加速度增量_) 设备状态步数 = 角色(列表[张量] 设备状态步数_) 如果 是否复杂: 真实查看( 设备参数, 设备梯度, 设备平方平均值, 设备加速度变化 ) 更新步骤 如果步骤在 CPU 上,foreach 将回退到慢速路径,即调用 t.add(1)的 for 循环,一次又一次地 1 将被一次又一次地包裹成 Tensor,这比如果我们只是 现已包裹一次。alpha 是必需的,以确保我们进入正确的重载。 如果 火炬.编译器.is_compiling() 设备状态步骤[0].是 CPU: 火炬._foreach_add_( 设备状态步骤, 火炬.张量(1.0, 设备="cpu"), 阿尔法=1.0 ) else: 火炬._foreach_add_(设备状态步骤, 1) 如果 最大化: 设备梯度 = 火炬._foreach_neg(设备梯度) # 类型:忽略[赋值] 如果 权重衰减 != 0: 重新使用为最大化分配的中间内存(device_grads) 如果 最大化: 火炬._foreach_add_(device_grads, 设备参数, 阿尔法=权重衰减) else: 设备梯度 = 火炬._foreach_add( # 类型:忽略[赋值] 设备梯度, 设备参数, 阿尔法=权重衰减 ) 火炬._foreach_mul_(设备平方平均值, 拉欧) 火炬._foreach_addcmul_( 设备平方平均值, 设备梯度, 设备梯度, =1 - 拉索 ) std = 火炬._foreach_add_(设备平方平均值, eps) 火炬._foreach_sqrt__(标准的) 跨度 = 火炬._foreach_add_(设备加速度跨度, eps) 火炬._foreach_sqrt__(跨度) 火炬._foreach_div_(跨度, 标准的) 火炬._foreach_mul_(跨度, 设备梯度) 火炬._foreach_mul_(设备加速度跨度, 拉欧) 火炬._foreach_addcmul_(device_acc_deltas, deltas, deltas, =1 - 拉欧) 如果 LR 是一个张量,else 分支将内部调用 item() 这将导致在捕获时出现无声的错误 如果 可捕获的 isinstance(lr, 火炬.张量): 火炬._foreach_mul_(deltas, -lr) 火炬._foreach_add_(设备参数, 跨度) else: 火炬._foreach_add_(设备参数, 跨度, 阿尔法=-lr) @_disable_dynamo_if_unsupported(单一张量函数=_单一张量_adadelta) def adadelta( 参数: 列表[张量] 梯度: 列表[张量] 平方平均值: 列表[张量] 累加差分: 列表[张量] 状态步数: 列表[张量] 使用 torchscript 编译的函数不支持带默认值的只写关键字参数问题 #70627 现由 torch/distributed/optim 编译的函数 API 参数 可捕获的: 布尔值 = 错误, foreach: 可选[布尔] = , 可微分的: 布尔值 = 错误, 具有复杂的: 布尔值 = 错误, *, lr: float, 拉欧: float, eps: float, 权重衰减: float, 最大化: 布尔, ): r执行 Adadelta 算法计算的函数 API。 请参阅:class:`~torch.optim.Adadelta` 以获取详细信息。 "文档" 此检查在编译期间较慢,因此我们跳过它。 如果确实需要,我们可以在 dynamo 中添加此检查。 如果 火炬.编译器.正在编译() 所有( isinstance(t, 火炬.张量) t 状态步骤 ): 提升 运行时错误( "API 已更改,`state_steps`参数必须包含一个单例张量列表" ) # 我们仍然尊重用户对 foreach 输入 False 的情况。 如果 foreach is : _, foreach = _default_to_fused_or_foreach( 参数, 可微分的, 使用融合的= ) 如果 foreach 火炬.算子.是否正在脚本化(): 提升 运行时错误("torch.jit.script 不支持 foreach 优化器") 如果 foreach 火炬.算子.是否正在脚本化(): 函数 = _multi_tensor_adadelta else: 函数 = 单个张量_adadelta 函数( 参数, 梯度, 平方平均值, 累积梯度, 状态步数, lr=lr, 拉欧=拉欧, eps=eps, 权重衰减=权重衰减, 最大化=最大化, 可微分的=可微分的, 可捕捉的=可捕捉的, 有复杂的=有复杂的, )

© 版权所有 PyTorch 贡献者。

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

文档

查看 PyTorch 的全面开发者文档

查看文档

教程

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

查看教程

资源

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

查看资源