본문 바로가기
기계학습/이미지 머신러닝

MNIST 실습 - GAN

by tryotto 2020. 2. 11.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import numpy as np
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
 
mnist = input_data.read_data_sets("./mnist/data/", one_hot=True)
 
 
# 변수 설정 - 입력값
X_real = tf.placeholder(tf.float32, [None, 784])
X_noise = tf.placeholder(tf.float32, [None, 128]) 
 
# 변수 설정 - 생성자
Gen_W1 = tf.Variable(tf.random_normal([128256], stddev=0.01))
Gen_b1 = tf.Variable(tf.zeros([256]))
Gen_W2 = tf.Variable(tf.random_normal([256784], stddev=0.01))
Gen_b2 = tf.Variable(tf.zeros([784]))
 
# 변수 설정 - 구분자
Disc_W1 = tf.Variable(tf.random_normal([784256], stddev=0.01))
Disc_b1 = tf.Variable(tf.zeros([256]))
Disc_W2 = tf.Variable(tf.random_normal([2561], stddev=0.01))
Disc_b2 = tf.Variable(tf.random_normal([1]))
 
 
 
 
# 생성자 함수 : 128 -> 256 -> 784
def generator(noise):
  hidden = tf.nn.relu(tf.matmul(noise, Gen_W1) + Gen_b1)
  output = tf.nn.sigmoid(tf.matmul(hidden, Gen_W2) + Gen_b2)
  return output
 
# 구분자 함수 : 784 -> 256 -> 1
def discriminator(image):
  hidden = tf.nn.relu(tf.matmul(image, Disc_W1) + Disc_b1)
  output = tf.nn.sigmoid(tf.matmul(hidden, Disc_W2) + Disc_b2)
  return output
 
# 노이즈 생성 함수
def make_noise(sample_num, size):
  return np.random.normal(size=(sample_num, size))
 
 
 
 
# 구분자 - 위조 이미지
gen_noise = generator(X_noise)
Disc_fake = discriminator(gen_noise)
 
# 구분자 - 실제 이미지
Disc_real = discriminator(X_real)     
 
 
 
 
 
# 구분자 손실함수 - 실제 이미지 값이 1에 가까울수록, 위조 이미지 값이 0에 가까울수록 좋다
# 그래야지 위조 그림에 대한 분별 확률이 더 커진다
cost_discriminator = tf.reduce_mean(tf.log(Disc_real) + tf.log(1 - Disc_fake))
 
# 생성자 손실함수 - 위조 이미지 값이 1에 가까울수록 좋다
# 그래야지 더 감쪽같은 위조 이미지를 만들 수 있다
cost_generator = tf.reduce_mean(tf.log(Disc_fake))
 
 
 
 
# 구분자 최적화 함수
disc_var_list = [Disc_W1, Disc_b1, Disc_W2, Disc_b2]
optimizer_discriminator = tf.train.AdamOptimizer(0.001).minimize(-cost_discriminator, var_list = disc_var_list)
 
# 생성자 최적화 함수
gen_var_list = [Gen_W1, Gen_b1, Gen_W2, Gen_b2]
optimizer_generator = tf.train.AdamOptimizer(0.001).minimize(-cost_generator, var_list = gen_var_list)
 
 
 
 
import matplotlib.pyplot as plt
 
# 훈련 과정
sess = tf.Session()
start = tf.global_variables_initializer()
sess.run(start)
 
epoch = 5
batch_size = 100
batch_num = int(mnist.train.num_examples/batch_size)
 
for i in range(epoch):
  avg_cost_disc = 0
  avg_cost_gen = 0
 
  for j in range(batch_num):
    batch_X, _ = mnist.train.next_batch(batch_size)
    tmp_noise = make_noise(batch_size, 128)
 
    _, cost_disc = sess.run([optimizer_discriminator, cost_discriminator], feed_dict={X_real: batch_X, X_noise: tmp_noise})
    _, cost_gen = sess.run([optimizer_generator, cost_generator], feed_dict={X_noise: tmp_noise})
 
    avg_cost_disc += cost_disc
    avg_cost_gen += cost_gen
  #  print(" ",cost_disc, "  ", cost_gen)
  print("epoch : ", i+1)
  print("cost discriminator : ", avg_cost_disc/batch_num)
  print("cost generator : ", avg_cost_gen/batch_num)
 
  test_size=10
  test_noise = make_noise(test_size,128)
 
  samples = sess.run(gen_noise, feed_dict={X_noise: test_noise})
    
  for i in range(test_size):
    plt.imshow(np.reshape(samples[i], (2828)))
cs



학습률이 굉장히 안 좋다

운 좋으면 어느정도 학습이 되고,

재수 없으면 아예 중간에 멈춰버린다


drop out 기법이나 CNN 기법을 이용해서 GAN 을 업그레이드 시켜야 할 것 같다

도대체 블로그 글쓴이는 이걸 어떻게 학습했다는건지 모르겠다.

그대로 코드를 복사 붙여넣기 해봐야겠다


-> 실험결과, 블로그 글쓴이 코드도 잘못됐다.

차라리 내 코드의 성능이 더 좋았다.

문법이 어딘가 틀린건지 모르겠다.

아예 1 epoch 가 끝나기도 전에 nan 을 출력해버렸다.


결론은, GAN 은 학습시키기가 정말 어려운 모델이라는 것.

더 공부해봐야겠다

'기계학습 > 이미지 머신러닝' 카테고리의 다른 글

남자 여자 판독기 - CNN 모델  (0) 2020.02.25
MNIST 실습 - CNN 모델  (0) 2020.02.10
MNIST - 일반 딥러닝 모델  (0) 2020.02.09
MNIST - 기본 1 layer 머신러닝  (0) 2020.02.08