torch.distributions.relaxed_categorical 源代码
# mypy: 允许未类型化定义
导入
火炬
from 火炬
导入
张量
from torch.distributions 导入
约束
from torch.distributions.categorical 导入
分类
from torch.distributions.distribution 导入
分布
from torch.distributions.transformed_distribution 导入
转换分布
from torch.distributions.transforms 导入 ExpTransform
from torch.distributions.utils 导入
广播全部, clamp_probs
from torch.types 导入
_大小
全部 = [
ExpRelaxedCategorical, "RelaxedOneHotCategorical"]
类 ExpRelaxedCategorical(
分发):
r""
创建一个由 :attr:`temperature` 参数化,并使用 :attr:`probs` 或 :attr:`logits`(但不能同时使用)的 ExpRelaxedCategorical。
attr:`温度`,并使用 :attr:`probs` 或 :attr:`logits`(但不能同时使用)。
返回单形中一点的日志。基于接口
class:`OneHotCategorical`。
基于[1]的实现。
参见::func:`torch.distributions.OneHotCategorical`
参数:
温度(张量):松弛温度
probs (Tensor):事件概率
logits(张量):每个事件的未归一化对数概率
[1] 混凝土分布:离散随机变量的连续松弛
(Maddison 等人,2017 年)
[2] 基于 Gumbel-Softmax 的类别重参数化
(Jang 等人,2017)
""
约束参数 = {
"概率":
约束.
单形, "logits":
约束.
实向量}
支持 = (
约束.
实向量
) # 真实支持实际上是这个子流形的。
has_rsample = 真实
def __init__(self, 温度,
概率=
无, logits=
无,
验证参数=
无):
self._分类 =
离散型随机变量分布(
概率, logits)
self.温度 =
温度
批量形状 = self.
_分类.
批量形状
事件形状 = self.
_分类.
参数形状[-1
]
超级().__init__(
批量形状, event_shape,
验证参数=
验证参数)
def 展开(self,
批量形状, _instance=
无):
新 = self._get_checked_instance(
宽松的类别, _instance)
批量形状 =
火炬.
尺寸(
批量形状)
新.
温度 = self.
温度
新.
_分类 = self.
_分类.
展开(
批量形状)
超级(
松弛的类别,
新).__init__(
批量形状, self.event_shape,
验证参数=
假
)
新.
验证参数 = self.
验证参数
返回
新
def 新(self, *
参数, **kwargs):
返回 self.
_分类.
新(*
参数, **kwargs)
@property
def 参数形状(self)
翻译
火炬.
尺寸:
返回 self.
_分类.
参数形状
@property
def logits(self) 翻译
张量:
返回 self.
_分类.logits
@property
def 概率(self)
翻译
张量:
返回 self.
_分类.
概率
def 重采样(self,
样本形状:
_大小 =
火炬.
尺寸())
翻译
张量:
形状 = self.
_扩展形状(
样本形状)
统一量 = clamp_probs(
火炬.
随机(
形状,
数据类型=self.logits.
数据类型,
设备=self.logits.
设备)
)
古姆贝尔斯 = -((-(
均匀分布.
日志())).
日志())
分数 = (self.logits +
古姆贝尔斯) / self.
温度
返回
分数 -
分数.logsumexp(
暗=-1,
保持维度=
是)
def 对数概率(self,
值):
K = self._分类.
_事件数
如果 self._validate_args:
self._validate_sample(值)
logits, 值 =
广播全部(self.logits,
值)
对数刻度 =
火炬.
完全一样(
self.温度, float(K)
).lgamma() - self.温度.
日志().
多(-(K - 1))
分数 = logits -
值.
多(self.
温度)
分数 = (
分数 -
分数.logsumexp(
暗=-1,
保持维度=
是)).
总和(-1)
返回
分数 +
对数尺度
[文档]类 RelaxedOneHotCategorical(变换分布):
r"""
创建一个由温度参数和:attr:`probs` 或:attr:`logits` 参数之一决定的 RelaxedOneHotCategorical 分布
attr:`温度`,并且其样本位于单纯形上,并且可重新参数化。
这是:class:`OneHotCategorical` 分布的宽松版本,因此
其样本位于单纯形上,并且可重新参数化。
示例::
>>> # xdoctest: +IGNORE_WANT("非确定性")
>>> m = RelaxedOneHotCategorical(torch.tensor([2.2]),
... torch.tensor([0.1, 0.2, 0.3, 0.4]))
>>> m.sample()
tensor([ 0.1294, 0.2324, 0.3859, 0.2523])
参数:
温度 (Tensor): 松弛温度
probs (Tensor):事件概率
logits (Tensor):每个事件的未归一化对数概率
"""
arg_constraints = {"probs": constraints.simplex, "logits": constraints.real_vector}
support = 简单约束
has_rsample = True
def __init__(self, temperature, probs=None, logits=None, validate_args=None):
base_dist = ExpRelaxedCategorical(
温度,概率,logits,validate_args=validate_args
)
super().__init__(base_dist, ExpTransform(), validate_args=validate_args)
[文档] def expand(self, batch_shape, _instance=None):
new = self._get_checked_instance(RelaxedOneHotCategorical, _instance)
return super().expand(batch_shape, _instance=new)
@property
def temperature(self) -> Tensor:
return self.base_dist.temperature
@property
def logits(self) -> Tensor:
return self.base_dist.logits
@property
def probs(self) -> Tensor:
return self.base_dist.probs