출처: https://www.analyticsvidhya.com/blog/2021/02/a-quick-introduction-to-manifold-learning/
1. AutoEncoder(AE)
출처: https://gaussian37.github.io/dl-concept-autoencoder2/
Input과 Output이 똑같이 설정된 비지도학습 신경망 모델(Unsupervised -> Supervised)
2. Stacked AutoEncoder(SAE)
출처: https://www.hindawi.com/journals/mpe/2018/5105709/
AE를 쌓아올린 모델
1) Input Data로 AE1을 학습(tied 방식 사용- input과 output weight 동일하게)
2) 1)에서 학습된 모형의 Hidden Layer을 Input으로(AE1의 weight 고정) 해 AE2를 학습
3) 2) 과정을 원하는 만큼 반복
4) 1)~3) 과정에서 학습된 Hidden Layer을 쌓아 올림
5) 마지막 Layer에 Classification의 기능이 있는 Output Layer를 추가 (ex. softmax)
6) Fine-tuning
3. Denoising AutoEncoder(DAE)
Robust(강건한)한 Feature을 만들기 위한 AE
4. Stacked Denoising AutoEncoder(SDAE)
SAE에서 AE를 DAE로 대체한 모형
5. Stochastic Contractive AutoEncoder(SCAE)
: Reconstruction Error
: Stochastic Regularization
6. Contractive AutoEncoder(CAE)
SCAE에 Taylor Expansion을 사용하여 Stochastic이 아닌 Deterministic하게 norm형태로 바꿔 계산
7. Variational AutoEncoder(VAE)
출처: https://lilianweng.github.io/lil-log/2018/08/12/from-autoencoder-to-beta-vae.html
Generator이 목적(뒷단이 목적 - 앞의 AE와 다름)
genetor은 이미지를 만들어 내는 애
무작정 만들어내는 것이 아니라 control 할 수 있으면 좋음
z는 control하는 역할 control하기 쉬운 분포 사용(normal, uniform 많이 사용)
network 자체는 deterministic
적분 힘드니까 sample 여러개 모아서 monte carlo 방법으로 sum하면 prior distribution 알 수 있다!
x를 보여주고 적어도 이 x는 잘 generate하는 z 만들어 봐. (이상적인 sampling함수 만든다.)
를 사용하여 구함
ELBO를 최대화하는 를 구하는 것은 이상적인 sampling 함수를 찾는 과정
maximum likelihood를 구한다.(학습)
generator 학습을 하고 싶다. prior에서 sampling하니까 잘 안돼. 그래서 이상적인 함수에서 sampling. x를 evidence로 주고 x로 잘 generate하는 z를 sampling하는 도입.
거기서 sampling해서 z를 구한 다음 x 나올 확률을 maximize한다.
하다보니 x가 입력으로 들어가서 sampling하고 나오는 값이 x가 되었다. AE가 되어버렸다.
수학적으로 보면 기존 AE와 VAE는 관련이 없다.
샘플링용 함수에 대한 NLL + 샘플링의 용이성과 통제성을 위한 조건을 prior에 부여하고 이와 유사해야 한다는 조건 부여
사실상 일단 AE와 다른 점은 Loss에 KL term이 붙는다는 정도(그 앞은 AE와 동일)
8. Conditional Variational AutoEncoder(CVAE)
출처: https://ratsgo.github.io/generative%20model/2018/01/28/VAEs/
9. Adversarial AutoEncoder(AAE)
https://medium.com/vitrox-publication/adversarial-auto-encoder-aae-a3fc86f71758
# AutoEncoder 모델링
class AE(torch.nn.Module): # nn.Module 클래스를 상속받는 AE 클래스 정의(함수 그대로 이용 가능)
def __init__(self): # 인스턴스 생성 시 지니게 되는 성질 정의
super(AE, self).__init__() # nn.Module 내의 메소드 상속받아 이용
self.encoder = nn.Sequential(
torch.nn.linear(28*28, 512),
torch.nn.ReLU(),
torch.nn.Linear(512, 256),
torch.nn.ReLU(),
torch.nn.Linear(256, 32)
)
self.decoder = nn.Sequential(
torch.nn.Linear(32, 256),
torch.nn.ReLU(),
torch.nn.Linear(256, 512),
torch.nn.ReLU()
torch.nn.Linear(512, 28*28)
)
def forward(self, x):
encoded = self.encoder(x) # latent variable vector 생성
decoded = self.decoder(encoded)
return encoded, decoded
# Optimizer&Criterion
model = AE.to(device)
optimizer = torch.optim.Adam(model.parameters, lr = 0.001)
criterion = nn.MSELoss()
# train, evaluate 함수
def train(model, train_loader, optimizer, log_interval):
model.train()
for batch_idx, (image, _) in enumerate(train_loader):
image = image.view(-1, 28*28).to(device)
target = image.view(-1, 28*28).to(device)
optimizer.zero_grad() # 기울기 초기화
encoded, decoded = model.forward(image) # 모델 계산
loss = criterion(decoded, target) # loss 계산
loss.backward() # 역전파법
optimizer.step() # 파라미터 업데이트
if batch_idx % log_interval == 0:
print(f'Train Epoch: {epoch},\tTrain Loss: {loss.item()}')
def evaluate(model, test_loader):
model.eval()
test_loss = 0
real_image = {}
gen_image = {}
with torch.no_grad(): # 파라미터 값 고정(학습되지 않도록)
for image, _ in test_loader:
image = image.view(-1, 28*28).to(device)
taget = image.veiw(-1, 28*28).to(device)
encoded, decoded = model(image)
test_loss += criterion(decoded, image).item()
real_image.append(image.to('cpu'))
gen_image.append(image.to('cpu'))
test_loss /= len(test_loader.dataset)
return test_loss, real_image, gen_image
# 모델 학습
for epoch in range(1, epochs+1):
train(model, train_loader, optimizer, 200)
test_loss, real_image, gen_image = evaluate(model, test_loader)
print(f'\nEpoch: {epoch},\tTest Loss: {test_loss}')
f, a = plt.subplots(2,10, figsize=(10,4))
for i in range(10):
img = np.reshape(real_image[0][i],(28,28))
a[0][i].imshow(img, cmap = 'gray_r')
a[0][i].set_xticks(())
a[0][i].set_yticks(())
for i in range(10):
img = np.reshape(gen_image[0][i],(28,28))
a[1][i].imshow(img, cmap = 'gray_r')
a[1][i].set_xticks(())
a[1][i].set_yticks(())
plt.show()
참고
파이썬 딥러닝 파이토치 (이경택, 방성수, 안상준)
https://www.youtube.com/watch?v=o_peo6U7IRM
https://www.youtube.com/watch?v=rNh2CrTFpm4