torch.distributions.utils 的源代码
# mypy: 允许未类型化定义
from functools 导入
update_wrapper 函数
from 打字
导入
任何,
可调用,
通用,
过载,
联合
from typing_extensions 导入
类型变量
导入
火炬
导入 torch.nn.functional
是 F
from 火炬
导入
张量
from torch.overrides 导入
类似于 tensor
from torch.types 导入
数值
欧拉常数 = 0.57721566490153286060
欧拉-马斯刻罗尼常数
全部 = [
广播所有,
logits 转概率,
概率裁剪,
概率转 logits,
懒加载属性,
"tril_matrix_to_vec",
"vec_to_tril_matrix",
]
def 广播全部(*
值):
r""
给定一个值列表(可能包含数字),返回一个列表,其中每个值根据以下规则进行广播:
值根据以下规则进行广播:
- `torch.*Tensor` 实例按照 :ref:`_broadcasting-semantics` 进行广播。
- 数字实例(标量)被提升为与第一个传递给 `values` 的张量具有相同大小和类型的张量。
如果所有值都是标量,则它们被提升为标量张量。
如果所有值都是标量,则它们被提升为标量张量。
参数:
值(`Number`列表、`torch.*Tensor`或实现`__torch_function__`的对象)
抛出异常:
ValueError:如果任何值不是`Number`实例,
`torch.*Tensor`实例,或实现`__torch_function__`的对象
""
如果
不是
所有(
是否与张量类似(v)
或者 isinstance(v,
数)
为 v
在
值):
提升 ValueError(
输入参数必须全部是`Number`实例的实例
"torch.Tensor 或实现 __torch_function__ 的对象。"
)
如果
不是
所有(
是否与张量类似(v)
为 v
在
值):
选项:
字典[
字符串,
任何] =
字典(
数据类型=
火炬.
获取默认数据类型())
为
值
在
值:
如果 isinstance(
值,
火炬.
张量):
选项 =
字典(
数据类型=
值.
数据类型,
设备=
值.
设备)
断开
新值 = [
v 如果
是否与张量类似(v)
否则
火炬.
张量(v, **
选项)
为 v
在 values
]
返回
火炬.
广播张量(*
新值)
返回
火炬.
广播张量(*
值)
def 标准正态(
形状,
数据类型,
设备):
如果
火炬._C.
_获取追踪状态():
# [JIT 临时解决方案] 不支持 .normal_() 方法
返回
火炬.
正常(
火炬.
零值(
形状,
数据类型=
数据类型,
设备=
设备),
火炬.
一(
形状,
数据类型=
数据类型,
设备=
设备),
)
返回
火炬.
空的(
形状,
数据类型=
数据类型,
设备=
设备).
正常的()
def _sum_rightmost(值,
暗):
r""
从给定的张量中求出最右侧的 `dim` 个维度之和。
参数:
value(张量):一个维度至少为 `dim` 的张量。
dim(整数):要减去的最右侧维度的数量。
""
如果
维度 == 0:
返回
值
required_shape = 值.
形状
[-
暗] + (-1,)
返回
值.
重塑(
所需形状).
总和(-1)
def logits 转概率(logits,
是否二进制=
错误):
r""
将 logits 张量转换为概率。注意,对于
二进制案例,每个值表示对数几率,而对于
多维情况,最后维度的值表示
事件的日志概率(可能未归一化)。
""
如果
是否二进制:
返回
火炬.
Sigmoid 函数(logits)
返回 F.
软式最大化(logits,
暗=-1)
def clamp_probs(概率):
将概率限制在开区间(0,1)内。
概率将被限制在 `eps` 和 `1 - eps` 之间,
其中 `eps` 将是输入数据类型能表示的最小正数。
参数:
probs (Tensor):一个概率张量。
返回:
Tensor:夹紧的概率。
示例:
>>> probs = torch.tensor([0.0, 0.5, 1.0])
>>> clamp_probs(probs)
tensor([1.1921e-07, 5.0000e-01, 1.0000e+00])
>>> probs = torch.tensor([0.0, 0.5, 1.0], dtype=torch.float64)
>>> clamp_probs(probs)
tensor([2.2204e-16, 5.0000e-01, 1.0000e+00], dtype=torch.float64)
""
eps = 火炬.finfo(
概率.
数据类型).eps
返回
概率.
卡钳(
最小值=eps,
最大值=1 - eps)
def 概率转对数概率(
概率,
是否二进制=
错误):
r""
将概率张量转换为 logits。对于二进制情况,
这表示索引为`1`的事件发生的概率。
对于多维情况,最后一个维度上的值表示每个事件发生的概率。
这些值表示每个事件发生的概率。
""
ps_clamped = clamp_probs(概率)
如果
是否二进制:
返回
火炬.
日志(ps_clamped) -
火炬.log1p(-ps_clamped)
返回
火炬.
日志(ps_clamped)
T = 类型变量(
T,
反变=
是)
R = 类型变量("R",
协变=
是)
类
懒属性(
通用[T, R
)]
r""
用作类属性的懒加载装饰器。这使用了
非数据描述符,调用包装方法来计算属性
第一次调用;之后将包装方法替换为实例
属性。
""
def __init__(self, 包装:
可调用[[T
] R])
翻译
无:
self.包装:
可调用[[T
] R] =
包装
更新包装器(self,
包装)
# 类型:忽略[arg-type]
@overload
def __get__(
self, 实例:
无,
对象类型:
任何 =
无
) 翻译
"_延迟属性和属性[T, R]": ...
@overload
def __get__(self, 实例: T,
对象类型:
任何 =
无)
翻译 R: ...
def __get__(
self, 实例:
联合[T,
无
]
对象类型:
任何 =
无
) 翻译
"R | _懒属性和属性[T, R]":
如果
实例 is
无:
返回
懒属性与属性(self.
包装)
与
火炬.
启用梯度():
值 = self.
包装(
实例)
setattr(实例, self.
包装.__name__,
值)
返回
值
类
懒属性与属性(
懒属性[T, R
]
属性):
我们希望懒属性看起来像多个东西。
* 当 Sphinx 自动文档生成时,它看起来像属性
当 Distribution 验证参数时,* lazy_property
""
def __init__(self, 包装:
可调用[[T
] R])
翻译
无:
属性.__init__(self,
包装)
def tril_matrix_to_vec(矩阵:
张量, diag:
整型 = 0)
翻译
张量:
r""
将一个 `D x D` 矩阵或矩阵批转换为(批处理)向量
该向量包含矩阵中的下三角元素,按行顺序排列。
""
n = 矩阵.
形状[-1]
如果
不是
火炬._C.
_获取追踪状态()
和 (diag < -n
或者 diag
≥ n):
提升 ValueError(f
"diag("{diag}
)提供的是在[{-n}, {n - 1}
“。”)
arange = 火炬.arange(n,
设备=
矩阵.
设备)
tril_mask = arange < arange.视图(-1, 1) + (diag + 1)
vec = 矩阵[..., tril_mask]
返回 vec
def vec_to_tril_matrix(向量:
张量, diag:
整型 = 0)
翻译
张量:
r""
将向量或向量批转换为批量的 `D x D`
包含向量元素按行顺序的低位三角形矩阵。
""
D**2 + (1+2*diag)*D - |diag| * (diag+1) - 2*vec.shape[-1] = 0 的正根
n = (
-(1 + 2 * diag)
+ ((1 + 2 * diag) ** 2 + 8 * 向量.
形状[-1] + 4 *
绝对值(diag) * (
对角线 + 1)) ** 0.5
) / 2
eps = 火炬.finfo(
向量.
数据类型).eps
如果
不是
火炬._C.
_获取追踪状态()
和 (
四舍五入(n) - n > eps):
提升 ValueError(
f"最后一维的大小是"{
向量.
形状[-1]}
无法用“”表示的
+ "一个 D x D 方阵的下三角部分。"
)
n = 四舍五入(n.
项目())
如果 isinstance(n,
火炬.
张量)
否则
四舍五入(n)
矩阵 =
向量.
新零(
向量.
形状
[-1] +
火炬.
尺寸((n, n)))
arange = 火炬.arange(n,
设备=
向量.
设备)
三角掩码 =
等差数列 < arange.
视图(-1, 1) + (
对角线 + 1)
矩阵[...,
三角掩码] = vec
返回 mat