1. GAN(Generative Adversarial Network)
GAN은 Ian Goodfellow가 2014년에 제안한 모델로, 두 개의 신경망인 생성기(generator)와 판별기(discriminator)가 서로 경쟁하는 구조입니다. 이 경쟁을 통해 생성기는 실제처럼 보이는 데이터를 생성하게 됩니다.
1.1 GAN의 구조
GAN은 두 개의 신경망으로 구성됩니다. 생성기는 랜덤 노이즈 벡터를 입력받아 가짜 데이터를 생성하고, 판별기는 입력받은 데이터가 실제 데이터인지 생성된 데이터인지를 구별합니다. 생성기와 판별기는 각각의 목적을 가지고 훈련됩니다.
1.2 GAN의 손실 함수
GAN의 손실 함수는 생성기와 판별기의 성능을 평가하는 데 사용됩니다. 생성기는 판별기를 속이기 위해 노력하고, 판별기는 이를 구별하기 위해 노력합니다.
\[
\text{Loss}_D = – \mathbb{E}_{x \sim p_{data}(x)}[\log(D(x))] – \mathbb{E}_{z \sim p_z(z)}[\log(1 – D(G(z)))]
\]
\[
\text{Loss}_G = – \mathbb{E}_{z \sim p_z(z)}[\log(D(G(z)))]
\]
1.3 GAN 예제 코드
다음은 PyTorch를 사용하여 간단한 GAN을 구현한 코드입니다:
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
# 하이퍼파라미터 정의
latent_size = 100
batch_size = 64
num_epochs = 200
learning_rate = 0.0002
# 데이터셋 불러오기
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))
])
dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
data_loader = torch.utils.data.DataLoader(dataset, batch_size=batch_size, shuffle=True)
# 생성기 정의
class Generator(nn.Module):
def __init__(self):
super(Generator, self).__init__()
self.model = nn.Sequential(
nn.Linear(latent_size, 256),
nn.ReLU(),
nn.Linear(256, 512),
nn.ReLU(),
nn.Linear(512, 1024),
nn.ReLU(),
nn.Linear(1024, 28*28),
nn.Tanh()
)
def forward(self, z):
return self.model(z).view(-1, 1, 28, 28)
# 판별기 정의
class Discriminator(nn.Module):
def __init__(self):
super(Discriminator, self).__init__()
self.model = nn.Sequential(
nn.Linear(28*28, 1024),
nn.LeakyReLU(0.2),
nn.Linear(1024, 512),
nn.LeakyReLU(0.2),
nn.Linear(512, 256),
nn.LeakyReLU(0.2),
nn.Linear(256, 1),
nn.Sigmoid()
)
def forward(self, img):
return self.model(img.view(-1, 28*28))
# 모델 초기화
generator = Generator()
discriminator = Discriminator()
# 손실 함수 및 최적화기 정의
criterion = nn.BCELoss()
optimizer_G = optim.Adam(generator.parameters(), lr=learning_rate)
optimizer_D = optim.Adam(discriminator.parameters(), lr=learning_rate)
# 학습 과정
for epoch in range(num_epochs):
for i, (imgs, _) in enumerate(data_loader):
# 진짜 이미지와 가짜 이미지 레이블
real_imgs = imgs
real_labels = torch.ones(imgs.size(0), 1) # 진짜 레이블
fake_labels = torch.zeros(imgs.size(0), 1) # 가짜 레이블
# 판별기 학습
optimizer_D.zero_grad()
outputs = discriminator(real_imgs)
d_loss_real = criterion(outputs, real_labels)
z = torch.randn(imgs.size(0), latent_size)
fake_imgs = generator(z)
outputs = discriminator(fake_imgs.detach())
d_loss_fake = criterion(outputs, fake_labels)
d_loss = d_loss_real + d_loss_fake
d_loss.backward()
optimizer_D.step()
# 생성기 학습
optimizer_G.zero_grad()
outputs = discriminator(fake_imgs)
g_loss = criterion(outputs, real_labels)
g_loss.backward()
optimizer_G.step()
print(f"Epoch [{epoch}/{num_epochs}], d_loss: {d_loss.item()}, g_loss: {g_loss.item()}")
2. 오토인코더(Autoencoder)
오토인코더는 입력 데이터를 압축하고 복원하는 비지도 학습 방법입니다. 입력과 동일한 출력을 목표로 하며, 특성을 학습하는 과정을 통해 데이터를 압축합니다.
2.1 오토인코더의 구조
오토인코더는 인코더와 디코더 두 부분으로 나뉩니다. 인코더는 입력을 저차원 잠재 표현(latent representation)으로 변환하며, 디코더는 이 잠재 표현을 사용하여 원래의 입력을 복원합니다.
2.2 오토인코더의 손실 함수
오토인코더는 주로 Mean Squared Error(MSE)를 손실 함수로 사용하여 입력과 출력 간의 차이를 최소화합니다.
\[
\text{Loss} = \frac{1}{N} \sum_{i=1}^N (x_i – \hat{x}_i)^2
\]
2.3 오토인코더 예제 코드
다음은 PyTorch를 사용한 간단한 오토인코더의 구현 코드입니다:
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
# 하이퍼파라미터 정의
batch_size = 64
num_epochs = 20
learning_rate = 0.001
# 데이터셋 불러오기
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))
])
dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
data_loader = torch.utils.data.DataLoader(dataset, batch_size=batch_size, shuffle=True)
# 오토인코더 정의
class Autoencoder(nn.Module):
def __init__(self):
super(Autoencoder, self).__init__()
self.encoder = nn.Sequential(
nn.Linear(28*28, 128),
nn.ReLU(),
nn.Linear(128, 64),
nn.ReLU()
)
self.decoder = nn.Sequential(
nn.Linear(64, 128),
nn.ReLU(),
nn.Linear(128, 28*28),
nn.Sigmoid()
)
def forward(self, x):
x = x.view(-1, 28*28)
encoded = self.encoder(x)
reconstructed = self.decoder(encoded)
return reconstructed.view(-1, 1, 28, 28)
# 모델 초기화
autoencoder = Autoencoder()
# 손실 함수 및 최적화기 정의
criterion = nn.MSELoss()
optimizer = optim.Adam(autoencoder.parameters(), lr=learning_rate)
# 학습 과정
for epoch in range(num_epochs):
for imgs, _ in data_loader:
optimizer.zero_grad()
outputs = autoencoder(imgs)
loss = criterion(outputs, imgs)
loss.backward()
optimizer.step()
print(f"Epoch [{epoch}/{num_epochs}], Loss: {loss.item()}")
3. 결론
GAN과 오토인코더는 이미지 생성 및 데이터 표현 및 압축을 위한 강력한 딥러닝 기법입니다. 각각의 구조와 학습 방법을 이해하고 실습함으로써, 더 높은 수준의 딥러닝 지식을 쌓을 수 있습니다.
이러한 모델들은 다양한 응용 분야에 활용될 수 있으며, 커스터마이징된 아키텍처로 더 나은 결과를 도출할 수 있습니다.