PyTorch Probability DistributionsにおけるTransform.inverse_shape():詳細解説とサンプルコード


この関数の動作を理解するために、以下の例を説明します。


  1. 正規分布 N(0, 1) を作成します。
  2. 平方根変換 Sqrt() を適用します。
  3. 出力形状を確認します。
  4. inverse_shape() を使用して元の形状に戻します。
import torch
import torch.distributions as distributions

# 正規分布を作成
distribution = distributions.Normal(0, 1)

# 平方根変換を適用
transform = distributions.transforms.Sqrt()
transformed_distribution = distribution.transform(transform)

# 出力形状を確認
print(transformed_distribution.sample(10).shape)  # torch.Size([10, 1])

# inverse_shape() を使用して元の形状に戻す
inverse_shape = transform.inverse_shape()
original_shape = inverse_shape(torch.Size([10, 1]))
print(original_shape)  # torch.Size([10])

この例では、正規分布 N(0, 1) に平方根変換を適用すると、出力形状が [10, 1] になります。これは、変換によって各サンプルが単一の値に変換されたことを意味します。

inverse_shape() を使用して元の形状に戻すと、[10] という元の形状が得られます。これは、変換を元に戻して元の形状に戻したことを意味します。

inverse_shape() は、Transform クラスのメソッドです。このメソッドは、変換層の入力形状を受け取り、出力形状を元の形状に戻すための形状を返します。

inverse_shape() の引数は以下の通りです。

  • shape: 変換層の入力形状を表す torch.Size オブジェクト

inverse_shape() の戻り値は以下の通りです。

  • 変換層の出力形状を表す torch.Size オブジェクト

torch.distributions.transforms.Transform.inverse_shape() は、確率分布の変換における出力形状を元の形状に戻すための関数です。この関数は、確率分布の変換層で形状が変更された場合に、元の形状に戻すために使用されます。



  1. 2つの変換を組み合わせた変換層を作成します。
  2. 各変換層の出力形状を確認します。
  3. inverse_shape() を使用して元の形状に戻します。
import torch
import torch.distributions as distributions

# 2つの変換を作成
transform1 = distributions.transforms.AffineTransform(loc=1, scale=2)
transform2 = distributions.transforms.ExpTransform()

# 2つの変換を組み合わせた変換層を作成
combined_transform = transform1.Compose(transform2)

# 正規分布を作成
distribution = distributions.Normal(0, 1)

# 変換層を適用
transformed_distribution = distribution.transform(combined_transform)

# 各変換層の出力形状を確認
print(transform1(torch.Size([10, 1])).shape)  # torch.Size([10, 1])
print(transform2(torch.Size([10, 1])).shape)  # torch.Size([10, 1])

# inverse_shape() を使用して元の形状に戻す
inverse_shape = combined_transform.inverse_shape()
original_shape = inverse_shape(torch.Size([10, 1]))
print(original_shape)  # torch.Size([10])

この例では、2つの変換 transform1transform2 を組み合わせて combined_transform という変換層を作成します。

  • transform2 は、各サンプルの指数をとります。
  • transform1 は、各サンプルに 1 を加え、2 倍します。


以下に、inverse_shape() の代替方法をいくつか紹介します。

手動計算

変換層が単純な場合、inverse_shape() を手動で計算することができます。例えば、線形変換の場合、以下の式を使用して逆変換の形状を計算できます。

def inverse_shape(shape, scale, loc):
    # 線形変換の逆変換の形状を計算
    new_shape = [shape[i] for i in range(len(shape))]
    for i, s in enumerate(shape):
        if scale[i] != 1:
            new_shape[i] = s // scale[i]
    return torch.Size(new_shape)

torch.distributions.InverseTransform を使用する

torch.distributions.InverseTransform クラスは、確率分布の変換を逆変換するためのクラスです。このクラスには、inverse_shape() メソッドがあり、変換層の出力形状を元の形状に戻すことができます。

import torch
import torch.distributions as distributions

# 2つの変換を作成
transform1 = distributions.transforms.AffineTransform(loc=1, scale=2)
transform2 = distributions.transforms.ExpTransform()

# 2つの変換を組み合わせた変換層を作成
combined_transform = transform1.Compose(transform2)

# 正規分布を作成
distribution = distributions.Normal(0, 1)

# 変換層を適用
transformed_distribution = distribution.transform(combined_transform)

# InverseTransform を使用して元の形状に戻す
inverse_transform = distributions.InverseTransform(combined_transform)
original_shape = inverse_transform.inverse_shape(torch.Size([10, 1]))
print(original_shape)  # torch.Size([10])

カスタム変換層を作成する

変換層が複雑な場合、inverse_shape() を手動で計算したり、InverseTransform クラスを使用したりするのは難しい場合があります。このような場合は、カスタム変換層を作成することができます。

カスタム変換層を作成するには、torch.distributions.transforms.Transform クラスを継承する必要があります。このクラスには、forward()inverse() という 2 つのメソッドを実装する必要があります。

  • inverse() メソッドは、出力形状を受け取り、入力形状を返す必要があります。
  • forward() メソッドは、入力形状を受け取り、出力形状を返す必要があります。

カスタム変換層を作成すると、inverse_shape() メソッドを自由に実装することができます。

torch.distributions.transforms.Transform.inverse_shape() は、確率分布の変換における出力形状を元の形状に戻すための便利な関数です。しかし、状況によっては、この関数よりも効率的な代替方法を使用できる場合があります。