> 기술 주변기기 > 일체 포함 > Variational Autoencoder: 이론 및 구현

Variational Autoencoder: 이론 및 구현

PHPz
풀어 주다: 2024-01-24 11:36:07
앞으로
711명이 탐색했습니다.

如何实现变分自动编码器 变分自动编码器的原理和实现步骤

VAE(Variational Autoencoder)는 신경망을 기반으로 하는 생성 모델입니다. 그 목표는 고차원 데이터의 저차원 잠재 변수 표현을 학습하고 이러한 잠재 변수를 데이터 재구성 및 생성에 사용하는 것입니다. 기존 오토인코더와 비교하여 VAE는 잠재 공간의 분포를 학습하여 보다 현실적이고 다양한 샘플을 생성할 수 있습니다. VAE의 구현 방법은 아래에서 자세히 소개된다.

1. VAE의 기본 원리

VAE의 기본 아이디어는 고차원 데이터를 저차원 잠재 공간에 매핑하여 데이터의 차원 축소 및 재구성을 달성하는 것입니다. 인코더와 디코더의 두 부분으로 구성됩니다. 인코더는 입력 데이터 x를 잠재 공간의 평균 μ 및 분산 σ^2에 매핑합니다. 이러한 방식으로 VAE는 잠재 공간의 데이터를 샘플링하고 샘플링된 결과를 디코더를 통해 원본 데이터로 재구성할 수 있습니다. 이 인코더-디코더 구조를 통해 VAE는 잠재 공간에서 연속성이 좋은 새로운 샘플을 생성하여 잠재 공간에서 유사한 샘플을 더 가깝게 만들 수 있습니다. 따라서 VAE는 차원 축소에만 사용될 수 없으며

\begin{aligned}
\mu &=f_{\mu}(x)\
\sigma^2 &=f_{\sigma}(x)
\end{aligned}
로그인 후 복사

여기에서 f_{mu} 및 f_{sigma}는 모든 신경망 모델이 될 수 있습니다. 일반적으로 우리는 인코더를 구현하기 위해 MLP(Multilayer Perceptron)를 사용합니다.

디코더는 잠재 변수 z를 원래 데이터 공간으로 다시 매핑합니다. 즉,

x'=g(z)
로그인 후 복사

여기서 g는 모든 신경망 모델일 수도 있습니다. 마찬가지로 우리는 일반적으로 MLP를 사용하여 디코더를 구현합니다.

VAE에서 잠재 변수 $z$는 사전 분포(일반적으로 가우스 분포)에서 샘플링됩니다. 즉:

z\sim\mathcal{N}(0,I)
로그인 후 복사

이러한 방식으로 재구성 오류를 최소화할 수 있으며 잠재 변수 KL 발산이 사용됩니다. 차원 축소 및 데이터 생성을 달성하기 위해 VAE를 훈련합니다. 구체적으로 VAE의 손실 함수는 다음과 같이 표현될 수 있습니다.

\mathcal{L}=\mathbb{E}_{z\sim q(z|x)}[\log p(x|z)]-\beta\mathrm{KL}[q(z|x)||p(z)]
로그인 후 복사

여기서, q(z|x)는 사후 분포, 즉 입력 x가 주어졌을 때 잠재 변수 z의 조건부 분포입니다. z)는 생성 분포, 즉 잠재 변수 $z$가 주어졌을 때 해당 데이터 분포이고, p(z)는 사전 분포, 즉 잠재 변수 z의 한계 분포가 사용된 하이퍼파라미터입니다. 재구성 오류와 KL 발산의 균형을 유지합니다.

위의 손실 함수를 최소화함으로써 입력 데이터 x를 잠재 공간의 분포 q(z|x)에 매핑할 수 있는 변환 함수 f(x)를 학습하고 다음에서 잠재 변수를 샘플링할 수 있습니다. z로 하여 차원 축소 및 데이터 생성을 달성합니다.

2. VAE 구현 단계

아래에서는 인코더, 디코더 및 손실 함수의 정의를 포함하여 기본 VAE 모델을 구현하는 방법을 소개합니다. MNIST 필기 숫자 데이터 세트를 예로 들겠습니다. 이 데이터 세트에는 60,000개의 훈련 샘플과 10,000개의 테스트 샘플이 포함되어 있으며 각 샘플은 28x28 회색조 이미지입니다.

2.1 데이터 전처리

먼저 MNIST 데이터 세트를 전처리하고 각 샘플을 784차원 벡터로 변환한 후 [0,1] 범위로 정규화해야 합니다. 코드는 다음과 같습니다.

# python

import torch

import torchvision.transforms as transforms

from torchvision.datasets import MNIST

# 定义数据预处理

transform = transforms.Compose([
    transforms.ToTensor(),  # 将图像转换成Tensor格式
    transforms.Normalize(mean=(0.
로그인 후 복사

2.2 모델 구조 정의

다음으로 잠재 변수의 인코더, 디코더 및 샘플링 기능을 포함하여 VAE 모델의 구조를 정의해야 합니다. 이 예에서는 2계층 MLP를 인코더와 디코더로 사용하며, 각 계층의 숨겨진 유닛 수는 각각 256개와 128개입니다. 잠재변수의 차원은 20이다. 코드는 다음과 같습니다.

import torch.nn as nn

class VAE(nn.Module):
    def __init__(self, input_dim=784, hidden_dim=256, latent_dim=20):
        super(VAE, self).__init__()

        # 定义编码器的结构
        self.encoder = nn.Sequential(
            nn.Linear(input_dim, hidden_dim),
            nn.ReLU(),
            nn.Linear(hidden_dim, hidden_dim//2),
            nn.ReLU(),
            nn.Linear(hidden_dim//2, latent_dim*2)  # 输出均值和方差
        )

        # 定义解码器的结构
        self.decoder = nn.Sequential(
            nn.Linear(latent_dim, hidden_dim//2),
            nn.ReLU(),
            nn.Linear(hidden_dim//2, hidden_dim),
            nn.ReLU(),
            nn.Linear(hidden_dim, input_dim),
            nn.Sigmoid()  # 输出范围在[0, 1]之间的概率
        )

    # 潜在变量的采样函数
    def sample_z(self, mu, logvar):
        std = torch.exp(0.5*logvar)
        eps = torch.randn_like(std)
        return mu + eps*std

    # 前向传播函数
    def forward(self, x):
        # 编码器
        h = self.encoder(x)
        mu, logvar = h[:, :latent_dim], h[:, latent_dim:]
        z = self.sample_z(mu, logvar)

        # 解码器
        x_hat = self.decoder(z)
        return x_hat, mu, logvar
로그인 후 복사

위 코드에서는 인코더와 디코더로 2계층 MLP를 사용합니다. 인코더는 입력 데이터를 잠재 공간의 평균 및 분산에 매핑합니다. 여기서 평균의 차원은 20이고 분산의 차원도 20이므로 잠재 변수의 차원은 20이 됩니다. 디코더는 잠재 변수를 원래 데이터 공간으로 다시 매핑합니다. 여기서 마지막 레이어는 Sigmoid 함수를 사용하여 출력 범위를 [0, 1]로 제한합니다.

VAE 모델을 구현할 때 손실 함수도 정의해야 합니다. 이 예에서는 재구성 오류와 KL 발산을 사용하여 손실 함수를 정의합니다. 여기서 재구성 오류는 교차 엔트로피 손실 함수를 사용하고 KL 발산은 표준 정규 분포를 사전 분포로 사용합니다. 코드는 다음과 같습니다.

# 定义损失函数
def vae_loss(x_hat, x, mu, logvar, beta=1):
    # 重构误差
    recon_loss = nn.functional.binary_cross_entropy(x_hat, x, reduction='sum')

    # KL散度
    kl_loss = -0.5 * torch.sum(1 + logvar - mu.pow(2) - logvar.exp())

    return recon_loss + beta*kl_loss
로그인 후 복사

위 코드에서는 교차 엔트로피 손실 함수를 사용하여 재구성 오류를 계산하고 KL 발산을 사용하여 잠재 변수 분포와 사전 분포의 차이를 계산합니다. 그 중 베타는 재구성 오류와 KL 발산의 균형을 맞추는 데 사용되는 하이퍼파라미터입니다.

2.3 훈련 모델

마지막으로 훈련 기능을 정의하고 MNIST 데이터 세트에서 VAE 모델을 훈련해야 합니다. 훈련 과정에서 먼저 모델의 손실 함수를 계산한 다음 역전파 알고리즘을 사용하여 모델 매개변수를 업데이트해야 합니다. 코드는 다음과 같습니다:

# python
# 定义训练函数

def train(model, dataloader, optimizer, device, beta):
    model.train()
    train_loss = 0

for x, _ in dataloader:
    x = x.view(-1, input_dim).to(device)
    optimizer.zero_grad()
    x_hat, mu, logvar = model(x)
    loss = vae_loss(x_hat, x, mu, logvar, beta)
        loss.backward()
        train_loss += loss.item()
        optimizer.step()

return train_loss / len(dataloader.dataset)
로그인 후 복사

이제 위의 훈련 함수를 사용하여 MNIST 데이터 세트에서 VAE 모델을 훈련할 수 있습니다. 코드는 다음과 같습니다.

# 定义模型和优化器
model = VAE().to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)

# 训练模型
num_epochs = 50
for epoch in range(num_epochs):
    train_loss = train(model, trainloader, optimizer, device, beta=1)
    print(f'Epoch {epoch+1}/{num_epochs}, Train Loss: {train_loss:.4f}')

# 测试模型
model.eval()
with torch.no_grad():
    test_loss = 0
    for x, _ in testloader:
        x = x.view(-1, input_dim).to(device)
        x_hat, mu, logvar = model(x)
        test_loss += vae_loss(x_hat, x, mu, logvar, beta=1).item()
    test_loss /= len(testloader.dataset)
    print(f'Test Loss: {test_loss:.4f}')
로그인 후 복사

교육 과정에서 우리는 Adam 최적화 프로그램과 베타=1의 하이퍼 매개변수를 사용하여 모델 매개변수를 업데이트합니다. 훈련이 완료된 후 테스트 세트를 사용하여 모델의 손실 함수를 계산합니다. 이 예에서는 재구성 오류와 KL 발산을 사용하여 손실 함수를 계산하므로 테스트 손실이 작을수록 모델이 학습한 잠재적 표현이 더 좋고 생성된 샘플이 더 현실적입니다.

2.4 샘플 생성

最后,我们可以使用VAE模型生成新的手写数字样本。生成样本的过程非常简单,只需要在潜在空间中随机采样,然后将采样结果输入到解码器中生成新的样本。代码如下:

# 生成新样本
n_samples = 10
with torch.no_grad():
    # 在潜在空间中随机采样
    z = torch.randn(n_samples, latent_dim).to(device)
    # 解码生成样本
    samples = model.decode(z).cpu()
    # 将样本重新变成图像的形状
    samples = samples.view(n_samples, 1, 28, 28)
    # 可视化生成的样本
    fig, axes = plt.subplots(1, n_samples, figsize=(20, 2))
    for i, ax in enumerate(axes):
        ax.imshow(samples[i][0], cmap='gray')
        ax.axis('off')
    plt.show()
로그인 후 복사

在上述代码中,我们在潜在空间中随机采样10个点,然后将这些点输入到解码器中生成新的样本。最后,我们将生成的样本可视化展示出来,可以看到,生成的样本与MNIST数据集中的数字非常相似。

综上,我们介绍了VAE模型的原理、实现和应用,可以看到,VAE模型是一种非常强大的生成模型,可以学习到高维数据的潜在表示,并用潜在表示生成新的样本。

위 내용은 Variational Autoencoder: 이론 및 구현의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:163.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿