# mypy: 允许未类型化定义
导入
数学
导入
火炬
from 火炬
导入
张量
from torch.distributions 导入
约束
from torch.distributions.distribution 导入
分布
from torch.distributions.utils 导入
标准正态,
懒加载属性
from torch.types 导入
_大小
全部 = [
多元正态分布]
def _batch_mv(bmat, bvec):
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
```
执行批量矩阵-向量乘法,具有兼容但不同的批量形状。
此函数以 `bmat` 作为输入,其中包含 :math:`n \times n` 矩阵,
`bvec`,其中包含长度为 :math:`n` 的向量。
`bmat` 和 `bvec` 可以有任意数量的前导维度,这些维度对应
将批次形状。它们不一定具有相同的批次形状。
只有可以播出的。
"""
返回
火炬.
矩阵乘法(bmat, bvec.
展平(-1)).
挤压(-1)
def _batch_mahalanobis(bL, bx):
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
```
计算平方马氏距离:\( \mathbf{x}^\top\mathbf{M}^{-1}\mathbf{x} \)
对于分解:`M = LL^T`。
接受 bL 和 bx 的批次。它们不一定具有相同的形状,但`bL`应该能够广播到`bx`。
`bL`应该能够广播到`bx`。
"""
n = bx.大小(-1)
bx_batch_shape = bx.形状
[-1]
# 假设 bL.shape = (i, 1, n, n), bx.shape = (..., i, j, n),
# 我们将使 bx 的形状变为 (..., 1, j, i, 1, n) 以应用批处理 tri.solve
bx_batch_dims = 长度(bx_batch_shape)
bL_batch_dims = bL.暗() - 2
外层批次维度 =
bx 批次维度 -
bL 批次维度
旧批次维度 =
外层批次维度 +
bL 批次维度
新批次维度 =
外层批次维度 + 2 * bL_batch_dims
# 将 bx 重塑为形状(..., 1, i, j, 1, n)
bx_new_shape = bx.形状
[
外层批次维度]
为 sL, sx
在 zip(bL.
形状
[-2
] bx.
形状[outer_batch_dims:-1
)]
bx_new_shape += (sx // sL, sL)
新形状 += (n,)
bx = bx.重塑(bx_new_shape)
将 bx 进行排列以使其形状为(..., 1, j, i, 1, n)
排列维度 = (
列表(
范围(
外层批次维度))
+ 列表(
范围(
外层批次维度,
新批次维度, 2))
+ 列表(
范围(
外层批次维度 + 1,
新批次维度, 2))
+ [新批次维度]
)
bx = bx.排列(
排列维度)
平坦的 L = bL.
重塑(-1, n, n)
# 形状 = b x n x n
平面_x = bx.
重塑(-1,
平面_L.
大小(0), n)
# 形状 = c x b x n
flat_x_swap = flat_x.排列(1, 2, 0)
# 形状 = b x n x c
M_swap = (
火炬.
线性代数.
解三角形方程(
平面_L,
平面_x_交换,
上=
错误).pow(2).
总和(-2)
) # 形状 = b x c
M = M_交换.t()
# 形状 = c x b
# 现在我们回滚上述重塑和置换算子。
# 置换_M = M.
重塑(
# bx.
形状
[-1])
# 形状 = (..., 1, j, i, 1)
排列逆维度 =
列表(
范围(
外部批次维度))
为 i
在
范围(
bL 批次维度):
排列维度 += [
外部批次维度 + i,
旧批次维度 + i]
重新塑形 M =
乱序_M.
排列(
逆序排列维度)
# 形状 = (..., 1, i, j, 1)
返回
重新排列_M.
重塑(
bx 批处理形状)
def _精度转换为尺度三角(P):
# 参考:https://nbviewer.jupyter.org/gist/fehiepsi/5ef8e09e61604f10607380467eb82006#精度-尺度_tril
Lf = 火炬.
线性代数.
转置分解(
火炬.
翻转(P, (-2, -1)))
L_inv = 火炬.
转置(
火炬.
翻转(Lf, (-2, -1)), -2, -1)
Id = 火炬.
眼睛(P.
形状[-1
]
数据类型=P.
数据类型,
设备=P.
设备)
L = 火炬.
线性代数.
解三角形方程(L_inv, Id,
上=
错误)
返回 L
[文档]
类
多元正态分布(
分发):
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
```
创建一个多元正态分布(也称为高斯分布)
由均值向量和协方差矩阵参数化。
多元正态分布可以由以下参数化
在正定协方差矩阵 :math:`\mathbf{\Sigma}` 的意义上
或者正定精度矩阵 :math:`\mathbf{\Sigma}^{-1}`
或者具有正值的下三角矩阵 :math:`\mathbf{L}`
对角线元素,使得
math:`Σ = LL^T`. 这是一个三角矩阵
可以通过例如协方差矩阵的 Cholesky 分解来获得。
示例:
>>> # xdoctest: +REQUIRES(env:TORCH_DOCTEST_LAPACK)
>>> # xdoctest: +IGNORE_WANT("非确定性")
>>> m = MultivariateNormal(torch.zeros(2), torch.eye(2))
>>> m.sample() # 均值为 `[0,0]` 且协方差矩阵为 `I` 的正态分布
tensor([-0.2102, -0.5429])
参数:
loc (Tensor):分布的均值
covariance_matrix (Tensor):正定协方差矩阵
precision_matrix (Tensor):正定精度矩阵
scale_tril (Tensor):协方差矩阵的下三角因子,对角线为正值
注意:
仅指定 :attr:`covariance_matrix` 或 :attr:`precision_matrix` 或
attr:`scale_tril` 中的一个。
使用 :attr:`scale_tril` 将更高效:所有内部计算
基于 :attr:`scale_tril`。如果传入 :attr:`covariance_matrix` 或
attr:`precision_matrix`,则仅用于计算
对应的下三角矩阵,使用 Cholesky 分解。
"""
约束参数 = {
"loc": 约束.
实向量,
协方差矩阵:
约束.
正定,
精度矩阵:
约束.
正定,
scale_tril:
约束.
下三角 Cholesky,
}
支持 =
约束.
实向量
has_rsample = 真实
def __init__(
self,
位置,
协方差矩阵=
无,
精度矩阵=
无,
缩放三角矩阵=
无,
验证参数=
无,
):
如果
位置.
暗() < 1:
提升 ValueError(
"位置至少需要为一维。")
如果 (
协方差矩阵 is
不是
无) + (scale_tril is
不是
无) + (
精度矩阵 is
不是
无
) != 1:
提升 ValueError(
"恰好指定协方差矩阵、精度矩阵或 scale_tril 中的一个。"
)
如果 scale_tril is
不是
无:
如果
缩放三角.
暗() < 2:
提升 ValueError(
"scale_tril 矩阵必须是至少二维的。"
"可选的批处理维度前缀"
)
批量形状 =
火炬.
广播形状(
缩放三角.
形状
[-2
]
位置.
形状
[-1])
self.scale_tril = scale_tril.展开(
批量形状 + (-1, -1))
如果...否则
协方差矩阵 is
不是
无:
如果
协方差矩阵.
暗() < 2:
提升 ValueError(
"协方差矩阵必须是至少二维的"
"可选的批处理维度前缀"
)
批量形状 =
火炬.
广播形状(
协方差矩阵.
形状
[-2
]
位置.
形状
[-1]
)
self.协方差矩阵 =
协方差矩阵.
展开(
批量形状 + (-1, -1))
else:
如果
精度矩阵.
暗() < 2:
提升 ValueError(
"精度矩阵必须是至少二维的,"
"可选的批处理维度前缀"
)
批量形状 =
火炬.
广播形状(
精度矩阵.
形状
[-2
]
位置.
形状
[-1]
)
self.精度矩阵 =
精度矩阵.
展开(
批量形状 + (-1, -1))
self.定位 =
位置.
展开(
批量形状 + (-1,))
事件形状 = self.
位置.
形状[-1
]
超级().__init__(
批量形状, event_shape,
验证参数=
验证参数)
如果 scale_tril is
不是
无:
self._未广播的 scale_tril = scale_tril
如果...否则
协方差矩阵 is
不是
无:
self._未广播的尺度三角 =
火炬.
线性代数.
转置分解(
协方差矩阵)
else: # 精度矩阵不为 None
self._未广播的尺度三角 =
_精度到规模三角化(
精度矩阵)
[文档] def expand(self, batch_shape, _instance=None):
new = self._get_checked_instance(MultivariateNormal, _instance)
batch_shape = torch.Size(batch_shape)
loc_shape = batch_shape + self.event_shape
cov_shape = batch_shape + self.event_shape + self.event_shape
new.loc = self.loc.expand(loc_shape)
new._unbroadcasted_scale_tril = self._unbroadcasted_scale_tril
如果 "covariance_matrix" 在 self.__dict__ 中:
new.covariance_matrix = self.covariance_matrix.expand(cov_shape)
如果 "scale_tril" 在 self.__dict__ 中:
new.scale_tril = self.scale_tril.expand(cov_shape)
如果 "precision_matrix" 在 self.__dict__ 中:
new.precision_matrix = self.precision_matrix.expand(cov_shape)
super(MultivariateNormal, new).__init__(batch_shape, self.event_shape, validate_args=False)
super(MultivariateNormal, new).__init__(batch_shape, self.event_shape, validate_args=False)
)
new._validate_args = self._validate_args
return new
@lazy_property
def 缩放三角(self)
翻译
张量:
返回 self.
未广播的尺度三重.
展开(
self._批次形状 + self.
_事件形状 + self.
_事件形状
)
@lazy_property
def 协方差矩阵(self)
翻译
张量:
返回
火炬.
矩阵乘法(
self.未广播的尺度三重, self.
未广播的尺度三重.mT
).展开(self.
_批次形状 + self.
_事件形状 + self.
事件形状)
@lazy_property
def 精度矩阵(self)
翻译
张量:
返回
火炬.
cholesky 逆矩阵(self.
未广播的尺度三重).
展开(
self._批次形状 + self.
_事件形状 + self.
_事件形状
)
@property
def 均值(self)
翻译
张量:
返回 self.
定位
@property
def 模式(self)
翻译
张量:
返回 self.
定位
@property
def 方差(self)
翻译
张量:
返回 (
self.未广播的尺度三重.pow(2)
.总和(-1)
.展开(self.
_批次形状 + self.
事件形状)
)
[文档] def rsample(self, sample_shape: _size = torch.Size()):
shape = self._extended_shape(sample_shape)
eps = _standard_normal(shape, dtype=self.loc.dtype, device=self.loc.device)
return self.loc + _batch_mv(self._unbroadcasted_scale_tril, eps)
[文档] def log_prob(self, value):
if self._validate_args:
self._validate_sample(value)
diff = value - self.loc
M = _batch_mahalanobis(self._unbroadcasted_scale_tril, diff)
half_log_det = (
self._unbroadcasted_scale_tril.diagonal(dim1=-2, dim2=-1).log().sum(-1)
)
返回 -0.5 * (self._event_shape[0] * math.log(2 * math.pi) + M) - half_log_det
[文档] def entropy(self):
half_log_det = (
self._unbroadcasted_scale_tril.diagonal(dim1=-2, dim2=-1).log().sum(-1)
)
H = 0.5 * self._event_shape[0] * (1.0 + math.log(2 * math.pi)) + half_log_det
if len(self._batch_shape) == 0:
return H
else:
返回 H.expand(self._batch_shape)