概率分布 - torch.distributions#
创建于:2017年10月19日 | 最后更新于:2025年6月13日
distributions
包包含可参数化的概率分布和采样函数。这允许构建用于优化的随机计算图和随机梯度估计器。该包通常遵循 TensorFlow Distributions 包的设计。
无法直接反向传播随机样本。但是,有两种主要方法可以创建可反向传播的代理函数:得分函数估计器/似然比估计器/REINFORCE 和路径wise导数估计器。REINFORCE 通常被视为强化学习中策略梯度方法的基础,而路径wise导数估计器通常出现在变分自编码器中的重参数化技巧中。虽然得分函数仅需要样本 的值,路径wise导数需要导数 。接下来的几节将在强化学习示例中讨论这两种方法。更多详情请参阅 使用随机计算图进行梯度估计。
得分函数#
当概率密度函数相对于其参数可微时,我们只需要 sample()
和 log_prob()
来实现 REINFORCE。
其中 是参数, 是学习率, 是奖励, 是在策略 下,状态 下采取动作 的概率。
实际上,我们将从网络的输出中采样一个动作,在环境中应用该动作,然后使用 log_prob
来构建等效的损失函数。请注意,我们使用的是负号,因为优化器使用梯度下降,而上述规则假定梯度上升。对于分类策略,实现 REINFORCE 的代码如下:
probs = policy_network(state)
# Note that this is equivalent to what used to be called multinomial
m = Categorical(probs)
action = m.sample()
next_state, reward = env.step(action)
loss = -m.log_prob(action) * reward
loss.backward()
路径wise导数#
实现这些随机/策略梯度的另一种方法是使用 rsample()
方法中的重参数化技巧,其中参数化随机变量可以通过无参数随机变量的参数化确定性函数来构造。因此,重参数化样本变得可微分。实现路径wise导数的代码如下:
params = policy_network(state)
m = Normal(*params)
# Any distribution with .has_rsample == True could work based on the application
action = m.rsample()
next_state, reward = env.step(action) # Assuming that reward is differentiable
loss = -reward
loss.backward()
Distribution#
- class torch.distributions.distribution.Distribution(batch_shape=torch.Size([]), event_shape=torch.Size([]), validate_args=None)[source]#
Bases:
object
Distribution 是概率分布的抽象基类。
- 参数
batch_shape (torch.Size) – 参数被分批处理的形状。
event_shape (torch.Size) – 单个样本(不带批处理)的形状。
validate_args (bool, optional) – 是否验证参数。默认值:None。
- property arg_constraints: dict[str, torch.distributions.constraints.Constraint]#
返回一个字典,将参数名称映射到
Constraint
对象,这些对象应由此分布的每个参数满足。不在此字典中的参数(非张量)无需考虑。
- enumerate_support(expand=True)[source]#
返回一个包含离散分布所有支持值的张量。结果将枚举维度 0,因此结果的形状为 (基数,) + batch_shape + event_shape(其中单变量分布的 event_shape = ())。
请注意,这会以同步方式枚举所有批处理张量,例如 [[0, 0], [1, 1], …]。当 expand=False 时,枚举沿 dim 0 进行,但其余批处理维度为单例维度,即 [[0], [1], .. 。
要迭代完整的笛卡尔积,请使用 itertools.product(m.enumerate_support())。
- expand(batch_shape, _instance=None)[source]#
返回一个新的分布实例(或填充由派生类提供的现有实例),其批处理维度已扩展到 batch_shape。此方法调用分布参数上的
expand
。因此,这不会为扩展的分布实例分配新内存。此外,这不会在实例首次创建时重复 __init__.py 中的任何参数检查或广播。- 参数
batch_shape (torch.Size) – 所需的扩展大小。
_instance – 由需要重写 .expand 的子类提供的新的实例。
- 返回
具有批处理维度扩展到 batch_size 的新分布实例。
- rsample(sample_shape=torch.Size([]))[source]#
生成 sample_shape 形状的重参数化样本,如果分布参数是批处理的,则生成 sample_shape 形状的重参数化样本批次。
- 返回类型
- sample(sample_shape=torch.Size([]))[source]#
生成 sample_shape 形状的样本,如果分布参数是批处理的,则生成 sample_shape 形状的样本批次。
- 返回类型
- static set_default_validate_args(value)[source]#
设置是否启用或禁用验证。
默认行为模仿 Python 的
assert
语句:默认情况下启用验证,但如果 Python 在优化模式下运行(通过python -O
),则禁用验证。验证可能很昂贵,因此一旦模型工作正常,您可能希望禁用它。- 参数
value (bool) – 是否启用验证。
- property support: Optional[Constraint]#
返回一个
Constraint
对象,表示此分布的支持域。
ExponentialFamily#
- class torch.distributions.exp_family.ExponentialFamily(batch_shape=torch.Size([]), event_shape=torch.Size([]), validate_args=None)[source]#
Bases:
Distribution
ExponentialFamily 是属于指数族的概率分布的抽象基类,其概率质量/密度函数形式如下:
其中 表示自然参数, 表示充分统计量, 是给定族对的对数归一化函数, 是载体测度。
注意
此类是 Distribution 类和属于指数族的分布之间的中间项,主要用于检查 .entropy() 和解析 KL 散度方法的正确性。我们使用此类通过对数归一化函数的 Bregman 散度来计算熵和 KL 散度(来源:Frank Nielsen 和 Richard Nock,Entropies and Cross-entropies of Exponential Families)。
Bernoulli#
- class torch.distributions.bernoulli.Bernoulli(probs=None, logits=None, validate_args=None)[source]#
Bases:
ExponentialFamily
使用
probs
或logits
(但不能同时)参数化的 Bernoulli 分布。样本是二元的(0 或 1)。它们以概率 p 取值 1,以概率 1 - p 取值 0。
示例
>>> m = Bernoulli(torch.tensor([0.3])) >>> m.sample() # 30% chance 1; 70% chance 0 tensor([ 0.])
- 参数
- arg_constraints = {'logits': Real(), 'probs': Interval(lower_bound=0.0, upper_bound=1.0)}#
- has_enumerate_support = True#
- support = Boolean()#
Beta#
- class torch.distributions.beta.Beta(concentration1, concentration0, validate_args=None)[source]#
Bases:
ExponentialFamily
由
concentration1
和concentration0
参数化的 Beta 分布。示例
>>> m = Beta(torch.tensor([0.5]), torch.tensor([0.5])) >>> m.sample() # Beta distributed with concentration concentration1 and concentration0 tensor([ 0.1046])
- 参数
- arg_constraints = {'concentration0': GreaterThan(lower_bound=0.0), 'concentration1': GreaterThan(lower_bound=0.0)}#
- has_rsample = True#
- support = Interval(lower_bound=0.0, upper_bound=1.0)#
Binomial#
- class torch.distributions.binomial.Binomial(total_count=1, probs=None, logits=None, validate_args=None)[source]#
Bases:
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 support#
- 返回类型
_DependentProperty
Categorical#
- class torch.distributions.categorical.Categorical(probs=None, logits=None, validate_args=None)[source]#
Bases:
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() # equal probability of 0, 1, 2, 3 tensor(3)
- arg_constraints = {'logits': IndependentConstraint(Real(), 1), 'probs': Simplex()}#
- has_enumerate_support = True#
- property support#
- 返回类型
_DependentProperty
Cauchy#
- class torch.distributions.cauchy.Cauchy(loc, scale, validate_args=None)[source]#
Bases:
Distribution
从柯西(洛伦兹)分布采样。均值为 0 的独立正态分布随机变量之比的分布遵循柯西分布。
示例
>>> m = Cauchy(torch.tensor([0.0]), torch.tensor([1.0])) >>> m.sample() # sample from a Cauchy distribution with loc=0 and scale=1 tensor([ 2.3214])
- arg_constraints = {'loc': Real(), 'scale': GreaterThan(lower_bound=0.0)}#
- has_rsample = True#
- support = Real()#
Chi2#
- class torch.distributions.chi2.Chi2(df, validate_args=None)[source]#
Bases:
Gamma
创建由形状参数
df
参数化的卡方分布。这与Gamma(alpha=0.5*df, beta=0.5)
完全等价。示例
>>> m = Chi2(torch.tensor([1.0])) >>> m.sample() # Chi2 distributed with shape df=1 tensor([ 0.1046])
- arg_constraints = {'df': GreaterThan(lower_bound=0.0)}#
ContinuousBernoulli#
- class torch.distributions.continuous_bernoulli.ContinuousBernoulli(probs=None, logits=None, lims=(0.499, 0.501), validate_args=None)[source]#
Bases:
ExponentialFamily
使用
probs
或logits
(但不能同时)参数化的连续 Bernoulli 分布。该分布的支持域为 [0, 1],由 'probs'(在 (0,1) 内)或 'logits'(实数值)参数化。请注意,与 Bernoulli 不同,'probs' 不代表概率,'logits' 也不代表对数几率,但由于与 Bernoulli 的相似性,使用了相同的名称。更多详情请参阅 [1]。
示例
>>> m = ContinuousBernoulli(torch.tensor([0.3])) >>> m.sample() tensor([ 0.2538])
[1] The continuous Bernoulli: fixing a pervasive error in variational autoencoders, Loaiza-Ganem G and 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#
- support = Interval(lower_bound=0.0, upper_bound=1.0)#
Dirichlet#
- class torch.distributions.dirichlet.Dirichlet(concentration, validate_args=None)[源码]#
Bases:
ExponentialFamily
创建一个由
concentration
参数化的 Dirichlet 分布。示例
>>> m = Dirichlet(torch.tensor([0.5, 0.5])) >>> m.sample() # Dirichlet distributed with concentration [0.5, 0.5] tensor([ 0.1046, 0.8954])
- 参数
concentration (Tensor) – 分布的 concentration 参数(通常称为 alpha)
- arg_constraints = {'concentration': IndependentConstraint(GreaterThan(lower_bound=0.0), 1)}#
- has_rsample = True#
- support = Simplex()#
Exponential#
- class torch.distributions.exponential.Exponential(rate, validate_args=None)[源码]#
Bases:
ExponentialFamily
创建一个由
rate
参数化的 Exponential 分布。示例
>>> m = Exponential(torch.tensor([1.0])) >>> m.sample() # Exponential distributed with rate=1 tensor([ 0.1046])
- arg_constraints = {'rate': GreaterThan(lower_bound=0.0)}#
- has_rsample = True#
- support = GreaterThanEq(lower_bound=0.0)#
FisherSnedecor#
- class torch.distributions.fishersnedecor.FisherSnedecor(df1, df2, validate_args=None)[源码]#
Bases:
Distribution
创建一个由
df1
和df2
参数化的 Fisher-Snedecor 分布。示例
>>> m = FisherSnedecor(torch.tensor([1.0]), torch.tensor([2.0])) >>> m.sample() # Fisher-Snedecor-distributed with df1=1 and df2=2 tensor([ 0.2453])
- 参数
- arg_constraints = {'df1': GreaterThan(lower_bound=0.0), 'df2': GreaterThan(lower_bound=0.0)}#
- has_rsample = True#
- support = GreaterThan(lower_bound=0.0)#
Gamma#
- class torch.distributions.gamma.Gamma(concentration, rate, validate_args=None)[源码]#
Bases:
ExponentialFamily
创建一个由
concentration
和rate
参数化的 Gamma 分布。示例
>>> m = Gamma(torch.tensor([1.0]), torch.tensor([1.0])) >>> m.sample() # Gamma distributed with concentration=1 and rate=1 tensor([ 0.1046])
- 参数
- arg_constraints = {'concentration': GreaterThan(lower_bound=0.0), 'rate': GreaterThan(lower_bound=0.0)}#
- has_rsample = True#
- support = GreaterThanEq(lower_bound=0.0)#
GeneralizedPareto#
- class torch.distributions.generalized_pareto.GeneralizedPareto(loc, scale, concentration, validate_args=None)[源码]#
Bases:
Distribution
创建一个由
loc
、scale
和concentration
参数化的 Generalized Pareto 分布。Generalized Pareto 分布是一类在实线上的连续概率分布。特殊情况包括指数分布(当
loc
= 0,concentration
= 0),Pareto 分布(当concentration
> 0,loc
=scale
/concentration
),以及均匀分布(当concentration
= -1)。该分布常用于对其他分布的尾部进行建模。此实现基于 TensorFlow Probability 中的实现。
示例
>>> m = GeneralizedPareto(torch.tensor([0.1]), torch.tensor([2.0]), torch.tensor([0.4])) >>> m.sample() # sample from a Generalized Pareto distribution with loc=0.1, scale=2.0, and concentration=0.4 tensor([ 1.5623])
- 参数
- arg_constraints: dict[str, torch.distributions.constraints.Constraint] = {'concentration': Real(), 'loc': Real(), 'scale': GreaterThan(lower_bound=0.0)}#
- has_rsample = True#
- property mean#
- property mode#
- property support#
- 返回类型
_DependentProperty
- property variance#
Geometric#
- class torch.distributions.geometric.Geometric(probs=None, logits=None, validate_args=None)[源码]#
Bases:
Distribution
创建一个由
probs
参数化的 Geometric 分布,其中probs
是 Bernoulli 试验成功的概率。注意
torch.distributions.geometric.Geometric()
-th trial is the first success hence draws samples in , whereastorch.Tensor.geometric_()
k-th trial is the first success hence draws samples in .示例
>>> m = Geometric(torch.tensor([0.3])) >>> m.sample() # underlying Bernoulli has 30% chance 1; 70% chance 0 tensor([ 2.])
- 参数
- arg_constraints = {'logits': Real(), 'probs': Interval(lower_bound=0.0, upper_bound=1.0)}#
- support = IntegerGreaterThan(lower_bound=0)#
Gumbel#
- class torch.distributions.gumbel.Gumbel(loc, scale, validate_args=None)[源码]#
Bases:
TransformedDistribution
从 Gumbel 分布采样。
示例
>>> m = Gumbel(torch.tensor([1.0]), torch.tensor([2.0])) >>> m.sample() # sample from Gumbel distribution with loc=1, scale=2 tensor([ 1.0124])
- arg_constraints: dict[str, torch.distributions.constraints.Constraint] = {'loc': Real(), 'scale': GreaterThan(lower_bound=0.0)}#
- support = Real()#
HalfCauchy#
- class torch.distributions.half_cauchy.HalfCauchy(scale, validate_args=None)[源码]#
Bases:
TransformedDistribution
创建一个由 scale 参数化的 half-Cauchy 分布,其中
X ~ Cauchy(0, scale) Y = |X| ~ HalfCauchy(scale)
示例
>>> m = HalfCauchy(torch.tensor([1.0])) >>> m.sample() # half-cauchy distributed with scale=1 tensor([ 2.3214])
- arg_constraints: dict[str, torch.distributions.constraints.Constraint] = {'scale': GreaterThan(lower_bound=0.0)}#
- has_rsample = True#
- support = GreaterThanEq(lower_bound=0.0)#
HalfNormal#
- class torch.distributions.half_normal.HalfNormal(scale, validate_args=None)[源码]#
Bases:
TransformedDistribution
创建一个由 scale 参数化的 half-normal 分布,其中
X ~ Normal(0, scale) Y = |X| ~ HalfNormal(scale)
示例
>>> m = HalfNormal(torch.tensor([1.0])) >>> m.sample() # half-normal distributed with scale=1 tensor([ 0.1046])
- arg_constraints: dict[str, torch.distributions.constraints.Constraint] = {'scale': GreaterThan(lower_bound=0.0)}#
- has_rsample = True#
- support = GreaterThanEq(lower_bound=0.0)#
Independent#
- class torch.distributions.independent.Independent(base_distribution, reinterpreted_batch_ndims, validate_args=None)[源码]#
Bases:
Distribution
,Generic
[D
]将分布的某些 batch 维度重新解释为 event 维度。
这主要用于更改
log_prob()
结果的形状。例如,要创建形状与 Multivariate Normal 分布相同的对角 Normal 分布(以便它们可以互换),您可以>>> 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])]
- 参数
base_distribution (torch.distributions.distribution.Distribution) – a base distribution
reinterpreted_batch_ndims (int) – the number of batch dims to reinterpret as event dims
- arg_constraints: dict[str, torch.distributions.constraints.Constraint] = {}#
- base_dist: D#
- property support#
- 返回类型
_DependentProperty
逆Gamma分布#
- class torch.distributions.inverse_gamma.InverseGamma(concentration, rate, validate_args=None)[源代码]#
Bases:
TransformedDistribution
创建一个由
concentration
和rate
参数化的逆 Gamma 分布,其中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])
- 参数
- arg_constraints: dict[str, torch.distributions.constraints.Constraint] = {'concentration': GreaterThan(lower_bound=0.0), 'rate': GreaterThan(lower_bound=0.0)}#
- has_rsample = True#
- support = GreaterThan(lower_bound=0.0)#
库马拉斯瓦米分布#
- class torch.distributions.kumaraswamy.Kumaraswamy(concentration1, concentration0, validate_args=None)[源代码]#
Bases:
TransformedDistribution
从库马拉斯瓦米分布中采样。
示例
>>> m = Kumaraswamy(torch.tensor([1.0]), torch.tensor([1.0])) >>> m.sample() # sample from a Kumaraswamy distribution with concentration alpha=1 and beta=1 tensor([ 0.1729])
- 参数
- arg_constraints: dict[str, torch.distributions.constraints.Constraint] = {'concentration0': GreaterThan(lower_bound=0.0), 'concentration1': GreaterThan(lower_bound=0.0)}#
- has_rsample = True#
- support = Interval(lower_bound=0.0, upper_bound=1.0)#
LKJCholesky#
- class torch.distributions.lkj_cholesky.LKJCholesky(dim, concentration=1.0, validate_args=None)[源代码]#
Bases:
Distribution
用于相关矩阵的下三角 Cholesky 分解的 LKJ 分布。该分布由
concentration
参数 控制,使得从 Cholesky 分解生成的协方差矩阵 的概率正比于 。因此,当concentration == 1
时,我们得到一个均匀分布在 Cholesky 分解的相关矩阵上的分布。L ~ LKJCholesky(dim, concentration) X = L @ L' ~ LKJCorr(dim, concentration)
请注意,此分布采样的是相关矩阵的 Cholesky 分解,而不是相关矩阵本身,因此与 [1] 中 LKJCorr 分布的推导略有不同。采样时,使用 [1] Section 3 中的 Onion 方法。
示例
>>> l = LKJCholesky(3, 0.5) >>> l.sample() # l @ l.T is a sample of a correlation 3x3 matrix tensor([[ 1.0000, 0.0000, 0.0000], [ 0.3516, 0.9361, 0.0000], [-0.1899, 0.4748, 0.8593]])
参考文献
[1] Generating random correlation matrices based on vines and extended onion method (2009), Daniel Lewandowski, Dorota Kurowicka, Harry Joe. Journal of Multivariate Analysis. 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)[源代码]#
Bases:
Distribution
创建一个由
loc
和scale
参数化的拉普拉斯分布。示例
>>> m = Laplace(torch.tensor([0.0]), torch.tensor([1.0])) >>> m.sample() # Laplace distributed with loc=0, scale=1 tensor([ 0.1046])
- arg_constraints = {'loc': Real(), 'scale': GreaterThan(lower_bound=0.0)}#
- has_rsample = True#
- support = Real()#
对数正态分布#
- class torch.distributions.log_normal.LogNormal(loc, scale, validate_args=None)[源代码]#
Bases:
TransformedDistribution
创建一个由
loc
和scale
参数化的对数正态分布,其中X ~ Normal(loc, scale) Y = exp(X) ~ LogNormal(loc, scale)
示例
>>> m = LogNormal(torch.tensor([0.0]), torch.tensor([1.0])) >>> m.sample() # log-normal distributed with mean=0 and stddev=1 tensor([ 0.1046])
- arg_constraints: dict[str, torch.distributions.constraints.Constraint] = {'loc': Real(), 'scale': GreaterThan(lower_bound=0.0)}#
- has_rsample = True#
- support = GreaterThan(lower_bound=0.0)#
低秩多元正态分布#
- class torch.distributions.lowrank_multivariate_normal.LowRankMultivariateNormal(loc, cov_factor, cov_diag, validate_args=None)[源代码]#
Bases:
Distribution
创建一个具有低秩协方差矩阵的多元正态分布,该分布由
cov_factor
和cov_diag
参数化。covariance_matrix = cov_factor @ cov_factor.T + cov_diag
示例
>>> m = LowRankMultivariateNormal( ... torch.zeros(2), torch.tensor([[1.0], [0.0]]), torch.ones(2) ... ) >>> m.sample() # normally distributed with mean=`[0,0]`, cov_factor=`[[1],[0]]`, cov_diag=`[1,1]` tensor([-0.2102, -0.5429])
- 参数
注意
当 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)}#
- has_rsample = True#
- support = IndependentConstraint(Real(), 1)#
相同族混合分布#
- class torch.distributions.mixture_same_family.MixtureSameFamily(mixture_distribution, component_distribution, validate_args=None)[源代码]#
Bases:
Distribution
MixtureSameFamily 分布实现了一个 (批量的) 混合分布,其中所有组件都来自同一分布类型的不同参数化。它由一个“选择分布” Categorical (用于选择 k 个组件) 和一个组件分布参数化,即一个右侧批次形状 (等于 [k]) 的 Distribution,用于索引每个 (批量的) 组件。
示例
>>> # Construct Gaussian Mixture Model in 1D consisting of 5 equally >>> # weighted normal distributions >>> mix = D.Categorical(torch.ones(5,)) >>> comp = D.Normal(torch.randn(5,), torch.rand(5,)) >>> gmm = MixtureSameFamily(mix, comp) >>> # Construct Gaussian Mixture Model in 2D consisting of 5 equally >>> # weighted bivariate normal distributions >>> mix = D.Categorical(torch.ones(5,)) >>> comp = D.Independent(D.Normal( ... torch.randn(5,2), torch.rand(5,2)), 1) >>> gmm = MixtureSameFamily(mix, comp) >>> # Construct a batch of 3 Gaussian Mixture Models in 2D each >>> # consisting of 5 random weighted bivariate normal distributions >>> 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)
- 参数
mixture_distribution (Categorical) – torch.distributions.Categorical 类实例。管理选择组件的概率。类别数量必须与 component_distribution 的最右侧批次维度匹配。必须具有标量 batch_shape 或 batch_shape 与 component_distribution.batch_shape[:-1] 匹配。
component_distribution (Distribution) – torch.distributions.Distribution 类实例。最右侧批次维度索引组件。
- arg_constraints: dict[str, torch.distributions.constraints.Constraint] = {}#
- property component_distribution: Distribution#
- has_rsample = False#
- property mixture_distribution: Categorical#
- property support#
- 返回类型
_DependentProperty
多项分布#
- class torch.distributions.multinomial.Multinomial(total_count=1, probs=None, logits=None, validate_args=None)[源代码]#
Bases:
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() # equal probability of 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 support#
- 返回类型
_DependentProperty
多元正态分布#
- class torch.distributions.multivariate_normal.MultivariateNormal(loc, covariance_matrix=None, precision_matrix=None, scale_tril=None, validate_args=None)[源代码]#
Bases:
Distribution
创建一个由均值向量和协方差矩阵参数化的多元正态 (也称为高斯) 分布。
多元正态分布可以根据正定协方差矩阵 或正定精度矩阵 或具有正值对角线的下三角矩阵 进行参数化,其中 . 此三角矩阵可通过例如协方差的 Cholesky 分解获得。
示例
>>> m = MultivariateNormal(torch.zeros(2), torch.eye(2)) >>> m.sample() # normally distributed with mean=`[0,0]` and covariance_matrix=`I` tensor([-0.2102, -0.5429])
- 参数
注意
只能指定
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()}#
- has_rsample = True#
- support = IndependentConstraint(Real(), 1)#
NegativeBinomial#
- 类 torch.distributions.negative_binomial.NegativeBinomial(total_count, probs=None, logits=None, validate_args=None)[源]#
Bases:
Distribution
创建一个负二项分布,即在达到
total_count
次失败之前的成功独立且相同的伯努利试验次数的分布。每次伯努利试验的成功概率为probs
。- 参数
- arg_constraints = {'logits': Real(), 'probs': HalfOpenInterval(lower_bound=0.0, upper_bound=1.0), 'total_count': GreaterThanEq(lower_bound=0)}#
- support = IntegerGreaterThan(lower_bound=0)#
Normal#
- 类 torch.distributions.normal.Normal(loc, scale, validate_args=None)[源]#
Bases:
ExponentialFamily
使用
loc
和scale
参数化的正态(也称为高斯)分布。示例
>>> m = Normal(torch.tensor([0.0]), torch.tensor([1.0])) >>> m.sample() # normally distributed with loc=0 and scale=1 tensor([ 0.1046])
- arg_constraints = {'loc': Real(), 'scale': GreaterThan(lower_bound=0.0)}#
- has_rsample = True#
- support = Real()#
OneHotCategorical#
- 类 torch.distributions.one_hot_categorical.OneHotCategorical(probs=None, logits=None, validate_args=None)[源]#
Bases:
Distribution
样本是大小为
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() # equal probability of 0, 1, 2, 3 tensor([ 0., 0., 0., 1.])
- arg_constraints = {'logits': IndependentConstraint(Real(), 1), 'probs': Simplex()}#
- has_enumerate_support = True#
- support = OneHot()#
Pareto#
- 类 torch.distributions.pareto.Pareto(scale, alpha, validate_args=None)[源]#
Bases:
TransformedDistribution
从帕累托 I 型分布中采样。
示例
>>> m = Pareto(torch.tensor([1.0]), torch.tensor([1.0])) >>> m.sample() # sample from a Pareto distribution with scale=1 and alpha=1 tensor([ 1.5623])
- arg_constraints: dict[str, torch.distributions.constraints.Constraint] = {'alpha': GreaterThan(lower_bound=0.0), 'scale': GreaterThan(lower_bound=0.0)}#
- 属性 support: Constraint#
- 返回类型
_DependentProperty
Poisson#
- 类 torch.distributions.poisson.Poisson(rate, validate_args=None)[源]#
Bases:
ExponentialFamily
使用率参数
rate
参数化的泊松分布。样本是非负整数,其概率质量函数 (pmf) 如下:
示例
>>> m = Poisson(torch.tensor([4])) >>> m.sample() tensor([ 3.])
- 参数
rate (数字, 张量) – 速率参数
- arg_constraints = {'rate': GreaterThanEq(lower_bound=0.0)}#
- support = IntegerGreaterThan(lower_bound=0)#
RelaxedBernoulli#
- 类 torch.distributions.relaxed_bernoulli.RelaxedBernoulli(temperature, probs=None, logits=None, validate_args=None)[源]#
Bases:
TransformedDistribution
创建一个 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, torch.distributions.constraints.Constraint] = {'logits': Real(), 'probs': Interval(lower_bound=0.0, upper_bound=1.0)}#
- base_dist: LogitRelaxedBernoulli#
- has_rsample = True#
- support = Interval(lower_bound=0.0, upper_bound=1.0)#
LogitRelaxedBernoulli#
- 类 torch.distributions.relaxed_bernoulli.LogitRelaxedBernoulli(temperature, probs=None, logits=None, validate_args=None)[源]#
Bases:
Distribution
使用
probs
或logits
(但不能同时使用)参数化的 LogitRelaxedBernoulli 分布,它是 RelaxedBernoulli 分布的对数几率。有关更多详细信息,请参阅 [1]。样本是 (0, 1) 范围内的值的对数几率。有关更多详细信息,请参阅 [1]。
[1] The Concrete Distribution: A Continuous Relaxation of Discrete Random Variables (Maddison et al., 2017)
[2] Categorical Reparametrization with Gumbel-Softmax (Jang et al., 2017)
- arg_constraints = {'logits': Real(), 'probs': Interval(lower_bound=0.0, upper_bound=1.0)}#
- support = Real()#
RelaxedOneHotCategorical#
- 类 torch.distributions.relaxed_categorical.RelaxedOneHotCategorical(temperature, probs=None, logits=None, validate_args=None)[源]#
Bases:
TransformedDistribution
创建一个 RelaxedOneHotCategorical 分布,由
temperature
参数化,以及probs
或logits
。这是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])
- arg_constraints: dict[str, torch.distributions.constraints.Constraint] = {'logits': IndependentConstraint(Real(), 1), 'probs': Simplex()}#
- base_dist: ExpRelaxedCategorical#
- has_rsample = True#
- support = Simplex()#
StudentT#
- 类 torch.distributions.studentT.StudentT(df, loc=0.0, scale=1.0, validate_args=None)[源]#
Bases:
Distribution
使用自由度
df
、均值loc
和尺度scale
参数化的 Student’s t 分布。示例
>>> m = StudentT(torch.tensor([2.0])) >>> m.sample() # Student's t-distributed with degrees of freedom=2 tensor([ 0.1046])
- arg_constraints = {'df': GreaterThan(lower_bound=0.0), 'loc': Real(), 'scale': GreaterThan(lower_bound=0.0)}#
- has_rsample = True#
- support = Real()#
TransformedDistribution#
- 类 torch.distributions.transformed_distribution.TransformedDistribution(base_distribution, transforms, validate_args=None)[源]#
Bases:
Distribution
Distribution 类的一个扩展,它将一系列变换应用于基本分布。令 f 为应用的变换的组合
X ~ BaseDistribution Y = f(X) ~ TransformedDistribution(BaseDistribution, f) log p(Y) = log p(X) + log |det (dX/dY)|
请注意,
TransformedDistribution
的.event_shape
是其基本分布和变换的最大形状,因为变换可能会引入事件之间的相关性。对
TransformedDistribution
用法的示例是# Building a Logistic Distribution # X ~ Uniform(0, 1) # f = a + b * logit(X) # Y ~ f(X) ~ Logistic(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
的实现。- arg_constraints: dict[str, torch.distributions.constraints.Constraint] = {}#
- rsample(sample_shape=torch.Size([]))[源]#
生成一个 sample_shape 大小的可重参数化样本,或者如果分布参数是批量的,则生成 sample_shape 大小的可重参数化样本批。首先从基本分布采样,然后为列表中的每个变换应用 transform()。
- 返回类型
- sample(sample_shape=torch.Size([]))[源]#
生成一个 sample_shape 大小的样本,或者如果分布参数是批量的,则生成 sample_shape 大小的样本批。首先从基本分布采样,然后为列表中的每个变换应用 transform()。
- 属性 support#
- 返回类型
_DependentProperty
Uniform#
- 类 torch.distributions.uniform.Uniform(low, high, validate_args=None)[源]#
Bases:
Distribution
在半开区间
[low, high)
中生成均匀分布的随机样本。示例
>>> m = Uniform(torch.tensor([0.0]), torch.tensor([5.0])) >>> m.sample() # uniformly distributed in the range [0.0, 5.0) tensor([ 2.3418])
- 属性 arg_constraints#
- has_rsample = True#
- 属性 support#
- 返回类型
_DependentProperty
VonMises#
- 类 torch.distributions.von_mises.VonMises(loc, concentration, validate_args=None)[源]#
Bases:
Distribution
一个圆 von Mises 分布。
此实现使用极坐标。
loc
和value
参数可以是任何实数(以便于无约束优化),但它们被解释为模 2 pi 的角度。- 示例:
>>> m = VonMises(torch.tensor([1.0]), torch.tensor([1.0])) >>> m.sample() # von Mises distributed with loc=1 and concentration=1 tensor([1.9777])
- 参数
loc (torch.Tensor) – 以弧度为单位的角度。
concentration (torch.Tensor) – 浓度参数
- arg_constraints = {'concentration': GreaterThan(lower_bound=0.0), 'loc': Real()}#
- has_rsample = False#
- sample(sample_shape=torch.Size([]))[源]#
von Mises 分布的采样算法基于以下论文:D.J. Best 和 N.I. Fisher,“Efficient simulation of the von Mises distribution。” Applied Statistics (1979): 152-157。
采样始终在内部以双精度进行,以避免在_rejection_sample()函数中因浓度值过小而导致的挂起,这种情况在单精度下大约是1e-4时就会发生(请参阅问题#88443)。
- support = Real()#
Weibull#
- class torch.distributions.weibull.Weibull(scale, concentration, validate_args=None)[source]#
Bases:
TransformedDistribution
从两参数威布尔分布中采样。
示例
>>> m = Weibull(torch.tensor([1.0]), torch.tensor([1.0])) >>> m.sample() # sample from a Weibull distribution with scale=1, concentration=1 tensor([ 0.4784])
- 参数
- arg_constraints: dict[str, torch.distributions.constraints.Constraint] = {'concentration': GreaterThan(lower_bound=0.0), 'scale': GreaterThan(lower_bound=0.0)}#
- support = GreaterThan(lower_bound=0.0)#
Wishart#
- class torch.distributions.wishart.Wishart(df, covariance_matrix=None, precision_matrix=None, scale_tril=None, validate_args=None)[source]#
Bases:
ExponentialFamily
创建一个由对称正定矩阵 或其乔列斯基分解 参数化的 Wishart 分布。
示例
>>> m = Wishart(torch.Tensor([2]), covariance_matrix=torch.eye(2)) >>> m.sample() # Wishart distributed with mean=`df * I` and >>> # variance(x_ij)=`df` for i != j and variance(x_ij)=`2 * df` for i == j
- 参数
注意
只能指定
covariance_matrix
、precision_matrix
或scale_tril
中的一个。使用scale_tril
会更有效:内部所有计算都基于scale_tril
。如果改用covariance_matrix
或precision_matrix
,则仅用于通过乔列斯基分解计算相应的下三角矩阵。‘torch.distributions.LKJCholesky’ 是一个受限的 Wishart 分布。[1]参考文献
[1] Wang, Z., Wu, Y. and Chu, H., 2018. On equivalence of the LKJ distribution and the restricted Wishart distribution. [2] Sawyer, S., 2007. Wishart Distributions and Inverse-Wishart Sampling. [3] Anderson, T. W., 2003. An Introduction to Multivariate Statistical Analysis (3rd ed.). [4] Odell, P. L. & Feiveson, A. H., 1966. A Numerical Procedure to Generate a SampleCovariance Matrix. JASA, 61(313):199-203. [5] Ku, Y.-C. & Bloomfield, P., 2010. Generating Random Wishart Matrices with Fractional Degrees of Freedom in OX.
- property arg_constraints#
- has_rsample = True#
- rsample(sample_shape=torch.Size([]), max_try_correction=None)[source]#
警告
在某些情况下,基于Bartlett分解的采样算法可能会返回奇异的矩阵样本。默认情况下会尝试几次来纠正奇异样本,但最终可能仍会返回奇异样本。奇异样本在 .log_prob() 中可能返回 -inf 值。在这种情况下,用户应验证样本,并相应地修复 df 的值或调整 .rsample 参数中的 max_try_correction 值。
- 返回类型
- support = PositiveDefinite()#
KL Divergence
#
- torch.distributions.kl.kl_divergence(p, q)[source]#
计算两个分布之间的 Kullback-Leibler 散度 。
- 参数
p (Distribution) – 一个
Distribution
对象。q (Distribution) – 一个
Distribution
对象。
- 返回
形状为 batch_shape 的 KL 散度批。
- 返回类型
- 引发
NotImplementedError – 如果分布类型尚未通过
register_kl()
注册。
- KL 散度目前为以下分布对实现:
Bernoulli
和Bernoulli
Bernoulli
和Poisson
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
和Gamma
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)[source]#
装饰器,用于将成对函数注册到
kl_divergence()
。用法@register_kl(Normal, Normal) def kl_normal_normal(p, q): # insert implementation here
查找返回最具体的 (类型,类型) 匹配,按子类排序。如果匹配不明确,则会引发 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) # Break the tie.
Transforms
#
- class torch.distributions.transforms.AffineTransform(loc, scale, event_dim=0, cache_size=0)[source]#
通过逐点仿射映射 进行变换。
- class torch.distributions.transforms.CatTransform(tseq, dim=0, lengths=None, cache_size=0)[source]#
变换函子,它以与
torch.cat()
兼容的方式,对 dim 维度上的每个子矩阵(长度为 lengths[dim])应用变换序列 tseq。示例
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)[source]#
将多个变换链式组合。被组合的变换负责缓存。
- class torch.distributions.transforms.CorrCholeskyTransform(cache_size=0)[source]#
将无约束实向量 (长度为 )转换为 D 维相关矩阵的乔列斯基因子。此乔列斯基因子是一个下三角矩阵,每行的对角线为正且欧几里得范数为单位。变换的处理方式如下:
首先,我们将 x 按行顺序转换为下三角矩阵。
对于下三角部分的每一行 ,我们应用
StickBreakingTransform
类的 *有符号* 版本来变换 到单位欧几里得长度向量,步骤如下: - 缩放到区间 域: . - 转换为无符号域: . - 应用 . - 转换回有符号域: .
- class torch.distributions.transforms.CumulativeDistributionTransform(distribution, cache_size=0)[source]#
通过概率分布的累积分布函数进行变换。
- 参数
distribution (Distribution) – 用于变换的累积分布函数所基于的分布。
示例
# Construct a Gaussian copula from a multivariate normal. 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)[source]#
另一个变换的包装器,用于将
reinterpreted_batch_ndims
个最右边的维度视为相关的。这不会影响正向或反向变换,但在log_abs_det_jacobian()
中会合并reinterpreted_batch_ndims
个最右边的维度。
- class torch.distributions.transforms.LowerCholeskyTransform(cache_size=0)[source]#
从无约束矩阵到对角线元素为非负的下三角矩阵的变换。
这对于用乔列斯基分解参数化正定矩阵很有用。
- class torch.distributions.transforms.PositiveDefiniteTransform(cache_size=0)[source]#
从无约束矩阵到正定矩阵的变换。
- class torch.distributions.transforms.ReshapeTransform(in_shape, out_shape, cache_size=0)[source]#
单位雅可比变换,用于重塑张量的最右边部分。
请注意,
in_shape
和out_shape
必须具有相同的元素数量,这与torch.Tensor.reshape()
相同。- 参数
in_shape (torch.Size) – 输入的事件形状。
out_shape (torch.Size) – 输出的事件形状。
cache_size (int) – 缓存大小。如果为零,则不进行缓存。如果为一,则缓存最新的单个值。仅支持 0 和 1。(默认 0。)
- class torch.distributions.transforms.SoftplusTransform(cache_size=0)[source]#
通过映射 进行变换。当 时,实现会退回到线性函数。
- class torch.distributions.transforms.TanhTransform(cache_size=0)[source]#
通过映射 进行变换。
它等价于
ComposeTransform( [ AffineTransform(0.0, 2.0), SigmoidTransform(), AffineTransform(-1.0, 2.0), ] )
然而,这可能在数值上不稳定,因此建议使用 TanhTransform 代替。
请注意,当遇到 值时,应使用 cache_size=1。
- class torch.distributions.transforms.SoftmaxTransform(cache_size=0)[source]#
通过 并随后进行归一化,将非约束空间变换到单纯形。
这不是双射变换,不能用于 HMC。然而,它主要在坐标系上操作(除了最后的归一化),因此适用于逐坐标优化算法。
- class torch.distributions.transforms.StackTransform(tseq, dim=0, cache_size=0)[source]#
变换函子,它以与
torch.stack()
兼容的方式,逐个分量地应用一系列变换 tseq 到每个子矩阵上,dim 为维度。示例
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)[source]#
通过“折断”过程将非约束空间变换到多一个维度的单纯形。
此变换是通过对 Dirichlet 分布的“折断”构造中的迭代 Sigmoid 变换产生的:第一个 logit 通过 sigmoid 变换为第一个概率以及剩余的概率,然后过程递归。
这是双射变换,适合用于 HMC;然而,它混合了坐标,不太适合优化。
- class torch.distributions.transforms.Transform(cache_size=0)[source]#
可逆变换的抽象类,其对数行列式雅可比行列式是可计算的。它们主要用于
torch.distributions.TransformedDistribution
。缓存对于那些逆变换计算成本高昂或数值不稳定的变换很有用。请注意,必须小心处理记忆值,因为自动微分图可能会被反转。例如,以下代码在有缓存或无缓存时都能正常工作
y = t(x) t.log_abs_det_jacobian(x, y).backward() # x will receive gradients.
然而,以下代码在缓存时会因依赖关系反转而报错
y = t(x) z = t.inv(y) grad(z.sum(), [y]) # error because z is x
派生类应实现
_call()
或_inverse()
中的一个或两个。将 bijective=True 设置为派生类还应实现log_abs_det_jacobian()
。- 参数
cache_size (int) – 缓存大小。如果为零,则不进行缓存。如果为一,则缓存最新的单个值。仅支持 0 和 1。
- 变量
domain (
Constraint
) – 表示此变换有效输入的约束。codomain (
Constraint
) – 表示此变换有效输出(作为逆变换的输入)的约束。bijective (bool) – 此变换是否为双射。当且仅当对于域中的每个
x
和共域中的y
,t.inv(t(x)) == x
且t(t.inv(y)) == y
时,变换t
才为双射。非双射变换至少应满足更弱的伪逆性质t(t.inv(t(x)) == t(x)
和t.inv(t(t.inv(y))) == t.inv(y)
。sign (int 或 Tensor) – 对于双射单变量变换,此值应为 +1 或 -1,取决于变换是单调递增还是递减。
Constraints
#
- class torch.distributions.constraints.Constraint[source]#
约束的抽象基类。
一个约束对象代表一个变量有效的区域,例如,变量可以在其中被优化。
- 变量
- torch.distributions.constraints.is_dependent(constraint)[source]#
检查
constraint
是否是_Dependent
对象。- 参数
constraint – 一个
Constraint
对象。- 返回
如果
constraint
可以被细化为_Dependent
类型,则返回 True,否则返回 False。- 返回类型
布尔值
示例
>>> import torch >>> from torch.distributions import Bernoulli >>> from torch.distributions.constraints import is_dependent
>>> dist = Bernoulli(probs=torch.tensor([0.6], requires_grad=True)) >>> constraint1 = dist.arg_constraints["probs"] >>> constraint2 = dist.arg_constraints["logits"]
>>> for constraint in [constraint1, constraint2]: >>> if is_dependent(constraint): >>> continue
Constraint Registry
#
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(HMC)很有用,其中来自具有有约束 .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 等算法是必需的。
biject_to
和 transform_to
对象可以通过用户定义的约束和变换来扩展,使用它们的 .register()
方法,可以是作为单例约束上的函数
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[source]#
链接约束到变换的注册表。
- register(constraint, factory=None)[source]#
在此注册表中注册一个
Constraint
子类。用法@my_registry.register(MyConstraintClass) def construct_transform(constraint): assert isinstance(constraint, MyConstraint) return MyTransform(constraint.arg_constraints)
- 参数
constraint (子类
Constraint
) –Constraint
的子类,或所需类的单例对象。factory (Callable) – 一个可调用对象,它接受一个约束对象作为输入并返回一个
Transform
对象。