概率分布 - torch.distributions¶
The distributions
包包含可参数化的概率分布和采样函数。这允许构建随机计算图和用于优化的随机梯度估计器。该包通常遵循 TensorFlow Distributions 包的设计。
直接通过随机样本进行反向传播是不可能的。然而,有两种主要方法可以创建可以进行反向传播的代理函数。这些是得分函数估计器/似然比估计器/REINFORCE和路径导数估计器。REINFORCE通常被视为强化学习中策略梯度方法的基础,而路径导数估计器通常出现在变分自编码器中的重参数化技巧中。虽然得分函数只需要样本的值 ,但路径导数需要导数 。接下来的部分将在强化学习的例子中讨论这两种方法。更多详情请参见 使用随机计算图进行梯度估计。
评分函数¶
当概率密度函数对其参数可微时,我们只需要 sample()
和
log_prob()
来实现 REINFORCE:
其中 是参数, 是学习率, 是奖励, 是采取动作 在状态 给定策略 。
在实践中,我们会从网络的输出中采样一个动作,将这个动作应用于环境中,然后使用log_prob
来构建一个等效的损失函数。请注意,我们使用了一个负号,因为优化器使用梯度下降,而上述规则假设梯度上升。对于分类策略,实现REINFORCE的代码如下:
probs = policy_network(state)
# 注意,这相当于以前称为多项式的内容
m = Categorical(probs)
action = m.sample()
next_state, reward = env.step(action)
loss = -m.log_prob(action) * reward
loss.backward()
路径导数¶
实现这些随机/策略梯度的另一种方法是使用来自
rsample()
方法的重参数化技巧,其中参数化的随机变量可以通过参数化的确定性函数构建,该函数依赖于一个无参数的随机变量。因此,重参数化的样本变得可微分。实现路径导数的代码如下:
params = policy_network(state)
m = Normal(*params)
# 任何具有 .has_rsample == True 的分布都可以根据应用程序工作
action = m.rsample()
next_state, reward = env.step(action) # 假设奖励是可微分的
loss = -reward
loss.backward()
分布¶
- class torch.distributions.distribution.Distribution(batch_shape=torch.Size([]), event_shape=torch.Size([]), validate_args=None)[源代码]¶
基类:
object
分布是概率分布的抽象基类。
- property arg_constraints: Dict[str, 约束]¶
返回一个从参数名称到
Constraint
对象的字典,这些对象应满足此分布的每个参数。非张量的参数不需要出现在此字典中。
- property batch_shape: Size¶
返回参数被批处理的形状。
- enumerate_support(expand=True)[源代码]¶
返回包含离散分布支持的所有值的张量。结果将沿维度0进行枚举,因此结果的形状将为(基数,) + 批次形状 + 事件形状(其中事件形状 = ()表示单变量分布)。
请注意,这是在所有批量张量上同步枚举的 [[0, 0], [1, 1], …]。使用 expand=False,枚举沿维度 0 进行,但剩余的批量维度为 单一维度,[[0], [1], ..。
要遍历完整的笛卡尔积,请使用 itertools.product(m.enumerate_support())。
- property event_shape: Size¶
返回单个样本的形状(不包括批次)。
- expand(batch_shape, _instance=None)[源代码]¶
返回一个新的分布实例(或由派生类提供的现有实例),其批次维度扩展到 batch_shape。此方法调用
expand
在 分布的参数上。因此,这不会为扩展的分布实例分配新的 内存。此外, 这不会在 __init__.py 中重复任何参数检查或参数广播,当实例首次创建时。- Parameters
batch_shape (torch.Size) – 所需的扩展大小。
_instance – 由需要覆盖.expand的子类提供的新实例。
- Returns
新分布实例,批次维度扩展为 批次大小。
- rsample(sample_shape=torch.Size([]))[源代码]¶
生成一个sample_shape形状的重参数化样本,或者如果分布参数是批量的,则生成一个sample_shape形状的批量重参数化样本。
- Return type
- sample(sample_shape=torch.Size([]))[源代码]¶
生成一个 sample_shape 形状的样本或 sample_shape 形状的批次样本,如果分布参数是批次的。
- Return type
- static set_default_validate_args(value)[源代码]¶
设置是否启用或禁用验证。
默认行为模仿了Python的
assert
语句:验证默认开启,但如果Python在优化模式下运行(通过python -O
),则验证会被禁用。验证可能会很耗费资源,因此一旦模型正常工作,您可能希望禁用它。- Parameters
值 (布尔值) – 是否启用验证。
- property support: Optional[Any]¶
返回一个表示此分布支持的
Constraint
对象。
指数族¶
- class torch.distributions.exp_family.ExponentialFamily(batch_shape=torch.Size([]), event_shape=torch.Size([]), validate_args=None)[源代码]¶
基类:
Distribution
ExponentialFamily 是指数族概率分布的抽象基类,其概率质量/密度函数的形式定义如下
其中 表示自然参数, 表示充分统计量, 是给定族的对数正规化函数, 是载体测度。
注意
这个类是Distribution类与属于指数族的分布之间的中介,主要是为了检查.entropy()和解析KL散度方法的正确性。我们使用这个类通过AD框架和Bregman散度(感谢:Frank Nielsen和Richard Nock,指数族的熵和交叉熵)来计算熵和KL散度。
伯努利¶
- class torch.distributions.bernoulli.Bernoulli(probs=None, logits=None, validate_args=None)[源代码]¶
-
创建一个由
probs
或logits
参数化的伯努利分布(但不能同时使用两者)。样本是二进制的(0 或 1)。它们以概率 p 取值 1,并以概率 1 - p 取值 0。
示例:
>>> m = Bernoulli(torch.tensor([0.3])) >>> m.sample() # 30% 的概率为 1;70% 的概率为 0 tensor([ 0.])
- arg_constraints = {'logits': Real(), 'probs': Interval(lower_bound=0.0, upper_bound=1.0)}¶
- has_enumerate_support = True¶
- property logits¶
- property mean¶
- property mode¶
- property param_shape¶
- property probs¶
- support = Boolean()¶
- property variance¶
Beta¶
- class torch.distributions.beta.Beta(concentration1, concentration0, validate_args=None)[源代码]¶
-
Beta 分布由
concentration1
和concentration0
参数化。示例:
>>> m = Beta(torch.tensor([0.5]), torch.tensor([0.5])) >>> m.sample() # 浓度为concentration1和concentration0的Beta分布 tensor([ 0.1046])
- Parameters
- arg_constraints = {'concentration0': GreaterThan(lower_bound=0.0), 'concentration1': GreaterThan(lower_bound=0.0)}¶
- property concentration0¶
- property concentration1¶
- has_rsample = True¶
- property mean¶
- property mode¶
- support = Interval(lower_bound=0.0, upper_bound=1.0)¶
- property variance¶
二项式¶
- class torch.distributions.binomial.Binomial(total_count=1, probs=None, logits=None, validate_args=None)[源代码]¶
基类:
Distribution
创建一个由
total_count
参数化的二项分布,并且可以通过probs
或logits
来定义(但不能同时使用两者)。total_count
必须与probs
/logits
兼容。示例:
>>> m = Binomial(100, torch.tensor([0 , .2, .8, 1])) >>> x = m.sample() tensor([ 0., 22., 71., 100.]) >>> m = Binomial(torch.tensor([[5.], [10.]]), torch.tensor([0.5, 0.8])) >>> x = m.sample() tensor([[ 4., 5.], [ 7., 6.]])
- arg_constraints = {'logits': Real(), 'probs': Interval(lower_bound=0.0, upper_bound=1.0), 'total_count': IntegerGreaterThan(lower_bound=0)}¶
- has_enumerate_support = True¶
- property logits¶
- property mean¶
- property mode¶
- property param_shape¶
- property probs¶
- property support¶
- property variance¶
分类¶
- class torch.distributions.categorical.Categorical(probs=None, logits=None, validate_args=None)[源代码]¶
基类:
Distribution
创建一个由
probs
或logits
参数化的分类分布(但不能同时使用两者)。注意
它等同于
torch.multinomial()
从中采样的分布。样本是从 中的整数,其中 K 是
probs.size(-1)
。如果 probs 是一维的且长度为 K,每个元素是采样该索引类别的相对概率。
如果 probs 是 N 维的,前 N-1 维被视为相对概率向量的批次。
注意
参数 probs 必须是非负的、有限的并且具有非零和,它将被归一化以沿最后一个维度总和为1。
probs
将返回这个归一化值。 参数 logits 将被解释为未归一化的对数概率,因此可以是任何实数。它同样将被归一化,使得生成的概率沿最后一个维度总和为1。logits
将返回这个归一化值。另请参阅:
torch.multinomial()
示例:
>>> m = Categorical(torch.tensor([ 0.25, 0.25, 0.25, 0.25 ])) >>> m.sample() # 0, 1, 2, 3 的概率相等 tensor(3)
- arg_constraints = {'logits': IndependentConstraint(Real(), 1), 'probs': Simplex()}¶
- has_enumerate_support = True¶
- property logits¶
- property mean¶
- property mode¶
- property param_shape¶
- property probs¶
- property support¶
- property variance¶
柯西¶
- class torch.distributions.cauchy.Cauchy(loc, scale, validate_args=None)[源代码]¶
基类:
Distribution
来自柯西(洛伦兹)分布的样本。独立正态分布随机变量比值的分布,其均值为0,遵循柯西分布。
示例:
>>> m = Cauchy(torch.tensor([0.0]), torch.tensor([1.0])) >>> m.sample() # 从位置为0,尺度为1的柯西分布中采样 tensor([ 2.3214])
- arg_constraints = {'loc': Real(), 'scale': GreaterThan(lower_bound=0.0)}¶
- has_rsample = True¶
- property mean¶
- property mode¶
- support = Real()¶
- property variance¶
Chi2¶
连续伯努利¶
- class torch.distributions.continuous_bernoulli.ContinuousBernoulli(probs=None, logits=None, lims=(0.499, 0.501), validate_args=None)[源代码]¶
-
创建一个由
probs
或logits
参数化的连续伯努利分布(但不能同时使用两者)。该分布支持在 [0, 1] 范围内,并通过 ‘probs’(在 (0,1) 之间)或 ‘logits’(实数值)进行参数化。请注意,与伯努利分布不同,‘probs’ 并不对应于概率,‘logits’ 也不对应于对数几率,但由于与伯努利分布的相似性,使用了相同的名称。更多详情请参见 [1]。
示例:
>>> m = ContinuousBernoulli(torch.tensor([0.3])) >>> m.sample() tensor([ 0.2538])
[1] 连续伯努利:修复变分自编码器中的一个普遍错误,Loaiza-Ganem G 和 Cunningham JP,NeurIPS 2019。 https://arxiv.org/abs/1907.06845
- arg_constraints = {'logits': Real(), 'probs': Interval(lower_bound=0.0, upper_bound=1.0)}¶
- has_rsample = True¶
- property logits¶
- property mean¶
- property param_shape¶
- property probs¶
- property stddev¶
- support = Interval(lower_bound=0.0, upper_bound=1.0)¶
- property variance¶
狄利克雷¶
- class torch.distributions.dirichlet.Dirichlet(concentration, validate_args=None)[源代码]¶
-
创建一个由浓度参数化的狄利克雷分布
concentration
。示例:
>>> m = Dirichlet(torch.tensor([0.5, 0.5])) >>> m.sample() # 狄利克雷分布,浓度为 [0.5, 0.5] tensor([ 0.1046, 0.8954])
- Parameters
浓度 (张量) – 分布的浓度参数 (通常称为alpha)
- arg_constraints = {'concentration': IndependentConstraint(GreaterThan(lower_bound=0.0), 1)}¶
- has_rsample = True¶
- property mean¶
- property mode¶
- support = Simplex()¶
- property variance¶
指数¶
- class torch.distributions.exponential.Exponential(rate, validate_args=None)[源代码]¶
-
创建一个由
rate
参数化的指数分布。示例:
>>> m = Exponential(torch.tensor([1.0])) >>> m.sample() # 指数分布,速率=1 tensor([ 0.1046])
- arg_constraints = {'rate': GreaterThan(lower_bound=0.0)}¶
- has_rsample = True¶
- property mean¶
- property mode¶
- property stddev¶
- support = GreaterThanEq(lower_bound=0.0)¶
- property variance¶
费舍尔-斯内德克¶
- class torch.distributions.fishersnedecor.FisherSnedecor(df1, df2, validate_args=None)[源代码]¶
基类:
Distribution
创建一个由
df1
和df2
参数化的 Fisher-Snedecor 分布。示例:
>>> m = FisherSnedecor(torch.tensor([1.0]), torch.tensor([2.0])) >>> m.sample() # 服从df1=1和df2=2的Fisher-Snedecor分布 tensor([ 0.2453])
- arg_constraints = {'df1': GreaterThan(lower_bound=0.0), 'df2': GreaterThan(lower_bound=0.0)}¶
- has_rsample = True¶
- property mean¶
- property mode¶
- support = GreaterThan(lower_bound=0.0)¶
- property variance¶
伽马¶
- class torch.distributions.gamma.Gamma(concentration, rate, validate_args=None)[源代码]¶
-
创建一个由形状参数
concentration
和rate
参数化的Gamma分布。示例:
>>> m = Gamma(torch.tensor([1.0]), torch.tensor([1.0])) >>> m.sample() # 伽马分布,浓度=1,速率=1 tensor([ 0.1046])
- Parameters
- arg_constraints = {'concentration': GreaterThan(lower_bound=0.0), 'rate': GreaterThan(lower_bound=0.0)}¶
- has_rsample = True¶
- property mean¶
- property mode¶
- support = GreaterThanEq(lower_bound=0.0)¶
- property variance¶
几何¶
- class torch.distributions.geometric.Geometric(probs=None, logits=None, validate_args=None)[源代码]¶
基类:
Distribution
创建一个几何分布,参数由
probs
指定,其中probs
是伯努利试验成功的概率。注意
torch.distributions.geometric.Geometric()
-th trial is the first success hence draws samples in , 而torch.Tensor.geometric_()
k-th trial is the first success hence draws samples in .示例:
>>> m = Geometric(torch.tensor([0.3])) >>> m.sample() # 基础的伯努利分布有30%的概率为1;70%的概率为0 tensor([ 2.])
- arg_constraints = {'logits': Real(), 'probs': Interval(lower_bound=0.0, upper_bound=1.0)}¶
- property logits¶
- property mean¶
- property mode¶
- property probs¶
- support = IntegerGreaterThan(lower_bound=0)¶
- property variance¶
Gumbel¶
半柯西¶
- class torch.distributions.half_cauchy.HalfCauchy(scale, validate_args=None)[源代码]¶
-
创建一个由尺度参数化的半柯西分布,其中:
X ~ Cauchy(0, scale) Y = |X| ~ HalfCauchy(scale)
示例:
>>> m = HalfCauchy(torch.tensor([1.0])) >>> m.sample() # 尺度为1的半柯西分布 tensor([ 2.3214])
- has_rsample = True¶
- property mean¶
- property mode¶
- property scale¶
- support = GreaterThanEq(lower_bound=0.0)¶
- property variance¶
半正态¶
- class torch.distributions.half_normal.HalfNormal(scale, validate_args=None)[源代码]¶
-
创建一个由scale参数化的半正态分布,其中:
X ~ Normal(0, scale) Y = |X| ~ HalfNormal(scale)
示例:
>>> m = HalfNormal(torch.tensor([1.0])) >>> m.sample() # 半正态分布,尺度参数为1 tensor([ 0.1046])
- has_rsample = True¶
- property mean¶
- property mode¶
- property scale¶
- support = GreaterThanEq(lower_bound=0.0)¶
- property variance¶
独立¶
- class torch.distributions.independent.Independent(base_distribution, reinterpreted_batch_ndims, validate_args=None)[源代码]¶
基类:
Distribution
将分布的一些批次维度重新解释为事件维度。
这主要用于改变
log_prob()
结果的形状。例如,要创建一个与多元正态分布形状相同的对角正态分布(以便它们可以互换),您可以:>>> from torch.distributions.multivariate_normal import MultivariateNormal >>> from torch.distributions.normal import Normal >>> loc = torch.zeros(3) >>> scale = torch.ones(3) >>> mvn = MultivariateNormal(loc, scale_tril=torch.diag(scale)) >>> [mvn.batch_shape, mvn.event_shape] [torch.Size([]), torch.Size([3])] >>> normal = Normal(loc, scale) >>> [normal.batch_shape, normal.event_shape] [torch.Size([3]), torch.Size([])] >>> diagn = Independent(normal, 1) >>> [diagn.batch_shape, diagn.event_shape] [torch.Size([]), torch.Size([3])]
- Parameters
base_distribution (torch.distributions.distribution.Distribution) – 一个基础分布
reinterpreted_batch_ndims (int) – 要重新解释为事件维度的批次维度数量
- property has_enumerate_support¶
- property has_rsample¶
- property mean¶
- property mode¶
- property support¶
- property variance¶
逆伽玛¶
- class torch.distributions.inverse_gamma.InverseGamma(concentration, rate, validate_args=None)[源代码]¶
-
创建一个由
concentration
和rate
参数化的逆伽马分布,其中:X ~ Gamma(concentration, rate) Y = 1 / X ~ InverseGamma(concentration, rate)
示例:
>>> m = InverseGamma(torch.tensor([2.0]), torch.tensor([3.0])) >>> m.sample() tensor([ 1.2953])
- Parameters
- arg_constraints: Dict[str, 约束] = {'concentration': GreaterThan(lower_bound=0.0), 'rate': GreaterThan(lower_bound=0.0)}¶
- property concentration¶
- has_rsample = True¶
- property mean¶
- property mode¶
- property rate¶
- support = GreaterThan(lower_bound=0.0)¶
- property variance¶
Kumaraswamy¶
- class torch.distributions.kumaraswamy.Kumaraswamy(concentration1, concentration0, validate_args=None)[源代码]¶
-
来自Kumaraswamy分布的样本。
示例:
>>> m = Kumaraswamy(torch.tensor([1.0]), torch.tensor([1.0])) >>> m.sample() # 从浓度为alpha=1和beta=1的Kumaraswamy分布中采样 tensor([ 0.1729])
- Parameters
- arg_constraints: Dict[str, 约束] = {'concentration0': GreaterThan(lower_bound=0.0), 'concentration1': GreaterThan(lower_bound=0.0)}¶
- has_rsample = True¶
- property mean¶
- property mode¶
- support = Interval(lower_bound=0.0, upper_bound=1.0)¶
- property variance¶
LKJCholesky¶
- class torch.distributions.lkj_cholesky.LKJCholesky(dim, concentration=1.0, validate_args=None)[源代码]¶
基类:
Distribution
用于相关矩阵的下Cholesky因子的LKJ分布。 该分布由
concentration
参数控制, 以使相关矩阵生成的概率 与Cholesky因子成正比。因此, 当concentration == 1
时,我们在相关矩阵的Cholesky因子上有一个均匀分布:L ~ LKJCholesky(dim, concentration) X = L @ L' ~ LKJCorr(dim, concentration)
请注意,此分布采样的是相关矩阵的Cholesky因子,而不是相关矩阵本身,因此与[1]中LKJCorr分布的推导略有不同。对于采样,此方法使用了[1]第3节中的Onion方法。
示例:
>>> l = LKJCholesky(3, 0.5) >>> l.sample() # l @ l.T 是一个 3x3 相关矩阵的样本 tensor([[ 1.0000, 0.0000, 0.0000], [ 0.3516, 0.9361, 0.0000], [-0.1899, 0.4748, 0.8593]])
参考文献
[1] 基于藤蔓和扩展洋葱法的生成随机相关矩阵 (2009), Daniel Lewandowski, Dorota Kurowicka, Harry Joe. 多元分析杂志. 100. 10.1016/j.jmva.2009.04.008
- arg_constraints = {'concentration': GreaterThan(lower_bound=0.0)}¶
- support = CorrCholesky()¶
拉普拉斯¶
- class torch.distributions.laplace.Laplace(loc, scale, validate_args=None)[源代码]¶
基类:
Distribution
创建一个由
loc
和scale
参数化的拉普拉斯分布。示例:
>>> m = Laplace(torch.tensor([0.0]), torch.tensor([1.0])) >>> m.sample() # 拉普拉斯分布,位置参数为0,尺度参数为1 tensor([ 0.1046])
- arg_constraints = {'loc': Real(), 'scale': GreaterThan(lower_bound=0.0)}¶
- has_rsample = True¶
- property mean¶
- property mode¶
- property stddev¶
- support = Real()¶
- property variance¶
对数正态¶
- class torch.distributions.log_normal.LogNormal(loc, scale, validate_args=None)[源代码]¶
-
创建一个由
loc
和scale
参数化的对数正态分布,其中:X ~ Normal(loc, scale) Y = exp(X) ~ LogNormal(loc, scale)
示例:
>>> m = LogNormal(torch.tensor([0.0]), torch.tensor([1.0])) >>> m.sample() # 对数正态分布,均值=0,标准差=1 tensor([ 0.1046])
- has_rsample = True¶
- property loc¶
- property mean¶
- property mode¶
- property scale¶
- support = GreaterThan(lower_bound=0.0)¶
- property variance¶
低秩多元正态分布¶
- class torch.distributions.lowrank_multivariate_normal.LowRankMultivariateNormal(loc, cov_factor, cov_diag, validate_args=None)[源代码]¶
基类:
Distribution
创建一个具有低秩形式协方差矩阵的多变量正态分布,该矩阵由
cov_factor
和cov_diag
参数化:covariance_matrix = cov_factor @ cov_factor.T + cov_diag
示例
>>> m = LowRankMultivariateNormal(torch.zeros(2), torch.tensor([[1.], [0.]]), torch.ones(2)) >>> m.sample() # 正态分布,均值=`[0,0]`,cov_factor=`[[1],[0]]`,cov_diag=`[1,1]` tensor([-0.2102, -0.5429])
- Parameters
注意
当cov_factor.shape[1] << cov_factor.shape[0]时,由于Woodbury矩阵恒等式和 矩阵行列式引理,避免了协方差矩阵的行列式和逆的计算。 多亏了这些公式,我们只需要计算小尺寸“电容”矩阵的行列式和逆:
capacitance = I + cov_factor.T @ inv(cov_diag) @ cov_factor
- arg_constraints = {'cov_diag': IndependentConstraint(GreaterThan(lower_bound=0.0), 1), 'cov_factor': IndependentConstraint(Real(), 2), 'loc': IndependentConstraint(Real(), 1)}¶
- property covariance_matrix¶
- has_rsample = True¶
- property mean¶
- property mode¶
- property precision_matrix¶
- property scale_tril¶
- support = IndependentConstraint(Real(), 1)¶
- property variance¶
混合相同家族¶
- class torch.distributions.mixture_same_family.MixtureSameFamily(mixture_distribution, component_distribution, validate_args=None)[源代码]¶
基类:
Distribution
The MixtureSameFamily 分布实现了一个(批次的)混合分布,其中所有组件来自同一分布类型的不同参数化。它由一个 Categorical “选择分布”(在 k 个组件上)和一个组件分布参数化,即一个具有最右批次形状的 Distribution(等于 [k]),用于索引每个(批次的)组件。
示例:
>>> # 构建一个由5个等权重的正态分布组成的1维高斯混合模型 >>> # 权重相同的正态分布 >>> mix = D.Categorical(torch.ones(5,)) >>> comp = D.Normal(torch.randn(5,), torch.rand(5,)) >>> gmm = MixtureSameFamily(mix, comp) >>> # 构建一个由5个等权重的二元正态分布组成的2维高斯混合模型 >>> # 权重相同的二元正态分布 >>> 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个2维高斯混合模型的批次,每个模型由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)
- Parameters
mixture_distribution – torch.distributions.Categorical-like 实例。管理选择组件的概率。 类别数量必须与component_distribution的右端批次维度匹配。必须具有标量batch_shape或与component_distribution.batch_shape[:-1]匹配的batch_shape
component_distribution – torch.distributions.Distribution-类似实例。最右边的批次维度索引组件。
- property component_distribution¶
- has_rsample = False¶
- property mean¶
- property mixture_distribution¶
- property support¶
- property variance¶
多项式¶
- class torch.distributions.multinomial.Multinomial(total_count=1, probs=None, logits=None, validate_args=None)[源代码]¶
基类:
Distribution
创建一个由
total_count
和probs
或logits
(但不能同时使用两者)参数化的多项分布。probs
的最内层维度索引类别。所有其他维度索引批次。请注意,如果仅调用
log_prob()
,则无需指定total_count
(见下例)注意
参数 probs 必须是非负的、有限的并且具有非零的总和,它将被归一化以沿最后一个维度总和为 1。
probs
将返回这个归一化后的值。 参数 logits 将被解释为未归一化的对数概率,因此可以是任何实数。它同样将被归一化,使得生成的概率沿最后一个维度总和为 1。logits
将返回这个归一化后的值。sample()
需要所有参数和样本共享一个单一的 total_count。log_prob()
允许每个参数和样本使用不同的 total_count。
示例:
>>> m = Multinomial(100, torch.tensor([ 1., 1., 1., 1.])) >>> x = m.sample() # 0, 1, 2, 3的概率相等 tensor([ 21., 24., 30., 25.]) >>> Multinomial(probs=torch.tensor([1., 1., 1., 1.])).log_prob(x) tensor([-4.1338])
- arg_constraints = {'logits': IndependentConstraint(Real(), 1), 'probs': Simplex()}¶
- property logits¶
- property mean¶
- property param_shape¶
- property probs¶
- property support¶
- property variance¶
多元正态分布¶
- class torch.distributions.multivariate_normal.MultivariateNormal(loc, covariance_matrix=None, precision_matrix=None, scale_tril=None, validate_args=None)[源代码]¶
基类:
Distribution
创建一个多元正态分布(也称为高斯分布),由均值向量和协方差矩阵参数化。
多元正态分布可以通过以下参数化: 在正定协方差矩阵 或正定精度矩阵 或下三角矩阵 ,其对角线元素为正值,使得 。这个三角矩阵 可以通过例如协方差的Cholesky分解获得。
示例
>>> m = MultivariateNormal(torch.zeros(2), torch.eye(2)) >>> m.sample() # 正态分布,均值为`[0,0]`,协方差矩阵为`I` tensor([-0.2102, -0.5429])
- Parameters
注意
只能指定
covariance_matrix
或precision_matrix
或scale_tril
中的一个。使用
scale_tril
会更高效:所有内部计算都是基于scale_tril
。如果传递了covariance_matrix
或precision_matrix
,则仅用于通过 Cholesky 分解计算相应的下三角矩阵。- arg_constraints = {'covariance_matrix': PositiveDefinite(), 'loc': IndependentConstraint(Real(), 1), 'precision_matrix': PositiveDefinite(), 'scale_tril': LowerCholesky()}¶
- property covariance_matrix¶
- has_rsample = True¶
- property mean¶
- property mode¶
- property precision_matrix¶
- property scale_tril¶
- support = IndependentConstraint(Real(), 1)¶
- property variance¶
负二项分布¶
- class torch.distributions.negative_binomial.NegativeBinomial(total_count, probs=None, logits=None, validate_args=None)[源代码]¶
基类:
Distribution
创建一个负二项分布,即在达到
total_count
次失败之前,独立且相同的伯努利试验成功的次数的分布。每次伯努利试验成功的概率为probs
。- Parameters
- arg_constraints = {'logits': Real(), 'probs': HalfOpenInterval(lower_bound=0.0, upper_bound=1.0), 'total_count': GreaterThanEq(lower_bound=0)}¶
- property logits¶
- property mean¶
- property mode¶
- property param_shape¶
- property probs¶
- support = IntegerGreaterThan(lower_bound=0)¶
- property variance¶
正常¶
- class torch.distributions.normal.Normal(loc, scale, validate_args=None)[源代码]¶
-
创建一个正态(也称为高斯)分布,参数化由
loc
和scale
指定。示例:
>>> m = Normal(torch.tensor([0.0]), torch.tensor([1.0])) >>> m.sample() # 正态分布,均值为0,标准差为1 tensor([ 0.1046])
- arg_constraints = {'loc': Real(), 'scale': GreaterThan(lower_bound=0.0)}¶
- has_rsample = True¶
- property mean¶
- property mode¶
- property stddev¶
- support = Real()¶
- property variance¶
OneHotCategorical¶
- class torch.distributions.one_hot_categorical.OneHotCategorical(probs=None, logits=None, validate_args=None)[源代码]¶
基类:
Distribution
创建一个由
probs
或logits
参数化的一热分类分布。样本是大小为
probs.size(-1)
的独热编码向量。注意
参数 probs 必须是非负的、有限的并且具有非零的总和,它将被归一化以沿最后一个维度总和为1。
probs
将返回这个归一化后的值。 参数 logits 将被解释为未归一化的对数概率,因此可以是任何实数。它同样将被归一化,使得结果概率沿最后一个维度总和为1。logits
将返回这个归一化后的值。另请参阅:
torch.distributions.Categorical()
以了解probs
和logits
的规范。示例:
>>> m = OneHotCategorical(torch.tensor([ 0.25, 0.25, 0.25, 0.25 ])) >>> m.sample() # 0, 1, 2, 3的概率相等 tensor([ 0., 0., 0., 1.])
- arg_constraints = {'logits': IndependentConstraint(Real(), 1), 'probs': Simplex()}¶
- has_enumerate_support = True¶
- property logits¶
- property mean¶
- property mode¶
- property param_shape¶
- property probs¶
- support = OneHot()¶
- property variance¶
帕累托¶
- class torch.distributions.pareto.Pareto(scale, alpha, validate_args=None)[源代码]¶
-
来自帕累托I型分布的样本。
示例:
>>> m = Pareto(torch.tensor([1.0]), torch.tensor([1.0])) >>> m.sample() # 从尺度为1,alpha为1的帕累托分布中采样 tensor([ 1.5623])
- arg_constraints: Dict[str, 约束] = {'alpha': GreaterThan(lower_bound=0.0), 'scale': GreaterThan(lower_bound=0.0)}¶
- property mean¶
- property mode¶
- property support¶
- property variance¶
泊松¶
- class torch.distributions.poisson.Poisson(rate, validate_args=None)[源代码]¶
-
创建一个由
rate
参数化的泊松分布,即速率参数。样本是非负整数,其概率质量函数由以下给出
示例:
>>> m = Poisson(torch.tensor([4])) >>> m.sample() tensor([ 3.])
- Parameters
rate (数字, 张量) – 速率参数
- arg_constraints = {'rate': GreaterThanEq(lower_bound=0.0)}¶
- property mean¶
- property mode¶
- support = IntegerGreaterThan(lower_bound=0)¶
- property variance¶
RelaxedBernoulli¶
- class torch.distributions.relaxed_bernoulli.RelaxedBernoulli(temperature, probs=None, logits=None, validate_args=None)[源代码]¶
-
创建一个RelaxedBernoulli分布,由
temperature
参数化,并且由probs
或logits
(但不能同时使用两者)。这是Bernoulli分布的松弛版本, 因此值在(0, 1)之间,并且具有可重参数化的样本。示例:
>>> m = RelaxedBernoulli(torch.tensor([2.2]), ... torch.tensor([0.1, 0.2, 0.3, 0.99])) >>> m.sample() tensor([ 0.2951, 0.3442, 0.8918, 0.9021])
- arg_constraints: Dict[str, 约束] = {'logits': Real(), 'probs': Interval(lower_bound=0.0, upper_bound=1.0)}¶
- has_rsample = True¶
- property logits¶
- property probs¶
- support = Interval(lower_bound=0.0, upper_bound=1.0)¶
- property temperature¶
LogitRelaxedBernoulli¶
- class torch.distributions.relaxed_bernoulli.LogitRelaxedBernoulli(temperature, probs=None, logits=None, validate_args=None)[源代码]¶
基类:
Distribution
创建一个由
probs
或logits
(但不能同时使用两者)参数化的 LogitRelaxedBernoulli 分布,该分布是 RelaxedBernoulli 分布的对数几率。样本是(0, 1)区间内值的对数几率。更多细节请参见[1]。
[1] 具体分布:离散随机变量的连续松弛(Maddison 等,2017)
[2] 使用Gumbel-Softmax的分类重参数化(Jang等,2017)
- arg_constraints = {'logits': Real(), 'probs': Interval(lower_bound=0.0, upper_bound=1.0)}¶
- property logits¶
- property param_shape¶
- property probs¶
- support = Real()¶
RelaxedOneHotCategorical¶
- class torch.distributions.relaxed_categorical.RelaxedOneHotCategorical(temperature, probs=None, logits=None, validate_args=None)[源代码]¶
-
创建一个由
temperature
,以及probs
或logits
参数化的 RelaxedOneHotCategorical 分布。 这是OneHotCategorical
分布的松弛版本,因此 其样本位于单纯形上,并且是可重参数化的。示例:
>>> 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])
- has_rsample = True¶
- property logits¶
- property probs¶
- support = Simplex()¶
- property temperature¶
学生T¶
- class torch.distributions.studentT.StudentT(df, loc=0.0, scale=1.0, validate_args=None)[源代码]¶
基类:
Distribution
创建一个由自由度
df
、均值loc
和尺度scale
参数化的学生 t 分布。示例:
>>> m = StudentT(torch.tensor([2.0])) >>> m.sample() # 学生t分布,自由度为2 tensor([ 0.1046])
- arg_constraints = {'df': GreaterThan(lower_bound=0.0), 'loc': Real(), 'scale': GreaterThan(lower_bound=0.0)}¶
- has_rsample = True¶
- property mean¶
- property mode¶
- support = Real()¶
- property variance¶
变换分布¶
- class torch.distributions.transformed_distribution.TransformedDistribution(base_distribution, transforms, validate_args=None)[源代码]¶
基类:
Distribution
Distribution类的扩展,它将一系列Transform应用于基础分布。设f为应用的变换的组合:
X ~ BaseDistribution Y = f(X) ~ TransformedDistribution(BaseDistribution, f) log p(Y) = log p(X) + log |det (dX/dY)|
请注意,
.event_shape
的TransformedDistribution
是其基础分布及其变换的最大形状,因为变换可以在事件之间引入相关性。一个使用
TransformedDistribution
的示例是:# 构建一个逻辑分布 # X ~ 均匀分布(0, 1) # f = a + b * logit(X) # Y ~ f(X) ~ 逻辑分布(a, b) base_distribution = Uniform(0, 1) transforms = [SigmoidTransform().inv, AffineTransform(loc=a, scale=b)] logistic = TransformedDistribution(base_distribution, transforms)
更多示例,请查看
Gumbel
,HalfCauchy
,HalfNormal
,LogNormal
,Pareto
,Weibull
,RelaxedBernoulli
和RelaxedOneHotCategorical
的实现- property has_rsample¶
- rsample(sample_shape=torch.Size([]))[源代码]¶
生成一个sample_shape形状的重参数化样本,或者如果分布参数是批量的,则生成一个sample_shape形状的批量重参数化样本。首先从基本分布中采样,并对列表中的每个变换应用transform()。
- sample(sample_shape=torch.Size([]))[源代码]¶
生成一个 sample_shape 形状的样本或 sample_shape 形状的批次样本(如果分布参数是批次的)。首先从基础分布中采样,并对列表中的每个变换应用 transform()。
- property support¶
均匀分布¶
- class torch.distributions.uniform.Uniform(low, high, validate_args=None)[源代码]¶
基类:
Distribution
生成从半开区间均匀分布的随机样本
[low, high)
。示例:
>>> m = Uniform(torch.tensor([0.0]), torch.tensor([5.0])) >>> m.sample() # 在范围 [0.0, 5.0) 内均匀分布 tensor([ 2.3418])
- arg_constraints = {'high': Dependent(), 'low': Dependent()}¶
- has_rsample = True¶
- property mean¶
- property mode¶
- property stddev¶
- property support¶
- property variance¶
冯·米塞斯¶
- class torch.distributions.von_mises.VonMises(loc, concentration, validate_args=None)[源代码]¶
基类:
Distribution
一个循环的von Mises分布。
此实现使用极坐标。
loc
和value
参数可以是任何实数(以便于无约束优化),但被解释为模 2 pi 的角度。- Example::
>>> m = VonMises(torch.tensor([1.0]), torch.tensor([1.0])) >>> m.sample() # 冯·米塞斯分布,位置参数为1,集中度为1 tensor([1.9777])
- Parameters
loc (torch.Tensor) – 一个以弧度为单位的角度。
浓度 (torch.Tensor) – 浓度参数
- arg_constraints = {'concentration': GreaterThan(lower_bound=0.0), 'loc': Real()}¶
- has_rsample = False¶
- property mean¶
提供的平均值是循环的。
- property mode¶
- sample(sample_shape=torch.Size([]))[源代码]¶
von Mises 分布的采样算法基于以下论文:D.J. Best 和 N.I. Fisher,“高效模拟 von Mises 分布”。应用统计学 (1979): 152-157。
采样总是在内部以双精度进行,以避免在浓度值较小时 _rejection_sample() 中出现挂起的情况,这种情况在单精度下大约在 1e-4 时开始发生(参见问题 #88443)。
- support = Real()¶
- property variance¶
提供的方差是循环的。
威布尔¶
- class torch.distributions.weibull.Weibull(scale, concentration, validate_args=None)[源代码]¶
-
来自双参数威布尔分布的样本。
示例
>>> m = Weibull(torch.tensor([1.0]), torch.tensor([1.0])) >>> m.sample() # 从尺度为1,浓度为1的韦伯分布中采样 tensor([ 0.4784])
- arg_constraints: Dict[str, 约束] = {'concentration': GreaterThan(lower_bound=0.0), 'scale': GreaterThan(lower_bound=0.0)}¶
- property mean¶
- property mode¶
- support = GreaterThan(lower_bound=0.0)¶
- property variance¶
Wishart¶
- class torch.distributions.wishart.Wishart(df, covariance_matrix=None, precision_matrix=None, scale_tril=None, validate_args=None)[源代码]¶
-
创建一个由对称正定矩阵 参数化的Wishart分布, 或者其Cholesky分解
示例
>>> m = Wishart(torch.Tensor([2]), covariance_matrix=torch.eye(2)) >>> m.sample() # 均值为`df * I`的Wishart分布 >>> # 方差(x_ij)=`df` 当 i != j 且 方差(x_ij)=`2 * df` 当 i == j
- Parameters
注意
只能指定
covariance_matrix
或precision_matrix
或scale_tril
中的一个。 使用scale_tril
会更高效:所有内部计算 都基于scale_tril
。如果传递了covariance_matrix
或precision_matrix
,则仅用于通过 Cholesky 分解计算 相应的下三角矩阵。 ‘torch.distributions.LKJCholesky’ 是受限的 Wishart 分布。[1]参考文献
[1] Wang, Z., Wu, Y. 和 Chu, H., 2018. 关于LKJ分布与受限Wishart分布的等价性. [2] Sawyer, S., 2007. Wishart分布与逆Wishart采样. [3] Anderson, T. W., 2003. 多元统计分析导论(第三版). [4] Odell, P. L. 和 Feiveson, A. H., 1966. 生成样本协方差矩阵的数值程序. JASA, 61(313):199-203. [5] Ku, Y.-C. 和 Bloomfield, P., 2010. 在OX中生成具有分数自由度的随机Wishart矩阵.
- arg_constraints = {'covariance_matrix': PositiveDefinite(), 'df': GreaterThan(lower_bound=0), 'precision_matrix': PositiveDefinite(), 'scale_tril': LowerCholesky()}¶
- property covariance_matrix¶
- has_rsample = True¶
- property mean¶
- property mode¶
- property precision_matrix¶
- rsample(sample_shape=torch.Size([]), max_try_correction=None)[源代码]¶
警告
在某些情况下,基于Bartlett分解的采样算法可能会返回奇异矩阵样本。默认情况下会进行多次尝试来纠正奇异样本,但最终仍可能返回奇异矩阵样本。奇异样本可能会在.log_prob()中返回-inf值。在这些情况下,用户应验证样本,并相应地调整df的值或调整.rsample参数中的max_try_correction值。
- property scale_tril¶
- support = PositiveDefinite()¶
- property variance¶
KL散度¶
- torch.distributions.kl.kl_divergence(p, q)[源代码]¶
计算两个分布之间的Kullback-Leibler散度 。
- Parameters
- Returns
一批形状为 batch_shape 的 KL 散度。
- Return type
- Raises
NotImplementedError – 如果分布类型尚未通过
register_kl()
注册。
- KL divergence is currently implemented for the following distribution pairs:
Bernoulli
和Bernoulli
伯努利
和泊松
Beta
和Beta
Beta
和ContinuousBernoulli
Beta
和Exponential
Beta
和Gamma
Beta
和Normal
Beta
和Pareto
Beta
和Uniform
Binomial
和Binomial
Categorical
和Categorical
Cauchy
和Cauchy
ContinuousBernoulli
和ContinuousBernoulli
ContinuousBernoulli
和Exponential
ContinuousBernoulli
和Normal
ContinuousBernoulli
和Pareto
ContinuousBernoulli
和Uniform
Dirichlet
和Dirichlet
Exponential
和Beta
Exponential
和ContinuousBernoulli
Exponential
和Exponential
指数
和伽马
Exponential
和Gumbel
Exponential
和Normal
Exponential
和Pareto
Exponential
和Uniform
ExponentialFamily
和ExponentialFamily
Gamma
和Beta
Gamma
和ContinuousBernoulli
Gamma
和Exponential
Gamma
和Gamma
Gamma
和Gumbel
Gamma
和Normal
Gamma
和Pareto
Gamma
和Uniform
Geometric
和Geometric
Gumbel
和Beta
Gumbel
和ContinuousBernoulli
Gumbel
和Exponential
Gumbel
和Gamma
Gumbel
和Gumbel
Gumbel
和Normal
Gumbel
和Pareto
Gumbel
和Uniform
HalfNormal
和HalfNormal
Independent
和Independent
Laplace
和Beta
Laplace
和ContinuousBernoulli
Laplace
和Exponential
Laplace
和Gamma
Laplace
和Laplace
Laplace
和Normal
Laplace
和Pareto
Laplace
和Uniform
LowRankMultivariateNormal
和LowRankMultivariateNormal
LowRankMultivariateNormal
和MultivariateNormal
MultivariateNormal
和LowRankMultivariateNormal
MultivariateNormal
和MultivariateNormal
Normal
和Beta
Normal
和ContinuousBernoulli
Normal
和Exponential
Normal
和Gamma
Normal
和Gumbel
Normal
和Laplace
Normal
和Normal
Normal
和Pareto
Normal
和Uniform
OneHotCategorical
和OneHotCategorical
Pareto
和Beta
Pareto
和ContinuousBernoulli
Pareto
和Exponential
Pareto
和Gamma
Pareto
和Normal
Pareto
和Pareto
Pareto
和Uniform
Poisson
和Bernoulli
Poisson
和Binomial
Poisson
和Poisson
TransformedDistribution
和TransformedDistribution
Uniform
和Beta
Uniform
和ContinuousBernoulli
Uniform
和Exponential
Uniform
和Gamma
Uniform
和Gumbel
Uniform
和Normal
Uniform
和Pareto
Uniform
和Uniform
- torch.distributions.kl.register_kl(type_p, type_q)[源代码]¶
用于将成对函数注册到
kl_divergence()
的装饰器。 用法:@register_kl(Normal, Normal) def kl_normal_normal(p, q): # 在此插入实现
查找返回按子类排序的最具体的(类型,类型)匹配。如果匹配不明确,则会引发RuntimeWarning。例如,为了解决不明确的情况:
@register_kl(BaseP, DerivedQ) def kl_version1(p, q): ... @register_kl(DerivedP, BaseQ) def kl_version2(p, q): ...
你应该注册一个第三最具体的实现,例如:
register_kl(DerivedP, DerivedQ)(kl_version1) # 打破平局。
变换¶
- class torch.distributions.transforms.AffineTransform(loc, scale, event_dim=0, cache_size=0)[源代码]¶
通过逐点仿射映射进行变换 .
- class torch.distributions.transforms.CatTransform(tseq, dim=0, lengths=None, cache_size=0)[源代码]¶
转换仿函数,逐组件地将一系列转换 tseq 应用于每个子矩阵,该子矩阵位于 dim 维度上,长度为 lengths[dim],并以与
torch.cat()
兼容的方式进行。示例:
x0 = torch.cat([torch.range(1, 10), torch.range(1, 10)], dim=0) x = torch.cat([x0, x0], dim=0) t0 = CatTransform([ExpTransform(), identity_transform], dim=0, lengths=[10, 10]) t = CatTransform([t0, t0], dim=0, lengths=[20, 20]) y = t(x)
- class torch.distributions.transforms.ComposeTransform(parts, cache_size=0)[源代码]¶
将多个变换组合成一个链。 被组合的变换负责缓存。
- class torch.distributions.transforms.CorrCholeskyTransform(cache_size=0)[源代码]¶
将一个长度为 的无约束实向量 转换为 D 维相关矩阵的 Cholesky 因子。该 Cholesky 因子是一个对角线为正的下三角矩阵,并且每行的欧几里得范数为单位。转换过程如下:
首先我们将x转换为按行顺序排列的下三角矩阵。
对于下三角部分的每一行 ,我们应用一个带符号版本的 类
StickBreakingTransform
来将 转换为 单位欧几里得长度向量,使用以下步骤: - 缩放到区间 域:。 - 转换为无符号域:。 - 应用 。 - 转换回带符号域:
- class torch.distributions.transforms.CumulativeDistributionTransform(distribution, cache_size=0)[源代码]¶
通过概率分布的累积分布函数进行转换。
- Parameters
分布 (分布) – 用于变换的累积分布函数所属的分布。
示例:
# 从多元正态分布构建一个高斯Copula。 base_dist = MultivariateNormal( loc=torch.zeros(2), scale_tril=LKJCholesky(2).sample(), ) transform = CumulativeDistributionTransform(Normal(0, 1)) copula = TransformedDistribution(base_dist, [transform])
- class torch.distributions.transforms.IndependentTransform(base_transform, reinterpreted_batch_ndims, cache_size=0)[源代码]¶
包装另一个变换,将
reinterpreted_batch_ndims
个额外的最右维度视为 依赖。这不会影响正向或反向变换,但在log_abs_det_jacobian()
中会累加reinterpreted_batch_ndims
个最右维度。
- class torch.distributions.transforms.LowerCholeskyTransform(cache_size=0)[源代码]¶
将无约束矩阵转换为具有非负对角线元素的下三角矩阵。
这对于以Cholesky分解的形式参数化正定矩阵非常有用。
- class torch.distributions.transforms.ReshapeTransform(in_shape, out_shape, cache_size=0)[源代码]¶
单位雅可比变换用于重塑张量的最右侧部分。
请注意,
in_shape
和out_shape
必须具有相同数量的元素,就像torch.Tensor.reshape()
一样。- Parameters
in_shape (torch.Size) – 输入事件形状。
out_shape (torch.Size) – 输出事件形状。
- class torch.distributions.transforms.SoftplusTransform(cache_size=0)[源代码]¶
通过映射 进行转换。 当 时,实现会恢复为线性函数。
- class torch.distributions.transforms.TanhTransform(cache_size=0)[源代码]¶
通过映射进行变换 。
它等同于
` ComposeTransform([AffineTransform(0., 2.), SigmoidTransform(), AffineTransform(-1., 2.)]) `
然而,这可能在数值上不稳定,因此建议使用TanhTransform 代替。请注意,当涉及到NaN/Inf值时,应使用cache_size=1。
- class torch.distributions.transforms.SoftmaxTransform(cache_size=0)[源代码]¶
通过 从无约束空间转换到单纯形,然后进行归一化。
这不是双射的,不能用于HMC。然而,这主要是按坐标操作的(除了最终的归一化),因此适用于按坐标优化的算法。
- class torch.distributions.transforms.StackTransform(tseq, dim=0, cache_size=0)[源代码]¶
转换仿函数,逐组件地将一系列转换 tseq 应用于 dim 处的每个子矩阵,其方式与
torch.stack()
兼容。示例:
x = torch.stack([torch.range(1, 10), torch.range(1, 10)], dim=1) t = StackTransform([ExpTransform(), identity_transform], dim=1) y = t(x)
- class torch.distributions.transforms.StickBreakingTransform(cache_size=0)[源代码]¶
通过分段过程将无约束空间转换为增加一个维度的单纯形。
这种变换作为Dirichlet分布的分割构造中的迭代sigmoid变换出现:第一个logit通过sigmoid变换为第一个概率和所有其他概率,然后这个过程递归进行。
这是双射的,适用于HMC;然而,它将坐标混合在一起,不太适合优化。
- class torch.distributions.transforms.Transform(cache_size=0)[源代码]¶
用于具有可计算对数行列式雅可比矩阵的可逆变换的抽象类。它们主要用于
torch.distributions.TransformedDistribution
。缓存对于那些逆变换代价高昂或数值不稳定的变换非常有用。需要注意的是,使用记忆化值时必须小心,因为自动求导图可能会被反转。例如,以下代码无论是否使用缓存都能正常工作:
y = t(x) t.log_abs_det_jacobian(x, y).backward() # x 将接收梯度。
然而,由于依赖反转,以下内容在缓存时会出现错误:
y = t(x) z = t.inv(y) grad(z.sum(), [y]) # 错误,因为 z 是 x
派生类应实现
_call()
或_inverse()
中的一个或两个。设置 bijective=True 的派生类还应 实现log_abs_det_jacobian()
。- Parameters
cache_size (int) – 缓存大小。如果为零,则不进行缓存。如果为一,则缓存最新的单个值。仅支持0和1。
- Variables
domain (
Constraint
) – 表示此变换的有效输入的约束。目标域 (
Constraint
) – 表示此变换的有效输出的约束,这些输出是反变换的输入。双射 (bool) – 此变换是否为双射。一个变换
t
是双射当且仅当t.inv(t(x)) == x
且t(t.inv(y)) == y
对于定义域中的每个x
和陪域中的每个y
。非双射的变换至少应保持较弱的伪逆性质t(t.inv(t(x)) == t(x)
和t.inv(t(t.inv(y))) == t.inv(y)
。
- property sign¶
返回雅可比行列式的符号(如果适用)。 通常,这仅对双射变换有意义。
约束¶
以下约束已实现:
constraints.boolean
constraints.cat
constraints.corr_cholesky
constraints.dependent
constraints.greater_than(lower_bound)
constraints.greater_than_eq(lower_bound)
constraints.independent(constraint, reinterpreted_batch_ndims)
constraints.integer_interval(下界, 上界)
constraints.interval(lower_bound, upper_bound)
constraints.less_than(upper_bound)
constraints.lower_cholesky
constraints.lower_triangular
constraints.multinomial
constraints.nonnegative
constraints.nonnegative_integer
constraints.one_hot
constraints.positive_integer
constraints.positive
constraints.positive_semidefinite
constraints.positive_definite
constraints.real_vector
constraints.real
constraints.simplex
constraints.symmetric
constraints.stack
constraints.square
constraints.symmetric
constraints.unit_interval
- class torch.distributions.constraints.Constraint[源代码]¶
约束的抽象基类。
约束对象表示变量有效的区域,例如,在该区域内可以对变量进行优化。
- Variables
- torch.distributions.constraints.cat¶
别名
_Cat
- torch.distributions.constraints.dependent_property¶
别名
_DependentProperty
- torch.distributions.constraints.greater_than¶
别名
_GreaterThan
- torch.distributions.constraints.greater_than_eq¶
别名
_GreaterThanEq
- torch.distributions.constraints.independent¶
别名
_IndependentConstraint
- torch.distributions.constraints.integer_interval¶
别名
_IntegerInterval
- torch.distributions.constraints.interval¶
别名
_Interval
- torch.distributions.constraints.half_open_interval¶
别名
_HalfOpenInterval
- torch.distributions.constraints.less_than¶
别名
_LessThan
- torch.distributions.constraints.multinomial¶
别名
_Multinomial
- torch.distributions.constraints.stack¶
别名
_Stack
约束注册表¶
PyTorch 提供了两个全局 ConstraintRegistry
对象,这些对象将
Constraint
对象与
Transform
对象链接起来。这两个对象都
接受约束并返回变换,但它们在双射性方面有不同的保证。
biject_to(constraint)
查找一个从constraints.real
到给定constraint
的双射Transform
。返回的变换保证具有.bijective = True
并且应该实现.log_abs_det_jacobian()
。transform_to(constraint)
查找一个不一定双射的Transform
从constraints.real
到给定的constraint
。返回的变换不保证实现.log_abs_det_jacobian()
。
注册表 transform_to()
对于在概率分布的约束参数上执行无约束优化非常有用,这些约束由每个分布的 .arg_constraints
字典指示。这些变换通常会过度参数化一个空间以避免旋转;因此,它们更适合像 Adam 这样的坐标优化算法:
loc = torch.zeros(100, requires_grad=True)
unconstrained = torch.zeros(100, requires_grad=True)
scale = transform_to(Normal.arg_constraints['scale'])(unconstrained)
loss = -Normal(loc, scale).log_prob(data).sum()
注册表 biject_to()
对于哈密顿蒙特卡洛(Hamiltonian Monte Carlo)很有用,其中
从具有约束 .support
的概率分布中采样的样本
在无约束空间中传播,并且算法通常是旋转不变的。
dist = Exponential(rate)
unconstrained = torch.zeros(100, requires_grad=True)
sample = biject_to(dist.support)(unconstrained)
potential_energy = -dist.log_prob(sample).sum()
注意
一个transform_to
和 biject_to
不同的例子是
constraints.simplex
:transform_to(constraints.simplex)
返回一个
SoftmaxTransform
,它只是对其输入进行指数化和归一化;这是一个廉价且主要是坐标式的操作,适用于像SVI这样的算法。相比之下,biject_to(constraints.simplex)
返回一个
StickBreakingTransform
,它将其输入映射到一个更低维的空间;这是一个更昂贵且数值稳定性较差的变换,但对于像HMC这样的算法是必需的。
可以使用用户定义的约束和变换通过它们的 .register()
方法来扩展 biject_to
和 transform_to
对象,方法可以是作为单例约束的函数:
transform_to.register(my_constraint, my_transform)
或作为参数化约束的装饰器:
@transform_to.register(MyConstraintClass)
def my_factory(constraint):
assert isinstance(constraint, MyConstraintClass)
return MyTransform(constraint.param1, constraint.param2)
您可以通过创建一个新的 ConstraintRegistry
对象来创建自己的注册表。
- class torch.distributions.constraint_registry.ConstraintRegistry[源代码]¶
注册表以将约束链接到变换。
- register(constraint, factory=None)[源代码]¶
在此注册表中注册一个
Constraint
子类。用法:@my_registry.register(MyConstraintClass) def construct_transform(constraint): assert isinstance(constraint, MyConstraint) return MyTransform(constraint.arg_constraints)
- Parameters
约束(
Constraint
的子类) –Constraint
的子类,或所需类的单例对象。工厂 (可调用) – 一个可调用对象,输入一个约束对象并返回一个
Transform
对象。