機率分佈 - torch.distributions¶
`distributions` 包包含可引數化的機率分佈和取樣函式。這允許構建用於最佳化的隨機計算圖和隨機梯度估計器。此包的設計通常遵循 TensorFlow Distributions 包。
無法直接透過隨機樣本進行反向傳播。然而,有兩種主要方法可以建立可進行反向傳播的替代函式。它們是得分函式估計器/似然比估計器/REINFORCE 和路徑導數估計器。REINFORCE 通常被視為強化學習中策略梯度方法的基礎,而路徑導數估計器常見於變分自編碼器中的重引數化技巧。得分函式僅需要樣本 的值,而路徑導數需要導數 。接下來的部分將在一個強化學習示例中討論這兩種方法。更多詳情請參閱 Gradient Estimation Using Stochastic Computation Graphs 。
得分函式¶
當機率密度函式對其引數可微時,我們只需要 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()
路徑導數¶
實現這些隨機/策略梯度的另一種方法是使用 rsample() 方法中的重引數化技巧,其中引數化隨機變數可以透過一個無引數隨機變數的引數化確定性函式構建。因此,重引數化樣本變得可微。實現路徑導數的程式碼如下:
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()
分佈¶
- class torch.distributions.distribution.Distribution(batch_shape=torch.Size([]), event_shape=torch.Size([]), validate_args=None)[source][source]¶
基類:
object`Distribution` 是機率分佈的抽象基類。
- property arg_constraints: dict[str, torch.distributions.constraints.Constraint]¶
返回一個字典,將引數名對映到每個分佈引數應滿足的
Constraint物件。非 Tensor 引數不必出現在此字典中。
- enumerate_support(expand=True)[source][source]¶
返回包含離散分佈支援的所有值的 Tensor。結果將沿維度 0 進行列舉,因此結果的形狀將是 (cardinality,) + batch_shape + event_shape (其中對於單變數分佈,event_shape = ())。
請注意,這會同步列舉所有批次 Tensor,例如 [[0, 0], [1, 1], …]。當 expand=False 時,列舉沿維度 0 進行,但其餘批次維度是單例維度,例如 [[0], [1], ...
要遍歷完整的笛卡爾積,請使用 itertools.product(m.enumerate_support())。
- expand(batch_shape, _instance=None)[source][source]¶
返回一個新分佈例項(或填充由派生類提供的現有例項),其批次維度已展開到 batch_shape。此方法會呼叫分佈引數的
expand方法。因此,這不會為展開的分佈例項分配新的記憶體。此外,當首次建立例項時,它不會重複 __init__.py 中的任何引數檢查或引數廣播。- 引數
batch_shape (torch.Size) – 期望的展開大小。
_instance – 需要覆蓋 .expand 的子類提供的新例項。
- 返回
批次維度已展開到 batch_size 的新分佈例項。
- rsample(sample_shape=torch.Size([]))[source][source]¶
生成形狀為 sample_shape 的重引數化樣本,如果分佈引數是批次的,則生成形狀為 sample_shape 的批次重引數化樣本。
- 返回型別
- sample(sample_shape=torch.Size([]))[source][source]¶
生成形狀為 sample_shape 的樣本,如果分佈引數是批次的,則生成形狀為 sample_shape 的批次樣本。
- 返回型別
- static set_default_validate_args(value)[source][source]¶
設定是否啟用或停用驗證。
預設行為模仿 Python 的
assert語句:預設開啟驗證,但在以最佳化模式執行 Python (透過python -O) 時停用。驗證可能很耗時,因此您可能希望在模型正常工作後將其停用。- 引數
value (bool) – 是否啟用驗證。
- property support: Optional[Constraint]¶
返回表示此分佈支援範圍的
Constraint物件。
指數族¶
- class torch.distributions.exp_family.ExponentialFamily(batch_shape=torch.Size([]), event_shape=torch.Size([]), validate_args=None)[source][source]¶
基類:
Distribution`ExponentialFamily` 是屬於指數族的機率分佈的抽象基類,其機率質量/密度函式形式如下:
其中 表示自然引數, 表示充分統計量, 是給定族類的對數歸一化函式,且 是載波測度。
注意
此類是 Distribution 類和屬於指數族類的分佈之間的中介,主要用於檢查 .entropy() 和解析 KL 散度方法的正確性。我們使用此類透過 AD 框架和 Bregman 散度(引用:Frank Nielsen 和 Richard Nock 的著作《Entropies and Cross-entropies of Exponential Families》)計算熵和 KL 散度。
伯努利分佈¶
- class torch.distributions.bernoulli.Bernoulli(probs=None, logits=None, validate_args=None)[source][source]¶
繼承自:
ExponentialFamily建立一個伯努利分佈,由
probs或logits引數化(但不能同時使用兩者)。樣本是二進位制的(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][source]¶
繼承自:
ExponentialFamilyBeta 分佈由
concentration1和concentration0引數化。示例
>>> 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)¶
二項分佈¶
- class torch.distributions.binomial.Binomial(total_count=1, probs=None, logits=None, validate_args=None)[source][source]¶
基類:
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¶
- 返回型別
_依賴屬性
範疇分佈¶
- class torch.distributions.categorical.Categorical(probs=None, logits=None, validate_args=None)[source][source]¶
基類:
Distribution建立一個範疇分佈,由
probs或logits引數化(但不能同時使用兩者)。注意
它等同於
torch.multinomial()取樣所依據的分佈。樣本是來自 的整數,其中 K 是
probs.size(-1)。如果 probs 是長度為 K 的 1 維張量,則每個元素表示取樣到該索引對應類別的相對機率。
如果 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¶
- 屬性 support¶
- 返回型別
_依賴屬性
柯西分佈¶
- 類 torch.distributions.cauchy.Cauchy(loc, scale, validate_args=None)[source][source]¶
基類:
Distribution從柯西(Lorentz)分佈中進行取樣。均值為 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()¶
卡方分佈¶
- 類 torch.distributions.chi2.Chi2(df, validate_args=None)[source][source]¶
基類:
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)}¶
連續伯努利分佈¶
- 類 torch.distributions.continuous_bernoulli.ContinuousBernoulli(probs=None, logits=None, lims=(0.499, 0.501), validate_args=None)[source][source]¶
繼承自:
ExponentialFamily建立一個由
probs或logits引數化的連續伯努利分佈(但不能同時指定兩者)。該分佈支援在 [0, 1] 範圍內,並由“probs”(在 (0,1) 範圍內)或“logits”(實數值)引數化。請注意,與伯努利分佈不同,“probs”不對應於機率,“logits”也不對應於對數機率,但由於與伯努利分佈的相似性而使用了相同的名稱。更多詳情請參閱 [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 分佈¶
- 類 torch.distributions.dirichlet.Dirichlet(concentration, validate_args=None)[source][source]¶
繼承自:
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) – 分佈的集中度引數(通常稱為 alpha)
- arg_constraints = {'concentration': IndependentConstraint(GreaterThan(lower_bound=0.0), 1)}¶
- has_rsample = True¶
- support = Simplex()¶
指數分佈¶
- class torch.distributions.exponential.Exponential(rate, validate_args=None)[source][source]¶
繼承自:
ExponentialFamily建立一個由
rate引數化的指數分佈。示例
>>> 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)[source][source]¶
基類:
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)[source][source]¶
繼承自:
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)¶
Geometric¶
- class torch.distributions.geometric.Geometric(probs=None, logits=None, validate_args=None)[source][source]¶
基類:
Distribution建立一個由
probs引數化的 Geometric 分佈,其中probs是伯努利試驗的成功機率。注意
torch.distributions.geometric.Geometric()取樣第 次試驗是第一次成功的情況,因此取樣範圍是 ,而torch.Tensor.geometric_()取樣第 k 次試驗是第一次成功的情況,因此取樣範圍是 。示例
>>> 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)[source][source]¶
-
從 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()¶
-
arg_constraints:
HalfCauchy¶
- class torch.distributions.half_cauchy.HalfCauchy(scale, validate_args=None)[source][source]¶
-
建立一個由 scale 引數化的半柯西分佈,其中
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)[source][source]¶
-
建立一個半正態分佈,其引數為 scale,其中
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)[source][source]¶
基類:
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])]
- 引數
base_distribution (torch.distributions.distribution.Distribution) – 一個基礎分佈
reinterpreted_batch_ndims (整型) – 要重新解釋為事件維度的批次維度數量
- arg_constraints: dict[str, torch.distributions.constraints.Constraint] = {}¶
- property support¶
- 返回型別
_依賴屬性
InverseGamma¶
- class torch.distributions.inverse_gamma.InverseGamma(concentration, rate, validate_args=None)[source][source]¶
-
建立一個逆伽馬分佈,其引數為
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])
- 引數
- 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)¶
Kumaraswamy¶
- class torch.distributions.kumaraswamy.Kumaraswamy(concentration1, concentration0, validate_args=None)[source][source]¶
-
從 Kumaraswamy 分佈中取樣。
示例
>>> 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)[source][source]¶
基類:
Distribution相關矩陣的下喬利斯基因子的 LKJ 分佈。該分佈由
concentration引數 控制,使得由喬利斯基因子生成的相關矩陣 的機率與 成正比。因此,當concentration == 1時,我們在相關矩陣的喬利斯基因子上得到一個均勻分佈。L ~ LKJCholesky(dim, concentration) X = L @ L' ~ LKJCorr(dim, concentration)
請注意,此分佈取樣的是相關矩陣的喬利斯基因子,而不是相關矩陣本身,因此與 [1] 中 LKJCorr 分佈的推導略有不同。對於取樣,它使用了 [1] 中第 3 節的洋蔥方法 (Onion method)。
示例
>>> 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] 基於 vines 和擴充套件洋蔥方法生成隨機相關矩陣 (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)[source][source]¶
基類:
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)[source][source]¶
-
建立一個對數正態分佈,由
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)[source][source]¶
基類:
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])
- 引數
注意
由於 Woodbury 矩陣恆等式 和 矩陣行列式引理,當 cov_factor.shape[1] << cov_factor.shape[0] 時,可以避免計算協方差矩陣的行列式和逆。由於這些公式,我們只需要計算小尺寸“電容”矩陣的行列式和逆。
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)[source][source]¶
基類:
DistributionMixtureSameFamily 分佈實現了(批次)混合分佈,其中所有分量來自同一分佈型別的不同引數化。它由一個 Categorical “選擇分佈”(關於 k 個分量)和一個分量分佈引數化,即一個 Distribution,其最右邊的批次形狀(等於 [k])索引每個(批次的)分量。
示例
>>> # 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 或與 component_distribution.batch_shape[:-1] 匹配的 batch_shape
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¶
- 返回型別
_依賴屬性
多項分佈¶
- class torch.distributions.multinomial.Multinomial(total_count=1, probs=None, logits=None, validate_args=None)[source][source]¶
基類:
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': 獨立約束(實數(), 1), 'probs': 單純形()}¶
- property support¶
- 返回型別
_依賴屬性
多元正態分佈¶
- 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() # 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': 正定(), 'loc': 獨立約束(實數(), 1), 'precision_matrix': 正定(), 'scale_tril': LowerCholesky()}¶
- has_rsample = True¶
- support = 獨立約束(實數(), 1)¶
負二項分佈¶
- class torch.distributions.negative_binomial.NegativeBinomial(total_count, probs=None, logits=None, validate_args=None)[原始碼][原始碼]¶
基類:
Distribution建立一個負二項分佈,即在達到
total_count次失敗之前成功的獨立同分布 Bernoulli 試驗次數的分佈。每次 Bernoulli 試驗成功的機率為probs。- 引數
- arg_constraints = {'logits': 實數(), 'probs': 半開區間(下界=0.0, 上界=1.0), 'total_count': 大於等於(下界=0)}¶
- support = 大於0的整數(下界=0)¶
正態分佈¶
- class torch.distributions.normal.Normal(loc, scale, validate_args=None)[原始碼][原始碼]¶
繼承自:
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': 實數(), 'scale': 大於(下界=0.0)}¶
- has_rsample = True¶
- support = Real()¶
獨熱分類分佈 (OneHotCategorical)¶
- 類 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() # 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)[原始碼][原始碼]¶
-
從帕累託第一型分佈取樣。
示例
>>> 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¶
- 返回型別
_依賴屬性
泊松分佈 (Poisson)¶
- 類 torch.distributions.poisson.Poisson(rate, validate_args=None)[原始碼][原始碼]¶
繼承自:
ExponentialFamily建立一個泊松分佈,其引數為速率引數
rate。樣本是非負整數,其機率質量函式 (pmf) 如下所示:
示例
>>> m = Poisson(torch.tensor([4])) >>> m.sample() tensor([ 3.])
- 引數
rate (數值, Tensor) – 速率引數
- 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)[原始碼][原始碼]¶
-
建立一個鬆弛伯努利分佈,其引數為
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)}¶
- has_rsample = True¶
- support = Interval(lower_bound=0.0, upper_bound=1.0)¶
Logit鬆弛伯努利分佈 (LogitRelaxedBernoulli)¶
- 類 torch.distributions.relaxed_bernoulli.LogitRelaxedBernoulli(temperature, probs=None, logits=None, validate_args=None)[原始碼][原始碼]¶
基類:
Distribution建立一個 Logit 鬆弛伯努利分佈,其引數由
probs或logits(二者不同時提供) 指定,它是鬆弛伯努利分佈的 logit。樣本是 (0, 1) 範圍內值的 logit。更多詳細資訊請參見 [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)¶
- class torch.distributions.relaxed_categorical.RelaxedOneHotCategorical(temperature, probs=None, logits=None, validate_args=None)[source][source]¶
-
建立一個 RelaxedOneHotCategorical 分佈,由
temperature引數化,並使用probs或logits。這是OneHotCategorical分佈的鬆弛版本,因此其樣本在 simplex 上,並且可重新引數化。示例
>>> 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()}¶
- has_rsample = True¶
- support =Simplex()¶
學生 t 分佈 (StudentT)¶
- class torch.distributions.studentT.StudentT(df, loc=0.0, scale=1.0, validate_args=None)[source][source]¶
基類:
Distribution建立一個 Student's t 分佈,由自由度
df、均值loc和尺度scale引數化。示例
>>> 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)¶
- class torch.distributions.transformed_distribution.TransformedDistribution(base_distribution, transforms, validate_args=None)[source][source]¶
基類:
DistributionDistribution 類別的擴充套件,它對基礎分佈應用一系列 Transform。令 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([]))[source][source]¶
如果分佈引數是批次化的,則生成一個 sample_shape 形狀的可重新引數化樣本或 sample_shape 形狀的可重新引數化樣本批次。首先從基礎分佈中取樣,然後對列表中的每個變換應用 transform()。
- 返回型別
- sample(sample_shape=torch.Size([]))[source][source]¶
如果分佈引數是批次化的,則生成一個 sample_shape 形狀的樣本或 sample_shape 形狀的樣本批次。首先從基礎分佈中取樣,然後對列表中的每個變換應用 transform()。
- property support¶
- 返回型別
_依賴屬性
均勻分佈 (Uniform)¶
- class torch.distributions.uniform.Uniform(low, high, validate_args=None)[source][source]¶
基類:
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 = {'high': Dependent(), 'low': Dependent()}¶
- has_rsample = True¶
- property support¶
- 返回型別
_依賴屬性
馮·米塞斯分佈 (VonMises)¶
- class torch.distributions.von_mises.VonMises(loc, concentration, validate_args=None)[source][source]¶
基類:
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([]))[source][source]¶
von Mises 分佈的取樣演算法基於以下論文:D.J. Best and N.I. Fisher, “Efficient simulation of the von Mises distribution.” Applied Statistics (1979): 152-157。
取樣內部始終使用雙精度進行,以避免在 concentration 值較小時導致 _rejection_sample() 卡死,這種情況在單精度下大約 1e-4 時開始發生(參見 issue #88443)。
- support = Real()¶
威布林分佈 (Weibull)¶
- class torch.distributions.weibull.Weibull(scale, concentration, validate_args=None)[source][source]¶
-
從兩引數 Weibull 分佈中取樣。
示例
>>> 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][source]¶
繼承自:
ExponentialFamily建立 Wishart 分佈,該分佈由對稱正定矩陣 或其 Cholesky 分解 引數化
示例
>>> 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,則僅用於透過 Cholesky 分解計算相應的下三角矩陣。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.
- arg_constraints = {'covariance_matrix': PositiveDefinite(), 'df': GreaterThan(lower_bound=0), 'precision_matrix': PositiveDefinite(), 'scale_tril': LowerCholesky()}¶
- has_rsample = True¶
- rsample(sample_shape=torch.Size([]), max_try_correction=None)[source][source]¶
警告
在某些情況下,基於 Bartlett 分解的取樣演算法可能會返回奇異矩陣樣本。預設情況下會嘗試幾次校正奇異樣本,但最終仍可能返回奇異矩陣樣本。奇異樣本在 .log_prob() 中可能會返回 -inf 值。在這些情況下,使用者應該驗證樣本,並修復 df 的值或相應調整 .rsample 中引數 max_try_correction 的值。
- 返回型別
- support = PositiveDefinite()¶
KL 散度¶
- torch.distributions.kl.kl_divergence(p, q)[source][source]¶
計算兩個分佈之間的 Kullback-Leibler 散度 。
- 引數
p (Distribution) – 一個
Distribution物件。q (Distribution) – 一個
Distribution物件。
- 返回
一個形狀為 batch_shape 的 KL 散度批次。
- 返回型別
- 引發
NotImplementedError – 如果分發型別尚未透過
register_kl()註冊。
- KL 散度目前已為以下分佈對實現
Bernoulli和BernoulliBernoulli和PoissonBeta和BetaBeta和ContinuousBernoulliBeta和ExponentialBeta和GammaBeta和NormalBeta和ParetoBeta和UniformBinomial和BinomialCategorical和CategoricalCauchy和CauchyContinuousBernoulli和ContinuousBernoulliContinuousBernoulli和ExponentialContinuousBernoulli和NormalContinuousBernoulli和ParetoContinuousBernoulli和UniformDirichlet和DirichletExponential和BetaExponential和ContinuousBernoulliExponential和ExponentialExponential和GammaExponential和GumbelExponential和NormalExponential和ParetoExponential和UniformExponentialFamily和ExponentialFamilyGamma和BetaGamma和ContinuousBernoulliGamma和ExponentialGamma和GammaGamma和GumbelGamma和NormalGamma和ParetoGamma和UniformGeometric和GeometricGumbel和BetaGumbel和ContinuousBernoulliGumbel和ExponentialGumbel和GammaGumbel和GumbelGumbel和NormalGumbel和ParetoGumbel和UniformHalfNormal和HalfNormalIndependent和IndependentLaplace和BetaLaplace和ContinuousBernoulliLaplace和ExponentialLaplace和GammaLaplace和LaplaceLaplace和NormalLaplace和ParetoLaplace和UniformLowRankMultivariateNormal和LowRankMultivariateNormalLowRankMultivariateNormal和MultivariateNormalMultivariateNormal和LowRankMultivariateNormalMultivariateNormal和MultivariateNormalNormal和BetaNormal和ContinuousBernoulliNormal和ExponentialNormal和GammaNormal和GumbelNormal和LaplaceNormal和NormalNormal和ParetoNormal和UniformOneHotCategorical和OneHotCategoricalPareto和BetaPareto和ContinuousBernoulliPareto和ExponentialPareto和GammaPareto和NormalPareto和ParetoPareto和UniformPoisson和BernoulliPoisson和BinomialPoisson和PoissonTransformedDistribution和TransformedDistributionUniform和BetaUniform和ContinuousBernoulliUniform和ExponentialUniform和GammaUniform和GumbelUniform和NormalUniform和ParetoUniform和Uniform
- torch.distributions.kl.register_kl(type_p, type_q)[source][source]¶
用於註冊一個對偶函式的裝飾器,與
kl_divergence()。用法@register_kl(Normal, Normal) def kl_normal_normal(p, q): # insert implementation here
查詢返回按子類排序的最具體的 (type,type) 匹配。如果匹配不明確,則會引發 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][source]¶
透過逐點仿射對映 進行變換。
- class torch.distributions.transforms.CatTransform(tseq, dim=0, lengths=None, cache_size=0)[source][source]¶
變換函式子,將一系列變換 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)[source][source]¶
將多個變換組合成一個鏈。被組合的變換負責快取。
- class torch.distributions.transforms.CorrCholeskyTransform(cache_size=0)[source][source]¶
將無約束實向量 ,長度為 ,變換為 D 維相關矩陣的 Cholesky 因子。此 Cholesky 因子是一個下三角矩陣,其對角線元素為正,且每行的歐幾里得範數為一。變換過程如下
首先,我們將 x 按行順序轉換為一個下三角矩陣。
對於下三角部分的每一行 ,我們應用類
StickBreakingTransform的 *有符號* 版本,透過以下步驟將 變換為單位歐幾里得範數向量: - 縮放到區間 域:。 - 變換到無符號域:。 - 應用 。 - 變換回有符號域:。
- class torch.distributions.transforms.CumulativeDistributionTransform(distribution, cache_size=0)[source][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][source]¶
另一個變換的包裝器,將最右邊的額外
reinterpreted_batch_ndims個維度視為相關的。這不會影響前向或後向變換,但會在log_abs_det_jacobian()中對最右邊的額外reinterpreted_batch_ndims個維度求和。
- class torch.distributions.transforms.LowerCholeskyTransform(cache_size=0)[source][source]¶
將無約束矩陣變換為具有非負對角線元素的下三角矩陣。
這對於透過 Cholesky 分解來引數化正定矩陣非常有用。
- class torch.distributions.transforms.PositiveDefiniteTransform(cache_size=0)[source][source]¶
將無約束矩陣變換為正定矩陣。
- class torch.distributions.transforms.PowerTransform(exponent, cache_size=0)[source][source]¶
透過對映 進行變換。
- class torch.distributions.transforms.ReshapeTransform(in_shape, out_shape, cache_size=0)[source][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][source]¶
透過以下對映進行變換 。當 時,實現會回退到線性函式。
- class torch.distributions.transforms.TanhTransform(cache_size=0)[source][source]¶
透過以下對映進行變換 。
它等價於
ComposeTransform( [ AffineTransform(0.0, 2.0), SigmoidTransform(), AffineTransform(-1.0, 2.0), ] )
然而這可能在數值上不穩定,因此建議使用 TanhTransform 代替。
注意,在涉及 NaN/Inf 值時,應使用 cache_size=1。
- class torch.distributions.transforms.SoftmaxTransform(cache_size=0)[source][source]¶
透過 然後歸一化,從無約束空間變換到單純形。
這不是雙射的,不能用於 HMC。然而,這主要按座標操作(最終歸一化除外),因此適用於按座標進行的最佳化演算法。
- class torch.distributions.transforms.StackTransform(tseq, dim=0, cache_size=0)[source][source]¶
變換函式(functor),它以與
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][source]¶
透過分段(stick-breaking)過程,從無約束空間變換到維度增加一的單純形。
此變換在 Dirichlet 分佈的分段構建中作為迭代 sigmoid 變換出現:第一個 logit 透過 sigmoid 變換為第一個機率以及其餘部分的機率,然後該過程遞迴進行。
這是雙射的,適用於 HMC;但它將座標混合在一起,不太適用於最佳化。
- class torch.distributions.transforms.Transform(cache_size=0)[source][source]¶
具有可計算的 log det jacobians 的可逆變換的抽象類。它們主要用於
torch.distributions.TransformedDistribution。對於逆變換計算成本高或數值不穩定的變換,快取非常有用。注意,使用記憶值(memoized values)時必須小心,因為 autograd 計算圖可能會被反轉。例如,以下程式碼無論是否使用快取都可以工作
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滿足t.inv(t(x)) == x且t(t.inv(y)) == y時,它是雙射的。非雙射變換至少應保持較弱的偽逆性質t(t.inv(t(x)) == t(x)和t.inv(t(t.inv(y))) == t.inv(y)。
Constraints¶
- class torch.distributions.constraints.Constraint[source][source]¶
約束的抽象基類。
約束物件表示變數有效的區域,例如變數可在其中進行最佳化的區域。
- 變數
- is_dependent(constraint)[source][source]¶
檢查
constraint是否為_Dependent物件。- 引數
constraint – 一個
Constraint物件。- 返回
如果
constraint可以被精煉為_Dependent型別,則為 True,否則為 False。- 返回型別
bool
示例
>>> 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)查詢一個從constraints.real到給定constraint的不一定是雙射的Transform。返回的變換不保證實現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 這樣的演算法是必需的。
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][source]¶
用於連結約束和變換的登錄檔。
- register(constraint, factory=None)[source][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物件。