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

torch.distributions.lkj_cholesky 的源代码

# mypy: 允许未类型化定义
"""
这与 NumPyro(https://github.com/pyro-ppl/numpyro)中的实现紧密相关。

原始版权声明:

# 版权:Pyro 项目贡献者。
# SPDX-License-Identifier: Apache-2.0
"文档"

导入 数学

导入 火炬
来自 torch.distributions 导入 测试版, 约束
来自 torch.distributions.distribution 导入 分布
来自 torch.distributions.utils 导入 广播全部


__全部__ = [LKJCholesky]


文档 LKJCholesky(分布): r""" LKJ 分布用于相关矩阵的下三角 Cholesky 因子。 分布由“浓度”参数 :math:`η` 控制 以使从相关矩阵 :math:`M` 生成的概率 一个与 :math:`\det(M)^{\eta - 1}` 成比例的 Cholesky 因子。由于这个原因, 当 `concentration == 1` 时,我们在 Cholesky 上具有均匀分布 相关矩阵的因子 L ~ LKJCholesky(维度, 浓度) X = L @ L' ~ LKJCorr(维度, 浓度) 注意,这个分布是对... 而不是协方差矩阵本身,因此与[1]中的推导略有不同 因此与[1]中的推导略有不同 `LKJCorr`分布。对于采样,它使用洋葱方法。 [1] 第 3 节。 示例:: >>> # xdoctest: +IGNORE_WANT("非确定性") >>> l = LKJCholesky(3, 0.5) >>> l.sample() # l @ l.T 是一个 3x3 相关矩阵的样本 tensor([[ 1.0000, 0.0000, 0.0000], [ 0.3516, 0.9361, 0.0000], [-0.1899, 0.4748, 0.8593]]) 参数: 矩阵的维度(dim):矩阵的维度 浓度(浮点数或张量):浓度/形状参数 分布(通常称为 eta) **参考文献** 基于 vines 和扩展洋葱方法生成随机相关矩阵(2009 年) 丹尼尔·莱万多夫斯基,多罗塔·库罗维卡,哈利·乔 多变量分析杂志. 100. 10.1016/j.jmva.2009.04.008 """ 边界约束 = {浓度: 约束.正的} 支持 = 约束.胡尔维茨分解 定义 __init__(self, dim, concentration=1.0, 验证参数=None): 如果 维度 < 2: 提升 ValueError( f"期望维度为大于或等于 2 的整数。找到的维度为 dim="{dim} ) 自我. = (.注意力,) = 广播所有(注意力) 批处理形状 = 自身.浓度.大小() 事件形状 = PyTorch.大小((维度, dim)) 这用于在[1]的第 3.2 节中绘制贝塔分布的矢量化样本。 边缘浓度 = .专注 + 0.5 * (自我.暗淡 - 2) 偏移 = 火炬.arange( self.dim - 1, 数据类型=自身.浓度.数据类型, 设备=自我.注意力.设备, ) 偏移 = 火炬.([偏移.新零((1,)), 偏移]) beta_conc1 = 偏移量 + 0.5 beta_conc0 = 边际浓度.展平(-1) - 0.5 * 偏移 自身._beta = 测试版(beta_conc1, beta_conc0) 超级().__init__(batch_shape, event_shape, validate_args)
[文档] def expand(self, batch_shape, _instance=None): new = self._get_checked_instance(LKJCholesky, _instance) batch_shape = torch.Size(batch_shape) new.dim = self.dim new.concentration = self.concentration.expand(batch_shape) new._beta = self._beta.expand(batch_shape + (self.dim,)) super(LKJCholesky, new).__init__( batch_shape, self.event_shape, validate_args=False ) new._validate_args = self._validate_args return new
[文档] def sample(self, sample_shape=torch.Size()): # 这使用的是洋葱法,但与[1]第 3.2 节有一些不同: # - 将循环向量化,也适用于异构的 eta。 # - 同样的算法可以推广到 n=1。 # - 由于我们正在采样 Cholesky 因子,因此程序简化了。 # 替代相关系数矩阵本身,因此 # 我们只需要生成 `w`。 y = self._beta.sample(sample_shape).unsqueeze(-1) u_normal = torch.randn( self._extended_shape(sample_shape), dtype=y.dtype, device=y.device ).tril(-1) u_hypersphere = u_normal / u_normal.norm(dim=-1, keepdim=True) # Replace NaNs in first row u_hypersphere[..., 0, :].fill_(0.0) w = torch.sqrt(y) * u_hypersphere # 填充对角线元素;夹具以提高数值稳定性 eps = torch.finfo(w.dtype).tiny diag_elems = torch.clamp(1 - torch.sum(w**2, dim=-1), min=eps).sqrt() w += torch.diag_embed(diag_elems) return w
[文档] def log_prob(self, value): 查看:https://mc-stan.org/docs/2_25/functions-reference/cholesky-lkj-correlation-distribution.html 相关矩阵的概率与成比例 行列式 ** (浓度 - 1) = prod(L_ii ^ 2(浓度 - 1)) 此外,从 Cholesky 因子到变换的雅可比矩阵 相关系数矩阵是: # prod(L_ii ^ (D - i)) 因此,Cholesky 因子的概率与成比例 # prod(L_ii ^ (2 * 浓度 - 2 + D - i)) = prod(L_ii ^ 指数_i) # with order_i = 2 * 浓度 - 2 + D - i if self._validate_args: self._validate_sample(value) diag_elems = value.diagonal(dim1=-1, dim2=-2)[..., 1:] order = torch.arange(2, self.dim + 1, device=self.concentration.device) order = 2 * (self.concentration - 1).unsqueeze(-1) + self.dim - order unnormalized_log_pdf = torch.sum(order * diag_elems.log(), dim=-1) # Compute normalization constant (page 1999 of [1]) dm1 = self.dim - 1 alpha = self.concentration + 0.5 * dm1 denominator = torch.lgamma(alpha) * dm1 numerator = torch.mvlgamma(alpha - 0.5, dm1) π常数在[1]中是 D * (D - 1) / 4 * log(π) π常数在多伽玛对数中是 (D - 1) * (D - 2) / 4 * log(π) 因此,我们需要添加一个 π常数 = (D - 1) * log(π) / 2 π常数 = 0.5 * dm1 * math.log(math.pi) normalize_term = pi_constant + 分子 - 分母 return 未归一化的对数概率密度 - normalize_term

© 版权所有 PyTorch 贡献者。

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

文档

查看 PyTorch 的全面开发者文档

查看文档

教程

为初学者和高级开发者提供深入教程

查看教程

资源

寻找开发资源,解答你的问题

查看资源