텐서플로우(TensorFlow)를 이용해서 MNIST 데이터를 생성하는 GAN(Generative Adversarial Networks) 생성 모델(Generative Model) 구현해보기 – GAN 예제

이번 시간에는 텐서플로우(TensorFlow)를 이용해서 MNIST 데이터를 생성해내는 GAN(Generative Adversarial Networks) 모델을 구현해보자.

 

Generative Adversarial Networks(GAN)

Generative Adversarial Networks(GAN)은 적대적 학습(Adversarial Networks) 구조를 이용해서 생성 모델을 학습하는 아키텍쳐이다. GAN은 Discriminator(구분자)와 Generator(생성자)로 구성되어있다.

이는 경찰과 위조지폐생성범의 관계로 비유할 수 있다. 구분자는 어떤 이미지가 진짜 이미지인지 아니면 생성자가 만들어낸 가짜 이미지인지를 구분하도록 학습한다. 생성자는 Latent Variable(Noise Distribution에서 추출한 값)로부터 생성한 이미지가 구분자를 잘 속일 수 있도록 학습한다.

결과적으로 생성자는 원래 데이터의 분포(Distribution)을 거의 정확하게 근사하게 되고, 구분자는 50% 확률로 진짜 이미지와 생성자에 의해 생성된 가짜 이미지를 구분하는 균형점에 도달하게 된다. 새로운 이미지를 생성하고 싶을 때는 학습된 생성자(Generator)를 사용한다.

그림 1– Generative Adversarial Networks(GAN) architecture

그림 2 – GAN의 학습 과정(원래 데이터의 분포를 근사한다.)

 

텐서플로우(TensorFlow)를 이용한 MNIST 데이터 생성

이제 TensorFlow를 이용해서 MNIST 데이터의 분포를 학습하는 GAN 모델을 구현해보자.

경축! 아무것도 안하여 에스천사게임즈가 새로운 모습으로 재오픈 하였습니다.
어린이용이며, 설치가 필요없는 브라우저 게임입니다.
https://s1004games.com

  # -*- coding: utf-8 -*-
  """
  GAN(Generative Adversarial Networks)을 이용한 MNIST 데이터 생성
   
  Reference : https://github.com/TengdaHan/GAN-TensorFlow
   
  Author : solaris33
  Project URL : http://solarisailab.com/archives/2482
  """
   
  import tensorflow as tf
  import numpy as np
  import matplotlib.pyplot as plt
  import matplotlib.gridspec as gridspec
  import os
   
  # MNIST 데이터를 불러옵니다.
  from tensorflow.examples.tutorials.mnist import input_data
  mnist = input_data.read_data_sets("./mnist/data/", one_hot=True)
   
  # 생성된 MNIST 이미지를 8x8 Grid로 보여주는 plot 함수를 정의합니다.
  def plot(samples):
  fig = plt.figure(figsize=(8, 8))
  gs = gridspec.GridSpec(8, 8)
  gs.update(wspace=0.05, hspace=0.05)
   
  for i, sample in enumerate(samples):
  ax = plt.subplot(gs[i])
  plt.axis('off')
  plt.imshow(sample.reshape(28, 28))
  return fig
   
  # 설정값들을 선언합니다.
  num_epoch = 100000
  batch_size = 64
  num_input = 28 * 28
  num_latent_variable = 100
  num_hidden = 128
  learning_rate = 0.001
   
  # 플레이스 홀더를 선언합니다.
  X = tf.placeholder(tf.float32, [None, num_input]) # 인풋 이미지
  z = tf.placeholder(tf.float32, [None, num_latent_variable]) # 인풋 Latent Variable
   
  # Generator 변수들 설정
  # 100 -> 128 -> 784
  with tf.variable_scope('generator'):
  # 히든 레이어 파라미터
  G_W1 = tf.Variable(tf.random_normal(shape=[num_latent_variable, num_hidden], stddev=5e-2))
  G_b1 = tf.Variable(tf.constant(0.1, shape=[num_hidden]))
  # 아웃풋 레이어 파라미터
  G_W2 = tf.Variable(tf.random_normal(shape=[num_hidden, num_input], stddev=5e-2))
  G_b2 = tf.Variable(tf.constant(0.1, shape=[num_input]))
   
  # Discriminator 변수들 설정
  # 784 -> 128 -> 1
  with tf.variable_scope('discriminator'):
  # 히든 레이어 파라미터
  D_W1 = tf.Variable(tf.random_normal(shape=[num_input, num_hidden], stddev=5e-2))
  D_b1 = tf.Variable(tf.constant(0.1, shape=[num_hidden]))
  # 아웃풋 레이어 파라미터
  D_W2 = tf.Variable(tf.random_normal(shape=[num_hidden, 1], stddev=5e-2))
  D_b2 = tf.Variable(tf.constant(0.1, shape=[1]))
   
  # Generator를 생성하는 함수를 정의합니다.
  # Inputs:
  # X : 인풋 Latent Variable
  # Output:
  # generated_mnist_image : 생성된 MNIST 이미지
  def build_generator(X):
  hidden_layer = tf.nn.relu((tf.matmul(X, G_W1) + G_b1))
  output_layer = tf.matmul(hidden_layer, G_W2) + G_b2
  generated_mnist_image = tf.nn.sigmoid(output_layer)
   
  return generated_mnist_image
   
  # Discriminator를 생성하는 함수를 정의합니다.
  # Inputs:
  # X : 인풋 이미지
  # Output:
  # predicted_value : Discriminator가 판단한 True(1) or Fake(0)
  # logits : sigmoid를 씌우기전의 출력값
  def build_discriminator(X):
  hidden_layer = tf.nn.relu((tf.matmul(X, D_W1) + D_b1))
  logits = tf.matmul(hidden_layer, D_W2) + D_b2
  predicted_value = tf.nn.sigmoid(logits)
   
  return predicted_value, logits
   
  # 생성자(Generator)를 선언합니다.
  G = build_generator(z)
   
  # 구분자(Discriminator)를 선언합니다.
  D_real, D_real_logits = build_discriminator(X) # D(x)
  D_fake, D_fake_logits = build_discriminator(G) # D(G(z))
   
  # Discriminator의 손실 함수를 정의합니다.
  d_loss_real = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=D_real_logits, labels=tf.ones_like(D_real_logits))) # log(D(x))
  d_loss_fake = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=D_fake_logits, labels=tf.zeros_like(D_fake_logits))) # log(1-D(G(z)))
  d_loss = d_loss_real + d_loss_fake # log(D(x)) + log(1-D(G(z)))
   
  # Generator의 손실 함수를 정의합니다.
  g_loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=D_fake_logits, labels=tf.ones_like(D_fake_logits))) # log(D(G(z))
   
  # 전체 파라미터를 Discriminator와 관련된 파라미터와 Generator와 관련된 파라미터로 나눕니다.
  tvar = tf.trainable_variables()
  dvar = [var for var in tvar if 'discriminator' in var.name]
  gvar = [var for var in tvar if 'generator' in var.name]
   
  # Discriminator와 Generator의 Optimizer를 정의합니다.
  d_train_step = tf.train.AdamOptimizer(learning_rate).minimize(d_loss, var_list=dvar)
  g_train_step = tf.train.AdamOptimizer(learning_rate).minimize(g_loss, var_list=gvar)
   
  # 생성된 이미지들을 저장할 generated_outputs 폴더를 생성합니다.
  num_img = 0
  if not os.path.exists('generated_output/'):
  os.makedirs('generated_output/')
   
  with tf.Session() as sess:
  # 변수들에 초기값을 할당합니다.
  sess.run(tf.global_variables_initializer())
   
  # num_epoch 횟수만큼 최적화를 수행합니다.
  for i in range(num_epoch):
  # MNIST 이미지를 batch_size만큼 불러옵니다.
  batch_X, _ = mnist.train.next_batch(batch_size)
  # Latent Variable의 인풋으로 사용할 noise를 Uniform Distribution에서 batch_size만큼 샘플링합니다.
  batch_noise = np.random.uniform(-1., 1., [batch_size, 100])
   
  # 500번 반복할때마다 생성된 이미지를 저장합니다.
  if i % 500 == 0:
  samples = sess.run(G, feed_dict={z: np.random.uniform(-1., 1., [64, 100])})
  fig = plot(samples)
  plt.savefig('generated_output/%s.png' % str(num_img).zfill(3), bbox_inches='tight')
  num_img += 1
  plt.close(fig)
   
  # Discriminator 최적화를 수행하고 Discriminator의 손실함수를 return합니다.
  _, d_loss_print = sess.run([d_train_step, d_loss], feed_dict={X: batch_X, z: batch_noise})
   
  # Generator 최적화를 수행하고 Generator 손실함수를 return합니다.
  _, g_loss_print = sess.run([g_train_step, g_loss], feed_dict={z: batch_noise})
   
  # 100번 반복할때마다 Discriminator의 손실함수와 Generator 손실함수를 출력합니다.
  if i % 100 == 0:
  print('반복(Epoch): %d, Generator 손실함수(g_loss): %f, Discriminator 손실함수(d_loss): %f' % (i, g_loss_print, d_loss_print))
view rawmnist_gan.py hosted with ❤ by GitHub

 

학습이 끝나면 아래와 같이 GAN 모델이 그럴듯한 MNIST 데이터를 생성해낸 모습을 볼 수 있다.

그림 3 – GAN이 생성해낸 MNIST 이미지

 

References

[1] https://github.com/TengdaHan/GAN-TensorFlow

 

[출처] http://solarisailab.com/archives/2482

 

 

본 웹사이트는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
번호 제목 글쓴이 날짜 조회 수
공지 오라클 기본 샘플 데이터베이스 졸리운_곰 2014.01.02 86675
공지 [SQL컨셉] 서적 "SQL컨셉"의 샘플 데이타 베이스 SAMPLE DATABASE of ORACLE 가을의 곰을... 2013.02.10 79031
공지 [G_SQL] Sample Database 가을의 곰을... 2012.05.20 95791
644 Docker에서 SQL Server 컨테이너 이미지 구성 file 졸리운_곰 2020.01.23 1555
643 MSSQL 설치형 한글 환경으로 변경 file 졸리운_곰 2020.01.23 2890
642 FastText, 실전 사용하기 file 졸리운_곰 2020.01.12 1097
641 Generative Models Part 2: ImprovedGAN,InfoGAN,EBGAN file 졸리운_곰 2020.01.09 1202
640 Generative Models Part 1: VAE,GAN,DCGAN file 졸리운_곰 2020.01.09 1161
639 VAE & GAN 간단 비교 file 졸리운_곰 2020.01.09 1104
638 구글 Colab을 이용한 BERT-Base Model 학습하기 file 졸리운_곰 2020.01.08 1079
637 BERT 톺아보기 file 졸리운_곰 2020.01.08 1162
636 BERT 한국어버전(korquad) training 및 evaluating 해보기 file 졸리운_곰 2020.01.08 1001
635 딥 러닝 용어 - batch, iteration, epoch 졸리운_곰 2020.01.08 1071
634 tensorflow 로 mnist 흉내내는 GAN 만들기 file 졸리운_곰 2020.01.08 851
» 텐서플로우(TensorFlow)를 이용해서 MNIST 데이터를 생성하는 GAN(Generative Adversarial Networks) 생성 모델(Generative Model) 구현해보기 – GAN 예제 file 졸리운_곰 2020.01.08 981
632 Tensorflow로 50줄짜리 Original GAN Code 구현하기 졸리운_곰 2020.01.08 1194
631 Inductive bias란? 졸리운_곰 2020.01.05 936
630 형태소 분석기를 이용한 Bert-Multilingual Model 기반 Korquad 결과의 성능 개선 file 졸리운_곰 2020.01.05 1234
629 Bert-Multilingual model을 이용해 KorQuAD 수행해보기 Part 2 제출 file 졸리운_곰 2020.01.05 1182
628 Bert-Multilingual model을 이용해 KorQuAD 수행해보기 Part 1 훈련 및 평가 file 졸리운_곰 2020.01.05 1068
627 [기계독해][MRC] R-NET: MACHINE READING COMPREHENSION WITH SELF-MATCHING NETWORKS file 졸리운_곰 2020.01.05 1166
626 한국어 뉴스 데이터로 딥러닝 시작하기- 6. doc2vec으로 문사 유사도 측정하기 file 졸리운_곰 2020.01.04 1749
625 한국어 뉴스 데이터로 딥러닝 시작하기 - 5. 한국어 word2vec 데모 사이트 만들기 file 졸리운_곰 2020.01.04 961
대표 김성준 주소 : 경기 용인 분당수지 U타워 등록번호 : 142-07-27414
통신판매업 신고 : 제2012-용인수지-0185호 출판업 신고 : 수지구청 제 123호 개인정보보호최고책임자 : 김성준 sjkim70@stechstar.com
대표전화 : 010-4589-2193 [fax] 02-6280-1294 COPYRIGHT(C) stechstar.com ALL RIGHTS RESERVED