プログラマー必見!PyTorch Probability DistributionsのCumulativeDistributionTransformを使いこなす


具体的な使い方

  1. base_distribution = torch.distributions.Normal(loc=0, scale=1)
    
  2. 変換したい確率分布の累積分布関数を作成します。

    target_cdf = torch.distributions.Beta(alpha=2, beta=3).cdf
    
  3. CumulativeDistributionTransform を使って、変換を作成します。

    transform = torch.distributions.transforms.CumulativeDistributionTransform(target_cdf)
    
  4. 変換を使って、ベース分布のサンプリング結果を変換します。

    samples = base_distribution.rsample(1000)
    transformed_samples = transform(samples)
    

詳細

CumulativeDistributionTransform は、以下の操作を実行します。

  1. ベース分布からランダムサンプリングします。
  2. サンプリング結果を、変換したい確率分布の累積分布関数に渡します。
  3. 累積分布関数の出力値を、変換後の値として返します。

この変換は、以下のような場合に役立ちます。

  • 確率分布の形状を変えたい場合。
  • ある確率分布のサンプリング結果を、別の確率分布の範囲にマッピングしたい場合。

注意点

  • target_cdf の逆関数は、計算可能である必要があります。
  • target_cdf は、単調増加関数である必要があります。
import torch
from torch.distributions import *

base_distribution = Normal(loc=0, scale=1)
target_cdf = Beta(alpha=2, beta=3).cdf
transform = CumulativeDistributionTransform(target_cdf)

samples = base_distribution.rsample(1000)
transformed_samples = transform(samples)

print(transformed_samples)

torch.distributions.transforms.CumulativeDistributionTransform は、確率分布のサンプリング結果を変換するための便利なツールです。確率分布の形状を変えたり、サンプリング結果を別の分布の範囲にマッピングしたりする際に役立ちます。



import torch
from torch.distributions import *

# ベースとなる確率分布を定義
base_distribution = Normal(loc=0, scale=1)

# 変換したい確率分布の累積分布関数を作成
target_cdf = Beta(alpha=2, beta=3).cdf

# CumulativeDistributionTransform を使って、変換を作成
transform = CumulativeDistributionTransform(target_cdf)

# サンプル数を指定
num_samples = 1000

# ベース分布からランダムサンプリング
samples = base_distribution.rsample(num_samples)

# 変換を使って、サンプリング結果を変換
transformed_samples = transform(samples)

# 結果を出力
print(transformed_samples)

このコードを実行すると、以下のような出力が出力されます。

tensor([0.0332, 0.0472, 0.0741,  ..., 0.9589, 0.9663, 0.9802])

この出力は、base_distribution からサンプリングされた値が target_cdf によって変換された結果を表しています。

以下は、CumulativeDistributionTransform を使用して、確率分布の形状を変える例です。

import torch
from torch.distributions import *

# ベースとなる確率分布を定義
base_distribution = Uniform(low=0, high=1)

# 逆正弦関数の累積分布関数を作成
target_cdf = torch.sin

# CumulativeDistributionTransform を使って、変換を作成
transform = CumulativeDistributionTransform(target_cdf)

# サンプル数を指定
num_samples = 1000

# ベース分布からランダムサンプリング
samples = base_distribution.rsample(num_samples)

# 変換を使って、サンプリング結果を変換
transformed_samples = transform(samples)

# 結果を出力
print(transformed_samples)
tensor([-0.8415, -0.5448, -0.2475,  ..., 0.7568, 0.9063, 0.9961])


torch.distributions.TransformedDistribution

torch.distributions.TransformedDistribution は、確率分布とその変換を組み合わせて、新しい確率分布を作成するためのクラスです。CumulativeDistributionTransform を直接使用するよりも、コードが簡潔になる場合があり、特に変換が単純な場合に役立ちます。

import torch
from torch.distributions import *

base_distribution = Normal(loc=0, scale=1)
target_cdf = Beta(alpha=2, beta=3).cdf
transformed_distribution = TransformedDistribution(base_distribution, transform=CumulativeDistributionTransform(target_cdf))

samples = transformed_distribution.rsample(1000)
print(samples)

CumulativeDistributionTransform の内部動作を理解している場合は、手動で変換を適用することもできます。

import torch
from torch.distributions import *

base_distribution = Normal(loc=0, scale=1)
target_cdf = Beta(alpha=2, beta=3).cdf

samples = base_distribution.rsample(1000)
transformed_samples = target_cdf(samples)
print(transformed_samples)

PyTorch Probability Distributions には、CumulativeDistributionTransform 以外にも、様々な変換クラスが用意されています。状況に応じて、適切な変換クラスを選択することが重要です。

  • LogTransform: 対数変換を行うための変換クラス
  • PowerTransform: べき乗変換を行うための変換クラス
  • AffineTransform: 線形変換を行うための変換クラス
  • 複雑な変換を行う場合は、手動で実装するよりも、TransformedDistribution を使用する方が効率的な場合があります。
  • 変換の選択は、具体的な状況によって異なります。