-
Notifications
You must be signed in to change notification settings - Fork 0
/
0523_GAN.py
159 lines (126 loc) · 6.05 KB
/
0523_GAN.py
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# -*- coding: utf-8 -*-
"""0523_GAN.ipynb
Automatically generated by Colaboratory.
Original file is located at
https://colab.research.google.com/drive/1Cn00f35VKj6VsBgryIEn7lpySChf45_z
"""
import datetime
from IPython.display import Image
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=0.02))
G_b1 = tf.Variable(tf.constant(0.1, shape=[num_hidden]))
# 아웃풋 레이어 파라미터
G_W2 = tf.Variable(tf.random_normal(shape=[num_hidden, num_input], stddev=0.02))
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=0.02))
D_b1 = tf.Variable(tf.constant(0.1, shape=[num_hidden]))
# 아웃풋 레이어 파라미터
D_W2 = tf.Variable(tf.random_normal(shape=[num_hidden, 1], stddev=0.02))
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/')
start_time = datetime.datetime.now()
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})
end_time= datetime.datetime.now()
learning_time = end_time - start_time
print('훈련시간: %d 마이크로초' % learning_time.microseconds)
print('훈련시간: %d 초' % learning_time.seconds)
Image('generated_output/000.png')
Image('generated_output/009.png')
Image('generated_output/099.png')
Image('generated_output/199.png')