>기술 주변기기 >일체 포함 >이미지 압축 구현 프로세스: Variational Autoencoder

이미지 압축 구현 프로세스: Variational Autoencoder

王林
王林앞으로
2024-01-23 11:24:151246검색

이미지 압축 구현 프로세스: Variational Autoencoder

VAE(Variational Autoencoder)는 이미지 압축 및 생성에 사용되는 비지도 학습 신경망입니다. 기존 자동 인코더와 비교하여 VAE는 입력 이미지를 재구성하고 이와 유사한 새로운 이미지를 생성할 수 있습니다. 핵심 아이디어는 입력 이미지를 잠재 변수 분포로 인코딩하고 이로부터 샘플링하여 새로운 이미지를 생성하는 것입니다. VAE는 변형 추론을 사용하여 모델을 훈련하고 관찰된 데이터와 생성된 데이터 사이의 하한을 최대화하여 매개변수 학습을 달성한다는 점에서 독특합니다. 이 방법을 통해 VAE는 데이터의 기본 구조와 새로운 샘플을 생성하는 기능을 학습할 수 있습니다. VAE는 이미지 생성, 속성 편집, 이미지 재구성 등의 작업을 포함한 다양한 분야에서 놀라운 성공을 거두었습니다.

VAE(Variational Autoencoder)는 오토인코더와 유사한 구조를 가지며 인코더와 디코더로 구성됩니다. 인코더는 입력 이미지를 평균 벡터와 분산 벡터를 포함한 잠재 변수 분포로 압축합니다. 디코더는 잠재 변수를 샘플링하여 새 이미지를 생성합니다. 잠재 변수의 분포를 보다 합리적으로 만들기 위해 VAE는 KL 발산의 정규화 항을 도입하여 잠재 변수의 분포를 표준 정규 분포에 더 가깝게 만듭니다. 그렇게 하면 모델의 표현력과 생성 능력이 향상될 수 있습니다.

다음은 MNIST 필기 숫자 데이터 세트를 예로 들어 VAE 구현 프로세스를 소개합니다.

먼저 필요한 라이브러리와 데이터세트를 가져와야 합니다.

import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
from torch.autograd import Variable

# 加载数据集
transform = transforms.Compose([
    transforms.ToTensor(),
])
train_dataset = datasets.MNIST(root='./data/', train=True, transform=transform, download=True)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=128, shuffle=True)

다음으로 인코더와 디코더의 네트워크 구조를 정의합니다.

# 定义编码器
class Encoder(nn.Module):
    def __init__(self):
        super(Encoder, self).__init__()
        self.conv1 = nn.Conv2d(1, 32, kernel_size=3, stride=1, padding=1)
        self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=2, padding=1)
        self.conv3 = nn.Conv2d(64, 128, kernel_size=3, stride=2, padding=1)
        self.fc1 = nn.Linear(128 * 7 * 7, 256)
        self.fc21 = nn.Linear(256, 20) # 均值向量
        self.fc22 = nn.Linear(256, 20) # 方差向量

    def forward(self, x):
        x = nn.functional.relu(self.conv1(x))
        x = nn.functional.relu(self.conv2(x))
        x = nn.functional.relu(self.conv3(x))
        x = x.view(-1, 128 * 7 * 7)
        x = nn.functional.relu(self.fc1(x))
        mean = self.fc21(x)
        log_var = self.fc22(x)
        return mean, log_var


# 定义解码器
class Decoder(nn.Module):
    def __init__(self):
        super(Decoder, self).__init__()
        self.fc1 = nn.Linear(20, 256)
        self.fc2 = nn.Linear(256, 128 * 7 * 7)
        self.conv1 = nn.ConvTranspose2d(128, 64, kernel_size=3, stride=2, padding=1, output_padding=1)
        self.conv2 = nn.ConvTranspose2d(64, 32, kernel_size=3, stride=2, padding=1, output_padding=1)
        self.conv3 = nn.ConvTranspose2d(32, 1, kernel_size=3, stride=1, padding=1)

    def forward(self, x):
        x = nn.functional.relu(self.fc1(x))
        x = nn.functional.relu(self.fc2(x))
        x = x.view(-1, 128, 7, 7)
        x = nn.functional.relu(self.conv1(x))
        x = nn.functional.relu(self.conv2(x))
        x = nn.functional.sigmoid(self.conv3(x))
        return x


# 定义VAE模型
class VAE(nn.Module):
    def __init__(self):
        super(VAE, self).__init__()
        self.encoder = Encoder()
        self.decoder = Decoder()

    def reparameterize(self, mean, log_var):
        std = torch.exp(0.5 * log_var)
        eps = torch.randn_like(std)
        return eps * std + mean

    def forward(self, x):
        mean, log_var = self.encoder(x)

다음 단계는 VAE 모델의 순방향 전파 프로세스입니다. 여기에는 잠재 변수에서 샘플링하여 새 이미지를 생성하고 재구성 오류 및 KL 발산의 정규화 항을 계산하는 작업이 포함됩니다.

z = self.reparameterize(mean, log_var)
x_recon = self.decoder(z)
return x_recon, mean, log_var

def loss_function(self, x_recon, x, mean, log_var):
    recon_loss = nn.functional.binary_cross_entropy(x_recon, x, size_average=False)
    kl_loss = -0.5 * torch.sum(1 + log_var - mean.pow(2) - log_var.exp())
    return recon_loss + kl_loss

def sample(self, num_samples):
    z = torch.randn(num_samples, 20)
    samples = self.decoder(z)
    return samples

마지막으로 옵티마이저를 정의하고 모델 학습을 시작합니다.

# 定义优化器
vae = VAE()
optimizer = optim.Adam(vae.parameters(), lr=1e-3)

# 开始训练模型
num_epochs = 10
for epoch in range(num_epochs):
for batch_idx, (data, _) in enumerate(train_loader):
data = Variable(data)
optimizer.zero_grad()
x_recon, mean, log_var = vae(data)
loss = vae.loss_function(x_recon, data, mean, log_var)
loss.backward()
optimizer.step()

    if batch_idx % 100 == 0:
        print('Epoch [{}/{}], Batch [{}/{}], Loss: {:.4f}'.format(
            epoch+1, num_epochs, batch_idx+1, len(train_loader), loss.data.item()))

훈련이 완료된 후 VAE를 사용하여 새로운 손글씨 숫자 이미지를 생성할 수 있습니다.

# 生成手写数字图像
samples = vae.sample(10)
fig, ax = plt.subplots(1, 10, figsize=(10, 1))
for i in range(10):
ax[i].imshow(samples[i].detach().numpy().reshape(28, 28), cmap='gray')
ax[i].axis('off')
plt.show()

VAE는 입력 이미지를 잠재 변수 분포로 인코딩하는 동시에 샘플링하여 새로운 이미지를 생성함으로써 이미지 압축을 달성하는 강력한 이미지 압축 및 생성 모델입니다. 기존 자동 인코더와 달리 VAE는 잠재 변수의 분포를 보다 합리적으로 만들기 위해 KL 발산의 정규화 용어도 도입합니다. VAE를 구현할 때 인코더와 디코더의 네트워크 구조를 정의하고 재구성 오류 및 KL 발산의 정규화 항을 계산해야 합니다. VAE 모델을 훈련함으로써 입력 이미지의 잠재 변수 분포를 학습할 수 있고, 이를 통해 새로운 이미지를 생성할 수 있습니다.

위 내용은 VAE의 기본 소개 및 구현 과정입니다. 독자들에게 도움이 되기를 바랍니다.

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

성명:
이 기사는 163.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제