torch.distributions.bernoulli 的源代码
# mypy: 允许未类型化定义
导入
火炬
来自
火炬
导入
纳尼,
张量
来自 torch.distributions
导入
约束
来自 torch.distributions.exp_family
导入
指数族
来自 torch.distributions.utils
导入 (
broadcast_all,
懒属性,
logits 转概率,
概率转 logits,
)
来自 torch.nn.functional
导入
带 logits 的二分类交叉熵
来自
torch 的类型
导入
数值
全部 = [
伯努利]
[文档]
类
伯努利分布(
指数族):
r""
创建一个由 :attr:`probs` 或 :attr:`logits` (但不能同时使用)参数化的伯努利分布。
或 :attr:`logits`(但不能同时使用)。
样本是二进制的(0 或 1)。它们以概率`p`取值`1`
并且以概率 `1 - p` 选择 `0`。
示例::
>>> # xdoctest: +IGNORE_WANT("非确定性")
>>> m = 伯努利(torch.tensor([0.3])
>>> m.sample() # 30%概率 1;70%概率 0
tensor([ 0.])
参数:
probs (Number, Tensor): 采样 `1` 的概率
logits (Number, Tensor): 采样 `1` 的对数几率
"沉浸式翻译"
arg_constraints = {"概率":
约束.
单位区间, "logits":
约束.
真实}
支持 =
约束.
布尔
支持枚举 =
真实
_平均载波测量 = 0
def __init__(self, 概率=
无, logits=
无,
验证参数=
无):
如果 (
概率
是
无) == (
对数几率
是
无):
抛出
值错误(
"必须指定 `概率` 或 `对数几率` 中的一个,但不能同时指定。"
)
如果
概率
是
不是
无:
is_scalar = isinstance(probs, _Number)
(self.probs,) = 广播全部(
概率)
否则:
是否为标量 = isinstance(logits,
_数字)
(self.logits,) = 广播全部(logits)
self._参数 = self.
概率
如果
概率
是
不是
无
否则 self.logits
如果 is_scalar:
batch_shape = torch.尺寸()
否则:
batch_shape = self.参数.
尺寸()
超级().__init__(
批量形状,
验证参数=
验证参数)
[文档] def expand(self, batch_shape, _instance=None):
new = self._get_checked_instance(Bernoulli, _instance)
batch_shape = torch.Size(batch_shape)
if "probs" in self.__dict__:
new.probs = self.probs.expand(batch_shape)
new._param = new.probs
如果 "logits" 在 self.__dict__ 中:
new.logits = self.logits.expand(batch_shape)
new._param = new.logits
super(Bernoulli, new).__init__(batch_shape, validate_args=False)
new._validate_args = self._validate_args
return new
def 新(self, *
参数, **kwargs):
返回 self.
参数.
新(*
参数, **kwargs)
@property
def 均值(self) ->
张量:
返回 self.
概率
@property
def 模式(self) ->
张量:
模式 = (self.
概率
≥ 0.5).
到(self.
可能)
模式[self.
可能 == 0.5] =
纳尼
返回
模式
@property
def 方差(self) ->
张量:
返回 self.
概率 * (1 - self.
概率)
@lazy_property
def logits(self) -> 张量:
返回
概率转对数概率(self.
概率,
是二进制=
是)
@lazy_property
def 概率(self) ->
张量:
返回
logits 转概率(self.logits,
是二进制=
是)
@property
def 参数形状(self) -> torch.
尺寸:
返回 self._param.
尺寸()
[文档] def sample(self, sample_shape=torch.Size()):
shape = self._extended_shape(sample_shape)
with torch.no_grad():
return torch.bernoulli(self.probs.expand(shape))
[文档] def log_prob(self, value):
if self._validate_args:
self._validate_sample(value)
logits, value = broadcast_all(self.logits, value)
return -binary_cross_entropy_with_logits(logits, value, reduction="none")
[文档] def entropy(self):
return binary_cross_entropy_with_logits(
self.logits, self.probs, reduction="none"
)
[文档] def enumerate_support(self, expand=True):
values = torch.arange(2, dtype=self._param.dtype, device=self._param.device)
values = values.view((-1,) + (1,) * len(self._batch_shape))
if expand:
values = values.expand((-1,) + self._batch_shape)
返回值
@property
def 自然参数(self) ->
元组[
张量
]
返回 (torch.logit(self.
概率),)
def 对数归一化器(self, x):
返回 torch.log1p(torch.exp(x))