• 文档 >
  • 模块代码 >
  • torch >
  • torch.distributions.lowrank_multivariate_normal
快捷键

torch.distributions.lowrank_multivariate_normal 的源代码

# mypy: 允许未类型化定义
导入 数学

导入 火炬
from 火炬 导入 张量
from torch.distributions 导入 约束
from torch.distributions.distribution 导入 分布
from torch.distributions.multivariate_normal 导入 _batch_mahalanobis, 批量移动
from torch.distributions.utils 导入 标准正态, 懒加载属性
from torch.types 导入 _大小


全部 = [低秩多元正态分布]


定义 批量电容三角(W, D):
    r```python
# 假设输入文本为:
input_text = """Immersive Translate"""

# 翻译函数(此处仅为示例,实际翻译功能需要调用真实的翻译 API)
def translate_to_simplified_chinese(text):
    # 这里应该调用真实的翻译 API 进行翻译
    # 由于示例中不使用真实的 API,以下为模拟翻译结果
    return text  # 假设翻译结果与原文相同

# 输出翻译结果
translated_text = translate_to_simplified_chinese(input_text)
print(translated_text)
```

输出:
```
Immersive Translate
```
计算矩阵批量的 Cholesky 分解::math:`I + W.T @ inv(D) @ W`
以及向量批量的 :math:`D`。
    """
    m = W.大小(-1)
    Wt_Dinv = W.mT / D.展平(-2)
    K = 火炬.矩阵乘法(Wt_Dinv, W).连续()
    K.视图(-1, m * m)[:, :: m + 1] += 1  # 添加单位矩阵到 K
    return 火炬.线性代数.转置分解(K)


定义 _batch_lowrank_logdet(W, D, 电容_tril):
    r```python
# 假设输入文本为:
input_text = """Immersive Translate"""

# 翻译函数(此处仅为示例,实际翻译功能需要调用真实的翻译 API)
def translate_to_simplified_chinese(text):
    # 这里应该调用真实的翻译 API 进行翻译
    # 由于示例中不使用真实的 API,以下为模拟翻译结果
    return text  # 假设翻译结果与原文相同

# 输出翻译结果
translated_text = translate_to_simplified_chinese(input_text)
print(translated_text)
```

输出:
```
Immersive Translate
```
使用“矩阵行列式引理”
log|W @ W.T + D| = log|C| + log|D|,
其中:math:`C` 是电容矩阵:math:`I + W.T @ inv(D) @ W`,用于计算
对数行列式。
    """
    return 2 * 电容三重积分.对角线(dim1=-2, dim2=-1).日志().总和(-1) + D.日志().总和(
        -1
    )


定义 _低秩马氏距离批处理(W, D, x, 电容三重积分):
    r```python
# 假设输入文本为:
input_text = """Immersive Translate"""

# 翻译函数(此处仅为示例,实际翻译功能需要调用真实的翻译 API)
def translate_to_simplified_chinese(text):
    # 这里应该调用真实的翻译 API 进行翻译
    # 由于示例中不使用真实的 API,以下为模拟翻译结果
    return text  # 假设翻译结果与原文相同

# 输出翻译结果
translated_text = translate_to_simplified_chinese(input_text)
print(translated_text)
```

输出:
```
Immersive Translate
```
使用“Woodbury 矩阵恒等式”::
        inv(W @ W.T + D) = inv(D) - inv(D) @ W @ inv(C) @ W.T @ inv(D),
其中 :math:`C` 是电容矩阵 :math:`I + W.T @ inv(D) @ W`,用于计算平方
马氏距离 :math:`x.T @ inv(W @ W.T + D) @ x`。
    """
    Wt_Dinv = W.mT / D.展平(-2)
    Wt_Dinv_x = _批量移动(Wt_Dinv, x)
    马氏距离项 1 = (x.pow(2) / D).总和(-1)
    马氏距离项 2 = _批量马氏距离(电容三联, Wt_Dinv_x)
    return 马哈拉诺比斯项 1 - 马哈拉诺比斯项 2


[文档] 低秩多元正态分布(分发): r```python # 假设输入文本为: input_text = """Immersive Translate""" # 翻译函数(此处仅为示例,实际翻译功能需要调用真实的翻译 API) def translate_to_simplified_chinese(text): # 这里应该调用真实的翻译 API 进行翻译 # 由于示例中不使用真实的 API,以下为模拟翻译结果 return text # 假设翻译结果与原文相同 # 输出翻译结果 translated_text = translate_to_simplified_chinese(input_text) print(translated_text) ``` 输出: ``` Immersive Translate ``` 创建具有低秩形式的协方差矩阵的多变量正态分布 通过 :attr:`cov_factor` 和 :attr:`cov_diag` 参数化:: covariance_matrix = cov_factor @ cov_factor.T + cov_diag 示例: >>> # xdoctest: +REQUIRES(env:TORCH_DOCTEST_LAPACK) >>> # xdoctest: +IGNORE_WANT("非确定性") >>> m = LowRankMultivariateNormal( ... torch.zeros(2), torch.tensor([[1.0], [0.0]]), torch.ones(2) ... ) >>> m.sample() # 正态分布,均值为 `[0,0]`,协方差因子为 `[[1],[0]]`,协方差对角线为 `[1,1]` tensor([-0.2102, -0.5429]) 参数: loc (Tensor):分布的均值,形状为 `batch_shape + event_shape` cov_factor (Tensor):协方差矩阵低秩形式的因子部分,形状为 `batch_shape + event_shape + (rank,)` cov_diag (Tensor):协方差矩阵低秩形式的对角部分,形状为 `batch_shape + event_shape` 注意: 计算协方差矩阵的行列式和逆矩阵被避免 `cov_factor.shape[1] 小于 cov_factor.shape[0]` 多亏了 `Woodbury 矩阵恒等式` `《伍德伯里矩阵恒等式》`_ 和 矩阵行列式引理 _. 感谢这些公式,我们只需计算行列式和逆矩阵 小型“电容”矩阵:: 电容 = I + cov_factor.T @ inv(cov_diag) @ cov_factor """ 约束参数 = { "loc": 约束.实向量, cov_factor: 约束.独立(约束.真实, 2), cov_diag: 约束.独立(约束.正的, 1), } 支持 = 约束.实向量 has_rsample = 真实 定义 __init__(self, 位置, 疫情系数, 诊断协方差, 验证参数=): 如果 位置.() < 1: 抛出 值错误("位置至少需要为一维。") 事件形状 = 位置.形状[-1] 如果 疫情系数.() < 2: 抛出 值错误( "cov_factor 至少必须是二维的," "可选的批处理维度前缀" ) 如果 cov_factor.形状[-2:-1] != event_shape: 抛出 值错误( f"cov_factor 必须是一个形状的矩阵批处理"{event_shape[0]}x m ) 如果 协方差诊断.形状[-1] != event_shape: 抛出 值错误( f"协方差诊断必须是一个形状为向量的批次"{event_shape}" ) loc_ = 位置.展平(-1) cov_diag_ = cov_diag.展平(-1) 尝试: loc_, self.cov_factor, cov_diag_ = 火炬.广播张量( loc_, cov_factor, cov_diag_ ) 除了 运行时错误 e: 抛出 值错误( f"不兼容的批量形状:loc"{位置.形状}, cov_factor {cov_factor.形状}, cov_diag {疫情诊断.形状}" ) from e self.定位 = 定位_[..., 0] self.疫情诊断 = 疫情诊断_[..., 0] 批量形状 = self.位置.形状[-1] self.未广播的协方差因子 = 协方差因子 self.未广播的对角协方差 = 对角协方差 self.三倍电容 = 批量三倍电容(协方差因子, 协方差对角线) 超级().__init__(批量形状, event_shape, 验证参数=验证参数)
[文档] def expand(self, batch_shape, _instance=None): new = self._get_checked_instance(LowRankMultivariateNormal, _instance) batch_shape = torch.Size(batch_shape) loc_shape = batch_shape + self.event_shape new.loc = self.loc.expand(loc_shape) new.cov_diag = self.cov_diag.expand(loc_shape) new.cov_factor = self.cov_factor.expand(loc_shape + self.cov_factor.shape[-1:]) new._unbroadcasted_cov_factor = self._unbroadcasted_cov_factor new._unbroadcasted_cov_diag = self._unbroadcasted_cov_diag new._capacitance_tril = self._capacitance_tril super(LowRankMultivariateNormal, new).__init__( batch_shape, self.event_shape, validate_args=False ) new._validate_args = self._validate_args return new
@property 定义
均值(self) 翻译 张量: return self.定位 @property 定义 模式(self) 翻译 张量: return self.定位 @lazy_property 定义 方差(self) 翻译 张量: # 类型:忽略[覆盖] return ( self._unbroadcasted_cov_factor.pow(2).总和(-1) + self.未广播的协方差诊断 ).展开(self._批次形状 + self.事件形状) @lazy_property 定义 scale_tril(self) 翻译 张量: 以下标识符用于提高数值计算的稳定性 用于 Cholesky 分解(参见 http://www.gaussianprocess.org/gpml/,第 3.4.3 节): # W @ W.T + D = D1/2 @ (I + D-1/2 @ W @ W.T @ D-1/2) @ D1/2 # 矩阵 "I + D-1/2 @ W @ W.T @ D-1/2" 的特征值从下限有界于 1, # 因此它是有良好条件的,可以安全地进行 Cholesky 分解。 n = self.事件形状[0] cov_diag_sqrt_unsqueeze = self.未广播的协方差诊断.平方根().展平(-1) Dinvsqrt_W = self.未广播的协方差因子 / 协方差对角线开平方后展开 K = 火炬.矩阵乘法(Dinvsqrt_W, Dinvsqrt_W.mT).连续() K.视图(-1, n * n)[:, :: n + 1] += 1 # 添加单位矩阵到 K scale_tril = cov_diag_sqrt_unsqueeze * 火炬.线性代数.转置分解(K) return scale_tril.展开( self._批次形状 + self._事件形状 + self._事件形状 ) @lazy_property 定义 covariance_matrix(self) 翻译 张量: 协方差矩阵 = 火炬.矩阵乘法( self._未广播的协方差因子, self._未广播的协方差因子.mT ) + 火炬.嵌入式诊断(self._未广播的协方差对角线) return 协方差矩阵.展开( self._批次形状 + self._事件形状 + self._事件形状 ) @lazy_property 定义 精确度矩阵(self) 翻译 张量: 我们使用“Woodbury 矩阵恒等式”来利用低秩形式: # (W @ W.T + D)^(-1) = D^(-1) - D^(-1) @ W @ C^(-1) @ W.T @ D^(-1) # 其中 :math:`C` 是电容矩阵。 Wt_Dinv = ( self._unbroadcasted_cov_factor.mT / self._unbroadcasted_cov_diag.展平(-2) ) A = 火炬.线性代数.解三角形方程(self.三相电容, Wt_Dinv, =错误) 精度矩阵 = ( 火炬.嵌入式诊断(self._未广播协方差对角线.相互()) - A.mT @ A ) return 精度矩阵.展开( self._批次形状 + self._事件形状 + self._事件形状 )
[文档] def rsample(self, sample_shape: _size = torch.Size()) -> Tensor: shape = self._extended_shape(sample_shape) W_shape = shape[:-1] + self.cov_factor.shape[-1:] eps_W = _standard_normal(W_shape, dtype=self.loc.dtype, device=self.loc.device) eps_D = _standard_normal(shape, dtype=self.loc.dtype, device=self.loc.device) return ( self.loc + _batch_mv(self._unbroadcasted_cov_factor, eps_W) + self._unbroadcasted_cov_diag.sqrt() * eps_D )
[文档] def log_prob(self, value): if self._validate_args: self._validate_sample(value) diff = value - self.loc M = _batch_lowrank_mahalanobis( self._unbroadcasted_cov_factor self._unbroadcasted_cov_diag diff self._capacitance_tril ) log_det = _batch_lowrank_logdet( self._unbroadcasted_cov_factor, self._unbroadcasted_cov_diag, self._capacitance_tril, ) return -0.5 * (self._event_shape[0] * math.log(2 * math.pi) + log_det + M)
[文档] def 熵(self): log_det = _batch_lowrank_logdet( self._unbroadcasted_cov_factor, self._unbroadcasted_cov_diag, self._capacitance_tril, ) H = 0.5 * (self._event_shape[0] * (1.0 + math.log(2 * math.pi)) + log_det) if len(self._batch_shape) == 0: return H else: 返回 H.expand(self._batch_shape)

© 版权所有 PyTorch 贡献者。

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

文档

查看 PyTorch 的全面开发者文档

查看文档

教程

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

查看教程

资源

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

查看资源