torch.distributions.mixture_same_family 源代码
# mypy: 允许未类型化定义
导入
火炬
from 火炬
导入
张量
from torch.distributions 导入
离散型随机变量分布,
约束
from torch.distributions.distribution 导入
分布
全部 = [
混合同家族]
[文档]
类
同一家族混合(
分发):
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
```
`MixtureSameFamily`分布实现了(批量的)混合分布,其中所有成分都来自同一分布类型的不同参数化。
分布的所有成分都来自同一分布类型的不同参数化。它由一个`Categorical`“选择分布”(在`k`个成分中选择)和一个成分
的参数化。它由一个`Categorical`“选择分布”(在`k`个成分中选择)和一个成分
的参数化。它由一个`Categorical`“选择分布”(在`k`个成分中选择)和一个成分
分布,即一个具有右侧批次形状的 `Distribution`
(等于 `[k]`)用于索引每个(批次)组件。
示例:
>>> # xdoctest: +SKIP("undefined vars")
>>> # 在 1D 中构建由 5 个等距的高斯混合模型
>>> # 加权正态分布
>>> mix = D.Categorical(torch.ones(5,))
>>> comp = D.Normal(torch.randn(5,), torch.rand(5,))
>>> gmm = MixtureSameFamily(mix, comp)
>>> # 构建由 5 个等权二元正态分布组成的 2D 高斯混合模型
>>> # 加权二元正态分布
>>> mix = D.Categorical(torch.ones(5,))
>>> comp = D.Independent(D.Normal(
torch.randn(5,2), torch.rand(5,2)), 1)
>>> gmm = MixtureSameFamily(mix, comp)
>>> # 构建一个包含 3 个 2D 高斯混合模型的批次
>>> # 每个模型由 5 个随机加权的二元正态分布组成
>>> mix = D.Categorical(torch.rand(3,5))
>>> comp = D.Independent(D.Normal(
... torch.randn(3,5,2), torch.rand(3,5,2)), 1)
>>> gmm = MixtureSameFamily(mix, comp)
参数:
混合分布:类似于 `torch.distributions.Categorical`
实例。管理选择组件的概率。
类别的数量必须与 `component_distribution` 的最右侧批次匹配。
必须具有 `component_distribution` 的维度。
标量 `batch_shape` 或 `batch_shape` 匹配
`component_distribution.batch_shape[:-1]`
component_distribution: 类似于 `torch.distributions.Distribution`
instance. 最右侧的批次维度索引组件。
"""
参数约束:
字典[
字符串,
约束.
约束] = {}
has_rsample = 假
定义 __init__(
self,
混合分布:
离散型随机变量分布,
组成分布:
分发,
验证参数=
无,
) 翻译
无:
self.混合分布 =
混合分布
self.组成分布 =
组成分布
如果
不是 isinstance(self.
混合分布,
离散型随机变量分布):
提升 ValueError(
“混合分布需要是一个“
“torch.distributions.Categorical 的实例”
)
如果
不是 isinstance(self.
_组件分布,
分发):
提升 ValueError(
"组件分布需要是一个 "
"torch.distributions.Distribution 的实例"
)
# 检查批大小是否匹配
mdbs = self.混合分布.
批量形状
cdbs = self.组件分布.
批量形状
[-1]
为 size1, size2
在 zip(
反转(mdbs),
反转(cdbs)):
如果 size1 != 1
和 size2 != 1
和
大小 1 != size2:
提升 ValueError(
f"`mixture_distribution.batch_shape` ("{mdbs}
) 不是 "
"兼容 `component_distribution."
f"批处理形状`({cdbs})"
)
# 检查混合成分的数量是否匹配
千米 = self.
混合分布.logits.
形状[-1]
千卡 = self.
组分分布.
批量形状[-1]
如果
千米 is
不是
无
和
千次 is
不是
无
和
千米 !=
千次:
提升 ValueError(
f"混合分布组件("{
千米}
)不等于"
“组件分布.batch_shape[-1]”
f"("{kc})"
)
self._组件编号 =
千米
事件形状 = self.
组件分布.
事件形状
self._event_ndims = 长度(event_shape)
超级().__init__(
批量形状=cdbs, event_shape=event_shape,
验证参数=
验证参数
)
[文档] def expand(self, batch_shape, _instance=None):
batch_shape = torch.Size(batch_shape)
batch_shape_comp = batch_shape + (self._num_component,)
new = self._get_checked_instance(MixtureSameFamily, _instance)
new._component_distribution = self._component_distribution.expand(
batch_shape_comp
)
new._mixture_distribution = self._mixture_distribution.expand(batch_shape)
new._num_component = self._num_component
new._event_ndims = self._event_ndims
event_shape = new._component_distribution.event_shape
super(MixtureSameFamily, new).__init__()
batch_shape=batch_shape, event_shape=event_shape, validate_args=False
)
new._validate_args = self._validate_args
return new
@constraints.依赖属性
定义
支持(self):
# FIXME 这可能当支持包含批处理时形状错误
参数
return self._组件分布.
支持
@property
定义
混合分布(self)
翻译
离散型随机变量分布:
return self._混合分布
@property
定义
组件分布(self)
翻译
分发:
return self.__组件分布
@property
定义
均值(self)
翻译
张量:
概率 = self.
_填充混合维度(self.
混合分布.
概率)
return 火炬.
总和(
概率 * self.
组件分布.
均值,
暗=-1 - self.
_事件维度
) # [B, E]
@property
定义
方差(self)
翻译
张量:
# 全变差定律:Var(Y) = E[Var(Y|X)] + Var(E[Y|X])
概率 = self.
填充混合维度(self.
混合分布.
概率)
均值条件方差 =
火炬.
总和(
概率 * self.
组成分布.
方差,
暗=-1 - self._event_ndims
)
变量条件均值 =
火炬.
总和(
概率 * (self.
组件分布.
平均值 - self.
_填充(self.
均值)).pow(2.0),
暗=-1 - self.
_事件维度,
)
return 均值条件方差 +
条件均值方差
[文档] def cdf(self, x):
x = self._pad(x)
cdf_x = self.component_distribution.cdf(x)
mix_prob = self.mixture_distribution.probs
return torch.sum(cdf_x * mix_prob, dim=-1)
[文档] def log_prob(self, x):
if self._validate_args:
self._validate_sample(x)
x = self._pad(x)
log_prob_x = self.component_distribution.log_prob(x) # [S, B, k]
log_mix_prob = torch.log_softmax(
self.mixture_distribution.logits, dim=-1
) # [B, k]
return torch.logsumexp(log_prob_x + log_mix_prob, dim=-1) # [S, B]
[文档] def sample(self, sample_shape=torch.Size()):
with torch.no_grad():
sample_len = len(sample_shape)
batch_len = len(self.batch_shape)
gather_dim = sample_len + batch_len
es = self.event_shape
# 混合样本 [n, B]
mix_sample = self.mixture_distribution.sample(sample_shape)
mix_shape = mix_sample.shape
# component samples [n, B, k, E]
comp_samples = self.component_distribution.sample(sample_shape)
沿着 k 维度收集
mix_sample_r = mix_sample.reshape(
mix_shape + torch.Size([1] * (len(es) + 1))
)
mix_sample_r = mix_sample_r.repeat(
torch.Size([1] * len(mix_shape)) + torch.Size([1]) + es
)
samples = torch.gather(comp_samples, gather_dim, mix_sample_r)
返回 samples.squeeze(gather_dim)
定义 _pad(self, x):
return x.展平(-1 - self._event_ndims)
定义 _pad_mixture_dimensions(self, x):
dist_batch_ndims = 长度(self.
批量形状)
cat_batch_ndims = 长度(self.
混合分布.
批量形状)
pad_ndims = 0 如果 cat_batch_ndims == 1
否则
批处理维度 -
类别批处理维度
xs = x.形状
x = x.重塑(
xs[-1]
+ 火炬.
尺寸(
扩展维度 * [1])
+ xs[-1]
+ 火炬.
尺寸(self._event_ndims * [1])
)
return x
定义 __repr__(self):
参数字符串 = (
f"输入文本翻译为简体中文为:\n {self.
混合分布},
输入文本翻译为简体中文为:\n {self.
组成分布}"
)
return "MixtureSameFamily" + “(” +
参数字符串 +
“)”