torch.distributions.studentT 的源代码
# mypy: 允许未类型化定义
导入
数学
导入
火炬
from 火炬
导入
无穷,
纳尼,
张量
from torch.distributions 导入
卡方,
约束
from torch.distributions.distribution 导入
分布
from torch.distributions.utils 导入
标准正态,
广播全部
from torch.types 导入
_大小
全部 = [
学生 t 分布]
[文档]
类
学生 t 分布(
分发):
r""
创建一个由自由度参数化的学生 t 分布
自由度:attr:`df`,均值:attr:`loc` 和尺度:attr:`scale`。
示例::
>>> # xdoctest: +IGNORE_WANT("非确定性")
>>> m = StudentT(torch.tensor([2.0]))
>>> m.sample() # 自由度为 2 的 Student 分布
tensor([ 0.1046])
参数:
df (浮点数或 Tensor): 自由度
loc (float or Tensor): 分布的均值
scale (float or Tensor): 分布的尺度
""
约束参数 = {
"df": 约束.
正的,
"loc": 约束.
真实,
"缩放":
约束.
正的,
}
支持 =
约束.
真实
has_rsample = 真实
@property
def 均值(self)
翻译
张量:
m = self.位置.
克隆(
内存格式=
火炬.
连续格式)
m[self.df <= 1] = 纳尼
返回 m
@property
def 模式(self)
翻译
张量:
返回 self.
定位
@property
def 方差(self)
翻译
张量:
m = self.df.克隆(
内存格式=
火炬.
连续格式)
m[self.df > 2] = (
self.比例[self.df > 2].pow(2)
* self.df[self.df > 2]
/ (self.df[self.df > 2] - 2)
)
m[self.df <= 2) & (self.df > 1)] =
无
m[self.df <= 1] = 纳尼
返回 m
def __init__(self, df, 位置=0.0,
比例=1.0,
验证参数=
无):
self.df, self.位置, self.
缩放 =
广播全部(df,
位置,
比例)
self._chi2 = 卡方(self.df)
批量形状 = self.df.
尺寸()
超级().__init__(
批量形状,
验证参数=
验证参数)
[文档] def expand(self, batch_shape, _instance=None):
new = self._get_checked_instance(StudentT, _instance)
batch_shape = torch.Size(batch_shape)
new.df = self.df.expand(batch_shape)
new.loc = self.loc.expand(batch_shape)
new.scale = self.scale.expand(batch_shape)
new._chi2 = self._chi2.expand(batch_shape)
super(StudentT, new).__init__(batch_shape, validate_args=False)
new._validate_args = self._validate_args
return new
[文档] def rsample(self, sample_shape: _size = torch.Size()) -> Tensor:
# 注意:这与 scipy 实现相比,与其他分布的实现不太一致。
# (参见 https://github.com/fritzo/notebooks/blob/master/debug-student-t.ipynb)。使用 DoubleTensor 参数似乎有所帮助。
# 参数似乎有所帮助。
# X ~ 正态分布(0, 1)
# Z ~ 卡方分布(df)
# Y = X / sqrt(Z / df) ~ t 分布(df)
shape = self._extended_shape(sample_shape)
X = _standard_normal(shape, dtype=self.df.dtype, device=self.df.device)
Z = self._chi2.rsample(sample_shape)
Y = X * torch.rsqrt(Z / self.df)
return self.loc + self.scale * Y
[文档] def log_prob(self, value):
if self._validate_args:
self._validate_sample(value)
y = (value - self.loc) / self.scale
Z = (
self.scale.log()
+ 0.5 * self.df.log()
+ 0.5 * math.log(math.pi)
+ torch.lgamma(0.5 * self.df)
- torch.lgamma(0.5 * (self.df + 1.0))
)
返回 -0.5 * (self.df + 1.0) * torch.log1p(y**2.0 / self.df) - Z
[文档] def 熵(self):
lbeta = (
torch.lgamma(0.5 * self.df)
+ math.lgamma(0.5)
torch.lgamma((self.df + 1) * 0.5)
)
return (
self.scale.log()
+ 0.5
* (self.df + 1)
* (torch.digamma(0.5 * (self.df + 1)) - torch.digamma(0.5 * self.df))
+ 0.5 * self.df.log()
+ 拉贝塔
)