Computer Science/Python

[AI PYTHON] AUTOENCODER 오토인코더 (ChatGpt, Stable Diffusion의 원리)

2023. 4. 27. 00:05
목차
  1. Autoencoder 의 구성
  2. Autoencoder Training
  3. 결과 확인
728x90

Generative Model (생성형 모델) 중 하나인 ChatGPT가 AI의 잠재력을 전세계에 퍼뜨리고 있다. 개인적인 생각으로 만든 사람도 정확히 ChatGPT가 어떻게 학습이 가능한 지에 대한 설명을 할 수는 없다고 생각한다. Model의 layer, weight들이 학습되는 형태는 처음에 초기값을 어떻게 잡는 지, 어떤 activation function을 쓰는 지에 따라 다르며, chatGPT처럼 데이터가 많게 되면 더더욱 설명하기는 어렵다. 우리가 ChatGPT의 원리를 정확히 알 수는 없더라도 생성형 모델의 기본적인 유형 중 하나인 Autoencoder에 대해서 먼저 보도록 하자. 

 

Autoencoder는 encoder 부분과 decoder 부분으로 나뉜다. Encoder는 latent space(h)로 input data를 압축(추상화) 시켜서차원을 압축한다. Decoder는 latent space를 다시 압축 해제하여 원래 input data를 출력한다. latent space는 manifold를 이루며 autoencoder의 학습이 끝나면 나중에는 latent space를 decoder에만 넣어서 원하는 결과를 출력 할 수 있다. 대표적인 예시로, VAE, GAN, Stable-Diffusion 등등 이미지 분야에서 다양하게 쓰인다.

 

이 블로그에서 다루는 autoencoder는 28 x 28 의 mnist 숫자 데이터이다. pixel 값에 따라 input dimension과 output dimension이 달라지니 개인적인 데이터를 사용할 시에는 참고 바란다!

 

Autoencoder 의 구성

Autoencoder class를 만든다. Activation Function은 sigmoid function을 사용하고 순전파(forward propagation), 역전파 (backward propagation) method, training method를 정의한다.

 

Initialize Weight

weight은 Gaussian Distribution을 따르고 평균은 0, 표준편차는 weight의 input layer의 dimension의 제곱근이다. weight의 사이즈는 input dimesion x output dimension인 행렬이다. 현재는 프레임워크나 라이브러리 없이 해서 간단한 Gaussian Distribution으로 했지만, Xavier Initialization을 사용하여 많은 데이터에 적용할 수 있다.

 

import numpy as np
import matplotlib.pyplot as plt

class Autoencoder:
  def __init__(self, input_dim, hidden_dim, lr=0.01):
    self.weight1 = np.random.normal(0.0, pow(input_dim, -0.5), (input_dim, hidden_dim))
    self.weight2 = np.random.normal(0.0, pow(hidden_dim, -0.5), (hidden_dim, input_dim))
    self.hidden = np.zeros((1,hidden_dim))
    self.learningrate = lr
    self.input_dim = input_dim
    self.hidden_dim = hidden_dim
    self.theta = 0

  def sigmoid(self, x):
    return 1/(1+np.exp(-x))
  def feedforward(self, x):
    self.h = self.sigmoid(np.dot(x, self.weight1) - self.theta) 
    return self.sigmoid(np.dot(self.h, self.w2)-self.theta)
  def backprop_weight2(self, t, y): # target, output
    temporary = -2*(t-y)*y*(1-y)
    return np.dot(self.h.reshape(self.hidden_dim, 1), temporary.reshape(1, self.input_dim))
  def backprop_weight1(self, t, y, x): # target, output, input
    temporary1 = -2*(t-y)*y*(1-y)
    temporary2 = np.dot(self.weight2, temporary1)
    return np.dot(x.reshape(self.input_dim, 1), temporary2*self.h*(1-self.h).reshape(1,self.hidden_dim))
  def training(self, input, target):
    x = np.array(input).T
    y = self.feedforward(x)
    t = np.array(target).T

    self.weight1 = self.weight1 - self.lr*self.backprop_weight1(t,y,x)
    self.weight2 = self.weight2 - self.lr*self.backprop_weight2(t,y)

 

Autoencoder Training

모델을 학습 시키기 전에 hyperparameter를 설정한다. 우리가 사용하는 이미지는 784 픽셀의 이미지이며, latent space의 차원은 100으로 하고 epoch(반복 횟수)는 100으로 한다. 마지막 줄을 통해, 모델 class를 담은 객체를 생성한다!

# Training
input_dim = 784
hidden_dim = 100
epoch = 100

ae = Autoencoder(784, 100, lr=0.1)

 

모델 학습을 위한 이미지 데이터 셋 다운로드. 여기서는 인터넷에서 흔히 구할 수 있는 MNIST data를 사용한다. 따로 데이터를 첨부하지는 않으며 인터넷에 찾으면 무척 많다.

training_dataset_file = open("/content/drive/MyDrive/ml/mnist_original.csv", 'r')
training_dataset_list = training_dataset_file.readlines()
training_dataset_file.close()
input_list = list()

 

각 이미지들을 위에서 만든 ae 라는 autoencoder 객체를 통해서 학습한다.

for k in range(epoch):
  ae.lr = ae.lr * 0.8  # learning rate decay
  for i in training_dataset_list:
    all_values = i.split(',')
    inputs = (np.asfarray(all_values[1:])/255.0*0.99) + 0.01
    input_list.append(inputs)
    ae.training(inputs, inputs)

 

 

참고로 training 동안에는 숫자 0만을 학습 시켰다!!

결과 확인

실제로 이미지를 출력해보면서 결과를 확인해보자.

 

원본 이미지 출력

# True image (dimension = 784)
im_array = np.asfarray(input_list[1]).reshape((28,28))
plt.imshow(im_array, cmap="Greys", interpolation='None')

 

Autoencoder가 생성한 이미지

output = ae.feedforward(input_list[1])
im_array = np.asfarray(output).reshape((28,28))
plt.imshow(im_array, cmap="Greys", interpolation='None') # change 'epoch'

학습에 사용한 숫자 0 외에 다른 숫자 출력해보기

학습동안 사용된 숫자 0은 autoencoder가 출력하는 게 신기하지 않다. 그렇다면 autoencoder 학습에 사용되지 않은 다른 숫자들을 넣었을 때는 어떻게 될까?

 

 테스트에 사용할 데이터 다운로드

test_dataset_file = open("/content/drive/MyDrive/ml/mnist_noise.csv", 'r')
test_dataset_list = test_dataset_file.readlines()
test_dataset_file.close()
test_inputs_list = list()

for i in test_dataset_list:
  all_values = i.split(',')
  test_inputs = (np.asfarray(all_values[1:])/255*0.99) + 0.01
  test_inputs_list.append(test_inputs)

 

원본 이미지 출력

im_array = np.asfarray(test_inputs_list[1]).reshape((28,28))
plt.imshow(im_array, cmap='Greys', interpolation='None')

Autoencoder가 생성한 이미지

 

 

노이즈가 낀 데이터에 대한 Autoencoder 테스트

Autoencoder의 작동 원리상 latent space를 한번 거치기 때문에 이미지가 추상화(압축) 된다. 사람이 기억을 할 때 필요한 기억만 남고 불필요한 기억들은 없애는 것처럼, autoencoder도 동일하게 작동한다.

 

원본 이미지 출력

im_array = np.asfarray(test_inputs_list[20]).reshape((28,28))
plt.imshow(im_array, cmap='Greys', interpolation='None')

Autoencoder가 생성한 이미지

output = ae.feedforward(test_inputs_list[20])
im_array = np.asfarray(output).reshape((28,28))
plt.imshow(im_array, cmap='Greys', interpolation='None')

 

Autoencoder의  기본적인 원리를 알아보고 코드로 구현해 보았다! ChatGpt, Stable Diffusion, Midjourney 등 다양한 Generative Model도 비슷한 원리를 따라간다. 여기서 어떤 weight initialization, activation function, regularization, model type 을 쓸 건지에 따라서 성능 차이가 생길 뿐이다. 이미지를 생성하냐, 말을 생성하냐에 따라서 사용한는 모델 또한 바뀌니 신기 방귀 뿡 가이다!

'Computer Science > Python' 카테고리의 다른 글

[AI-Pytorch Python] 다변수 함수의 선형 회귀 정복 및 실습 (2) (Kill Linear Regression Using Pytorch)  (0) 2023.04.09
[AI-Pytorch Python] 선형 회귀 정복 및 실습 (1) (Kill Linear Regression Using Pytorch)  (0) 2023.04.02
[AI OpenCV-Python] SIFT를 통한 이미지 매칭 (2) (Image Feature Extraction/Matching Using SIFT)  (0) 2023.03.28
[AI OpenCV-Python] SIFT를 통한 이미지 특징 추출 (1) (Image Feature Extraction/Matching Using SIFT)  (0) 2023.03.27
[AI tensorflow] Convolution Neural Network(CNN) MNIST 데이터 구분 (0-9 숫자 구분하기)  (0) 2023.03.23
  • Autoencoder 의 구성
  • Autoencoder Training
  • 결과 확인
'Computer Science/Python' 카테고리의 다른 글
  • [AI-Pytorch Python] 다변수 함수의 선형 회귀 정복 및 실습 (2) (Kill Linear Regression Using Pytorch)
  • [AI-Pytorch Python] 선형 회귀 정복 및 실습 (1) (Kill Linear Regression Using Pytorch)
  • [AI OpenCV-Python] SIFT를 통한 이미지 매칭 (2) (Image Feature Extraction/Matching Using SIFT)
  • [AI OpenCV-Python] SIFT를 통한 이미지 특징 추출 (1) (Image Feature Extraction/Matching Using SIFT)
아키엔지
아키엔지
일기
아키엔지
넓은 구석
아키엔지
전체
오늘
어제
  • 분류 전체보기 (57)
    • Computer Science (35)
      • Matlab(수학) (11)
      • Python (8)
      • AI (4)
      • C++ (5)
      • Graphics (2)
      • C# (3)
    • Architectural Engineering (7)
    • Finance (1)
    • Personal (14)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 머신러닝
  • pytorch
  • 매트랩
  • 인공지능
  • 라플라스
  • 용수철 운동
  • 건설 현장
  • .NET
  • machine learning
  • MATLAB
  • 벡터장
  • CNN
  • 그래프
  • 튜토리얼
  • 파이썬
  • mnist
  • 상미분방정식
  • AI
  • Python
  • C++

최근 댓글

최근 글

hELLO · Designed By 정상우.
아키엔지
[AI PYTHON] AUTOENCODER 오토인코더 (ChatGpt, Stable Diffusion의 원리)
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.