Encoding: Data를 저차원 latent space의 특정 point에 mapping시키는 것. Decoding: 이 point의 위치를 받아 해당 Data를 다시 생성하려 시도하는 것. encoder는 decoder가 정확하게 재구성하도록 가능한 많은 정보를 내포시키려 하는데, 이 벡터를 embedding이라 한다.
Auto Encoder: encoding과 decoding작업을 수행하도록 훈련된 신경망. → 원본에 가까워지도록 train시킨다. 보통 Loss function으론 원본과 재구성 img의 pixel간의 RMSE나 BCE를 사용한다. input은 latent embedding vector z로 encoding, 원본픽셀공간으로 decoding
🤔 이미 갖고 있는 img를 왜 재구성?
이미 갖고있는 img를 왜 재구성해야할까? "Auto Encoder 사용이유": Embedding공간(latent space) 때문! latent space에서 sampling하여 새로운 img를 생성할 수 있기 때문.
cf) test_set을 encoder에 통과시켜 만들어진 embedding을 그래프(scatter 등)로 나타내면, img가 latent space에 어떻게 embedding되는지 시각화가능하다.
import torch
import torch.nn as nn
import matplotlib.pyplot as plt
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
# 예시: Autoencoder 모델 정의
class Autoencoder(nn.Module):
def __init__(self, input_size, hidden_size):
super(Autoencoder, self).__init__()
self.encoder = nn.Linear(input_size, hidden_size)
self.decoder = nn.Linear(hidden_size, input_size)
def forward(self, x):
encoded = self.encoder(x)
decoded = self.decoder(encoded)
return encoded, decoded
# 예시: 잠재 공간 시각화 함수
def visualize_latent_space(data_loader, model, device):
model.eval()
latent_space, labels = [], []
with torch.no_grad():
for images, labels_batch in data_loader:
images = images.view(images.size(0), -1).to(device)
encoded, _ = model(images)
latent_space.append(encoded.cpu().numpy())
labels.append(labels_batch.numpy())
latent_space = torch.cat(latent_space, dim=0)
labels = torch.cat(labels, dim=0)
plt.figure(figsize=(10, 8))
plt.scatter(latent_space[:, 0], latent_space[:, 1], c=labels, cmap='viridis')
plt.colorbar()
plt.title('Latent Space Visualization')
plt.show()
# 예시: 데이터 로딩
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])
mnist_data = datasets.MNIST(root='./data', train=True, transform=transform, download=True)
data_loader = DataLoader(mnist_data, batch_size=64, shuffle=True)
# 예시: 모델 및 학습 설정
input_size = 28 * 28 # MNIST 이미지 크기
hidden_size = 2 # 잠재 공간 차원
autoencoder_model = Autoencoder(input_size, hidden_size)
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
autoencoder_model.to(device)
# 예시: 학습된 모델의 가중치 로드
autoencoder_model.load_state_dict(torch.load('autoencoder_model.pth'))
autoencoder_model.eval()
# 예시: 잠재 공간 시각화
visualize_latent_space(data_loader, autoencoder_model, device)
이에대해, Decoder를 사용해 다시 pixel공간으로 변환하면 새로운 img를 생성할 수 있다.
import torch
import torch.nn as nn
import matplotlib.pyplot as plt
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
# 예시: Autoencoder 모델 정의
class Autoencoder(nn.Module):
def __init__(self, input_size, hidden_size):
super(Autoencoder, self).__init__()
self.encoder = nn.Linear(input_size, hidden_size)
self.decoder = nn.Linear(hidden_size, input_size)
def forward(self, x):
encoded = self.encoder(x)
decoded = self.decoder(encoded)
return encoded, decoded
# 예시: 이미지 생성 함수
def generate_image_from_latent_space(latent_vector, model, device):
model.eval()
with torch.no_grad():
latent_vector = torch.tensor(latent_vector).float().to(device)
reconstructed_image = model.decoder(latent_vector)
reconstructed_image = reconstructed_image.view(1, 1, 28, 28) # MNIST 이미지 크기
return reconstructed_image
# 예시: 이미지 시각화 함수
def visualize_image(image):
plt.imshow(image.squeeze().cpu().numpy(), cmap='gray')
plt.axis('off')
plt.show()
# 예시: 데이터 로딩
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])
mnist_data = datasets.MNIST(root='./data', train=True, transform=transform, download=True)
data_loader = DataLoader(mnist_data, batch_size=64, shuffle=True)
# 예시: 모델 및 학습 설정
input_size = 28 * 28 # MNIST 이미지 크기
hidden_size = 2 # 잠재 공간 차원
autoencoder_model = Autoencoder(input_size, hidden_size)
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
autoencoder_model.to(device)
# 예시: 학습된 모델의 가중치 로드
autoencoder_model.load_state_dict(torch.load('autoencoder_model.pth'))
autoencoder_model.eval()
# 예시: 잠재 공간에서 샘플링하여 이미지 생성 및 시각화
latent_vector_sample = [0.5, 0.5] # 잠재 공간에서 샘플링한 값
generated_image = generate_image_from_latent_space(latent_vector_sample, autoencoder_model, device)
visualize_image(generated_image)
2. Variational Auto Encoder
Auto Encoder의 문제점.
Auto Encoder는 latent space가 연속적인지 강제하지 않기에, 다룰 수 있는 차원 수가 적다. 그렇기에, 더 복잡한 img생성 시, latent space에 더 많은 차원 사용 시, 이 문제는 뚜렷해진다. 즉, encoding 시, latent space를 자유롭게 사용하면 비슷한 point가 모인 그룹간의 큰 간격이 발생한다. 이런 간격이 발생한 공간에서는 잘 형성된 img를 생성할 가능성이 낮다.
이를 위해 Auto Encoder 대신, Variational Auto Encoder로 바꿔야한다.
VAE
AE: 각 img가 latent space의 한 point에 직접 mapping됨. VAE: 각 img가 latent space point주변의 다변량정규분포에 mapping됨. 다변량 정규분포 N(0,I)는 평균벡터가 0, 공분산행렬이 단위벡터이다. 즉, 요약해보면 Encoder는 input을 받아 latent space의 다변량정규분포를 정의하는 2개의 벡터로 encoding한다. ∙ z_mean: 이 분포의 평균벡터 ∙ z_log_var: 차원별 분산의 로그값
이런 작은 변화로 어떻게 Encoder를 향상시킬 수 있었을까? 이전 AE: latent space를 연속적으로 만들필요❌ VAE: z_mean주변영역에서 random point를 sampling하기에 재구성손실이 작게 유지되도록 동일영역의 Point의 img와 매우 비슷하게 decoding.
cf) reparameterization trick이란?
mean과 log_var로 정의된 정규분포에서 직접 sampling하는 대신, 표준정규분포에서 epsilon을 sampling → 올바른 평균과 분산을 갖도록 sample수동조정.
이 방법은 epsilon을 포함함으로써 출력의 편도함수를 결정론적(= random epsilon과 무관함)으로 표시할 수 있어 역전파를 위해 필수적이다.
🧐 Loss Function
AE의 손실함수: Src_img와 AE통과한 출력간의 Reconstruction Loss VAE: Reconstruction Loss + KL-Divergence (Latent Loss)
KL Divergence는 z_mean과 z_log_var가 표준정규분포와 얼마나 다른지를 측정한다.
CNN, Convolutional Neural Network은 기존 딥러닝 신경망이었던 Fully-Connected Layer를 대체하기 위해 나왔다.
CNN은 Locally-Connected Layer로 Fully-Connected Layer에 비해 정보손실이 발생할 수 있다.
하지만 CNN은 이런 정보손실에 대해 channel을 많이 줌을 통해 정보손실을 방지할 수 있다.
또한 CNN은 FC보다 훨씬 weight수 즉, param#이 더 줄어든다
weight의 개수 = input_channel수 x kernel개수 x kernel개수 x output_channel
(단, padding='same')
filter를 weight로 하며, 이때 model은 weight를 조정하여 filter를 모델이 '알아서' 만들도록 한다.
(filtering을 모델에게 맡겨 상황에 따라 필요한 filter를 자체적으로 만들 수 있게 하는 것이다.)
[Auto-Encoder]
[본 목적]
input의 압축 => 스스로 압축 알고리즘을 학습할 수 있는, input에 근사한 압축값을 뽑아낼 수 있음. - 특정 분야에서 정상적으로 동작한다.
(글자->강아지로 클래스가 변하게 된다면? 특징을 못뽑을 수도 있는, 특정 dataset에서만 가능한 비범용적 방법이다.)
- 주로 언어모델, segmentation 등등에서 사용됨.)
Encoding
- 코드화 시키는 것 = 어떠한 코드로 1:1 매칭시키는 것 - 암호화 즉, 용량 압축의 효과 및 일반화도 가능하다.
bottleneck
- 정보가 embedding되어 있음(= 필요 정보만 모여있는 것)
Decoding
- decoding은 사람이 이해하도록 바꿔주는 것으로 encoding과 반대 개념이다. - 이때, input image에 비해 손실이 발생한다.
[Curse of Dimensionality., 차원의 저주]
- 차원이 늘어날수록 문제를 풀기 쉬워지는것은 어느 정도까지이다! - 즉, 역효과가 발생가능하다. → 도리어 학습이 안될 수 있다는 것!
[ERF (Effective Receptive Field)]
- 학습이 되면서 점점 receptive field가 Gaussian distribution 형태에 가까워지는데, 이를 effective receptive field라 한다. - (가장 최외각의 patch는 뒤로 갈수록 영향력이 줄고, 가운데 patch의 영향력이 커져 뒤로갈수록 정규분포와 비슷해져버림) - 이러한 문제로 인해 CNN이 깊게 쌓을 수 없게 된다. → attention을 이용한 transformer, ViT가 나오게 된 배경이 되어 버림!