torch.distributions의 대량 크기

16348 단어 PyTorch
심층 강화 학습 방법과 생성 모델 제작을 통해 오차 역전파의 샘플링을 하고 싶습니다.
torch.distributions .Distribution은 오차 역전파를 할 수 있는 샘플링, sample은 일반적인 샘플링, rsample는 오차 역전파를 할 수 있는 샘플링 방법이다.
torch.distributions는 샘플을 채취할 때 사이즈를 지정하기 때문에 입력한 대량 크기와 출력한 대량 크기가 현저히 다르다.distributions의 Distribution 클래스 출력의 대량 크기를 확인합니다.
import torch
import matplotlib.pyplot as plt
다음 예에서 분할 크기는 모두 3이고 각 확률 변수의 비트는 2이다.VAE(변분 자동 인코더)에서는 분할 크기마다 평균과 분산을 준비하고 샘플링마다 하나씩 진행한다. 그 결과 전체 샘플의 사이즈는 분할 사이즈와 같다.
one_mean1 = torch.tensor([1,1]).float()
one_mean2 = torch.tensor([2,2]).float()
one_mean3 = torch.tensor([3,3]).float()

mean = torch.stack([one_mean1, one_mean2, one_mean3], dim=0)
print("maen:",mean)

one_var1 = torch.tensor([0.1, 0.1]).float()
one_var2 = torch.tensor([0.1, 0.1]).float()
one_var3 = torch.tensor([0.1, 0.1]).float()

var = torch.stack([one_var1, one_var2, one_var3], dim=0)  # 対角成分のみ
print("var:", var)

var_matrix = var[:,:,None] * torch.eye(var.size(1))[None,:,:]
print("var_matrix:", var_matrix)
maen: tensor([[1., 1.],
        [2., 2.],
        [3., 3.]])
var: tensor([[0.1000, 0.1000],
        [0.1000, 0.1000],
        [0.1000, 0.1000]])
var_matrix: tensor([[[0.1000, 0.0000],
         [0.0000, 0.1000]],

        [[0.1000, 0.0000],
         [0.0000, 0.1000]],

        [[0.1000, 0.0000],
         [0.0000, 0.1000]]])
torch.distributions의 단계는 대량으로 지정한 파라미터를 고려할 수 있습니다.
multi_normal = torch.distributions.MultivariateNormal(loc=mean, covariance_matrix=var_matrix)
볼륨 크기batch_size에 액세스할 수 있습니다.
print(multi_normal.batch_shape)
torch.Size([3])
다른 한편, event_shape에서 확률 변수의 비트에 접근할 수 있다.
print(multi_normal.event_shape)
torch.Size([2])
Distribution클래스sample 방법은 일괄 처리를 고려하여 샘플을 채취할 수 있기 때문에 일괄 처리 사이즈 = 모든 샘플 사이즈의VAE에서 샘플 사이즈를 지정하지 않습니다.
samples = multi_normal.sample()
print(samples.shape)
torch.Size([3, 2])
각 평균/방차는 여러 개의 견본을 지정할 때sample 방법으로 견본의 크기를 지정할 수 있다. 아래의 예시에서 분할 차원의 세 개는 각각 100개의 견본을 추출한다.
samples = multi_normal.sample(torch.Size([100]))
print(samples.shape)
torch.Size([100, 3, 2])
아래와 같이 두 번째는 원래의 분할 차원임을 알 수 있다.
fig, ax = plt.subplots()
for i in range(samples.size(1)):  # バッチ次元
    each_samples = samples[:,i,:]
    each_samples_array = each_samples.numpy()
    ax.scatter(each_samples_array[:,0], each_samples_array[:,1])

이상의 예에서 단위 매트릭스를 특별히 이용하여 방차를 매트릭스로 해야 한다. 그러나 일반적으로VAE에서 방차 매트릭스는 대각 매트릭스이기 때문에 각 확률 변수의 비트는 독립적이다. 만약에 이렇게 독립적으로 이용torch.distributions.Independent하면 1차원 변수의 확률 분포로 다차원 변수를 나타낼 수 있다.
one_mean1 = torch.tensor([1,1]).float()
one_mean2 = torch.tensor([2,2]).float()
one_mean3 = torch.tensor([3,3]).float()

mean = torch.stack([one_mean1, one_mean2, one_mean3], dim=0)
print("maen:",mean)

one_sigma1 = torch.sqrt(torch.tensor([0.1, 0.1]))
one_sigma2 = torch.sqrt(torch.tensor([0.1, 0.1]))
one_sigma3 = torch.sqrt(torch.tensor([0.1, 0.1]))

sigma = torch.stack([one_sigma1, one_sigma2, one_sigma3], dim=0)  # 対角成分のみ
print("sigma:", sigma)
maen: tensor([[1., 1.],
        [2., 2.],
        [3., 3.]])
sigma: tensor([[0.3162, 0.3162],
        [0.3162, 0.3162],
        [0.3162, 0.3162]])
normal = torch.distributions.Normal(loc=mean, scale=sigma)
이 mean·var의 대량 크기는 3이고 정규는 변수의 확률 분포이기 때문에 대량 크기가 잘못 식별된다.
print(normal.batch_shape)
torch.Size([3, 2])
print(normal.event_shape)
torch.Size([])
다음 독립된 확률 변수를 정의할 수 있습니다. 두 번째 파라미터는 대량 차원에서 새로운 확률 변수 차원과 대응하는 인덱스입니다. 원시적인 대량 처리 차원이 (3,2)이기 때문에 두 번째 파라미터는 확률 변수 차원으로 지정됩니다.
iid_normal = torch.distributions.Independent(normal, 1) 
print(iid_normal.batch_shape)
torch.Size([3])
print(iid_normal.event_shape)
torch.Size([2])
아래의 예에서 분할 차원의 세 개는 각각 100개의 견본을 추출한다.
samples = iid_normal.sample(torch.Size([100]))
print(samples.shape)
torch.Size([100, 3, 2])
fig, ax = plt.subplots()
for i in range(samples.size(1)):  # バッチ次元
    each_samples = samples[:,i,:]
    each_samples_array = each_samples.numpy()
    ax.scatter(each_samples_array[:,0], each_samples_array[:,1])

좋은 웹페이지 즐겨찾기