์ซ์ ์์ฑ ์ธ๊ณต์ง๋ฅ ์๋ฆฌ
์์ฑ ์ ๊ฒฝ๋ง ์ค GAN์ ์ด์ฉํจ.
GAN (Generative Adversarial Network)
- ์ ๋์ ์์ฑ ์ ๊ฒฝ๋ง.
2๊ฐ์ ์ ๊ฒฝ๋ง์ผ๋ก ์ด๋ฃจ์ด์ ธ ์์. ํ๋ณ์ ์ ๊ฒฝ๋ง๊ณผ ์์ฑ์ ์ ๊ฒฝ๋ง.
- ์์ฑ์๋ ์ง์ง๊ฐ์ ๊ฐ์ง๋ฅผ ์์ฑํจ.
- ํ๋ณ์๋ ์ง์ง๊ทธ๋ฆผ๊ณผ ์์ฑ์๊ฐ ๋ง๋ ๊ฐ์ง ๊ทธ๋ฆผ์ ๊ตฌ๋ณ ๊ฐ๋ฅ.
๋ ์ ๊ฒฝ๋ง์ ๋ชฉํ๊ฐ ์์.
- ์์ฑ์ : ํ๋ณ์๊ฐ ์์ ์ด ๋ง๋ ๊ทธ๋ฆผ์ ์ง์ง์ฒ๋ผ ์๊ฐํ ์ ๋์ ๊ทธ๋ฆผ์ ๊ทธ๋ฆผ.
- ํ๋ณ์ : ์์ฑ์๊ฐ ๋ง๋ ๊ทธ๋ฆผ์ ์ง์ง์ธ์ง ๊ฐ์ง์ธ์ง ์ ๋ถ ๊ตฌ๋ณํด์ผํจ.
์ด์ ๋ ์ ๊ฒฝ๋ง์ ์๋ก ์ด๊ธฐ๊ธฐ ์ํด ํ์ต์ ์์ํจ.
์ด๋ ๊ฒ ๋ ๊ฐ์ ์ ๊ฒฝ๋ง์ ์ฌ์ฉํ์ฌ ์ด๋ฌํ ์๋ฆฌ๋ก ์์ฑํด ๋ด๋ ๊ธฐ๋ฒ์ด GAN(์ ๋์ ์์ฑ ์ ๊ฒฝ๋ง)์.
๊ฐ๋ฐ ํ๊ฒฝ ์ธํ
from keras.models import Model, Sequential
from keras.layers import Dense, Input
from keras.layers.advanced_activations import LeakyReLU
from keras.optimizers import Adam
from keras.datasets import mnist
from tqdm import tqdm
import numpy
import matplotlib.pyplot as plt
from keras.models import Model, Sequential
๋ชจ๋ธ ๋๊ตฌ์ค์ ๋ชจ๋ธ๊ณผ ์ํ์ ๋ชจ๋ธํจ์๋ฅผ ๋ถ๋ฌ์ด.GAN์ ๋๊ฐ์ ์ ๊ฒฝ๋ง์ด ํ์ํ๊ณ , ์ด ๋ ์ ๊ฒฝ๋ง์ ๋ชจ๋ ์ํ์ ํํ์ด๊ธฐ์ ํ์ํจ.
from keras.layers.advanced_activations import LeakyReLU
๋ ๋ฃจํจ์์ Leaky๋ ๋ฃจํจ์์ ์ฐจ์ด์
- ๋ ๋ฃจํจ์ : 0๋ณด๋ค ์์ ๊ฐ ๋ค์ด์ค๋ฉด 0์ ๋ฐํ.
- Leaky๋ ๋ฃจ : 0๋ณด๋ค ์์ ๊ฐ ๋ค์ด์ค๋ฉด ์์์ ๊ฐ ๋ฐํ.
from keras.optimizers import Adam
ํ์ตํ ๋ชจ๋ธ์ ์ค์ฐจ ์ค์ด๊ธฐ ์ํด ๊ฒฝ์ฌํ๊ฐ๋ฒ ์ฌ์ฉ. ์ด๋ ์ฌ์ฉํ๋ ์ตํฐ๋ง์ด์ ๋ ์๋ด ์ตํฐ๋ง์ด์ .
๋ฐ์ดํฐ ๋ถ๋ฌ์ค๊ธฐ.
(x_train, y_train), (x_test, y_test) = mnist.load_data()
print(len(x_train))
print(len(y_train))
print(len(x_test))
print(len(y_test))
x_train = (x_train.astype(numpy.float32) - 127.5)/127.5
mnist_data = x_train.reshape(60000,784)
print(mnist_data.shape)
len(mnist_data)
mnist์ ๋ฐ์ดํฐ์๋ ํ๋ จ์ฉ๋ฐ์ดํฐ์ ๊ฒ์ฆ์ฉ ๋ฐ์ดํฐ๊ฐ ์๊ณ ๊ฐ 6๋ง๊ฐ, 1๋ง๊ฐ๊ฐ ์์.
ํ๋ จ์ฉ๋ฐ์ดํฐ 6๋ง๊ฐ๋ฅผ data๋ก ์ฌ์ฉํ ๊ฒ์.
x_train = (x_train.astype(numpy.float32) - 127.5)/127.5
์ผ๋จ ๋ฐ์ดํฐ์ ์ ๊ทํ๋ฅผ ์ํด -1 ~ 1 ์ฌ์ด์ ๊ฐ์ผ๋ก ๋ง๋ค์ด์ค. mnist ๋ฐ์ดํฐ์ ์ ๊ทธ๋ฆผ์ 0~ 255๊น์ง์ ์ซ์๋ก ์ด๋ฃจ์ด์ ธ ์์ด์ 127.5๋ฅผ ๋นผ๊ณ 127.5๋ก ๋๋์ด์ฃผ๋ฉด 0์ -1๋ก, 255๋ 1๋ก ๋ง๋ค์ด์ค. ์ ๊ทํ๋
mnist_data = x_train.reshape(60000,784)
mnist๋ฐ์ดํฐ๋ 28* 28๊ฐ์ ํฝ์ ๋ฐ์ดํฐ๋ก ์ด๋ฃจ์ด์ ธ ์์. ๊ทธ๋์ ํ์ค๋ก ๋ฃ๊ธฐ์ํด 784 * 1๋ก ์ค์ ํจ.
์์ฑ์ ์ ๊ฒฝ๋ง ์ ์
def create_generator():
generator = Sequential()
generator.add(Dense(units=256, input_dim=100))
generator.add(LeakyReLU(0.2))
generator.add(Dense(units=512))
generator.add(LeakyReLU(0.2))
generator.add(Dense(units=784, activation='tanh'))
return generator
g= create_generator()
g.summary()
input_dim ์ ์ ๋ ฅ ํํ. ์ํ์ ๋ชจ๋ธ์ ์ฌ์ฉํจ.(์์ฐจ์ ์ผ๋ก ๋ ์ด์ด๋ฅผ ์์)
generator.add(Dense(units=256, input_dim=100))
input_dim ์ ๋ ฅ๋ด๋ฐ์ ์๋ฅผ 100๊ฐ๋ก ์ค์ . ์ ๊ฒฝ๋ง์ ์ฒซ๋ฒ์งธ ์ธต์ 256๊ฐ์ ๋ ธ๋๋ก ์ค์ . 100์ ์ค์ ํด์ 100๊ฐ์ ํฝ์ ๊ฐ์ด ๋๋คํ ๊ฐ์ ๊ฐ์ง.(๋ ธ์ด์ฆ๊ฐ)
generator.add(LeakyReLU(0.2))
ํ์ฑํํจ์๋ฅผ leakyRelu๋ก ์ค์ . ์์๊ฐ์ ํน์ ํ ๊ธฐ์ธ๊ธฐ๋ฅผ ๋ณด์ด๋๋ฐ, ์ด ๊ธฐ์ธ๊ธฐ์ ๊ฐ์ 0.2๋ก ์ค์ ํ๋๊ฒ.
tanh : ํ์ดํผ๋ณผ๋ฆญํ์ ํธ ํจ์. ๋ง์ง๋ง ์ถ๋ ฅ์ธต์ ํ์ฌ mnist ๋ฐ์ดํฐ ๋ชจ์ต์ด 1*784๋ก ๋์ด์์ด์ 784๊ฐ์ ํฝ์ ์ ๋์ดํ ๋ชจ์ต์ผ๋ก ๋ํ๋ด์ผํ๊ธฐ์ 784๋ก ์ค์ .
ํ๋ณ์ ์ ๊ฒฝ๋ง ์ ์
def create_discriminator():
discriminator = Sequential()
discriminator.add(Dense(units=512, input_dim=784))
discriminator.add(LeakyReLU(0.2))
discriminator.add(Dense(units=256))
discriminator.add(LeakyReLU(0.2))
discriminator.add(Dense(units=1, activation='sigmoid'))
discriminator.compile(loss = 'binary_crossentropy', optimizer = Adam(lr=0.002, beta_1=0.5))
return discriminator
d = create_discriminator()
d.summary()
์ ๋ ฅ๋ด๋ฐ์ ์, input_dim์ ์์ฑ์๊ฐ ๋ง๋ ๊ธ์จ๊ฐ 784ํฝ์ ๋ก ์ด๋ฃจ์ด์ ธ์๊ธฐ์ ์ ๋ ฅ๊ฐ์ 784๋ก ์ค์ .
์ดค์ข ์ถ๋ ฅ ๋ ธ๋๋ 1๊ฐ. ์ง์ง๊ธ์จ๋ฉด 1, ์์ฑ์๊ฐ ๋ง๋ ๊ฐ์ง๊ธ์จ๋ฉด 0.
discriminator.compile(loss = 'binary_crossentropy', optimizer = Adam(lr=0.002, beta_1=0.5))
๋ ์ค ํ๋ ๊ณ ๋ฅด๋ ๋ฌธ์ ์ด๋ ์ค์ฐจ๊ฐ(loss)์ ์ดํญ๊ต์ฐจ ์ํธ๋กํผ ์ฌ์ฉ. ํ์ต์๋(ํ์ต๋ฅ )์ธ lr ์ 0.002๋ก, ๋ฒ ํ ์ต์ ํ ๊ฐ์ 0.5๋ก ์ค์ .
(์ฌ๊ธฐ์ ํ์ต์๋, ํ์ต๋ฅ ์ ๊ฒฝ์ฌํ๊ฐ๋ฒ์์ ์ค์ฐจ๊ฐ ์์์ง๋ ๋ฐฉํฅ์ผ๋ก ๊ฐ์ค์น์ ๊ฐ์ ์ด๋ํ ๋, ํ๋ฒ์ ์ผ๋งํผ์ ํฌ๊ธฐ๋ก ์ด๋ํ ๊ฒ์ธ์ง๋ฅผ ๋ปํจ.)
GAN ์์ฑ ํจ์ ์ ์
์์ฑ์ ์ ๊ฒฝ๋ง๊ณผ ํ๋ณ์ ์ ๊ฒฝ๋ง์ ์ ์ํ์ผ๋ GAN์ ๋ง๋ฌ.
def create_gan(discriminator, generator) :
discriminator.trainable = False
gan_input = Input(shape = (100,))
x = generator(gan_input)
gan_output = discriminator(x)
gan = Model(inputs = gan_input, outputs = gan_output)
gan.compile(loss='binary_crossentropy', optimizer = 'adam')
return gan
gan = create_gan(d,g)
gan.summary()
create_gan ํจ์๋ ์ธ์๊ฐ ๋๊ฐ, ํ๋ณ์์ ์์ฑ์๋ฅผ ์ ๋ ฅ๋ฐ์.
discriminator.trainable = False ์ด๊ฑด ํ๋ณ์๊ฐ ํ์ตํ์ง ๋ชปํ๊ฒ ๋ง๋ ์ฝ๋์.
input์ ์ ๋ ฅํ ๋ฐ์ดํฐ์ ๋ชจ์ต์ ์ ํ๋ ์ฝ๋์. ์ฝค๋ง , ๋ค์ ๋น ๊ณณ์ ์๋์ผ๋ก ์ค์ ์ด ๋ฐ์ดํฐ์ ๊ฐ์๋ฅผ ์๋์ผ๋ก ๋ฃ์ด์ค. ์๊น 60000๊ฐ ์ค์ ํ์ผ๋ 6๋ง์ ์๋์ผ๋ก ๋ฃ์ด์ค.
์ ๋ ฅ๊ฐ์ ์์ฑ์ ์ ๊ฒฝ๋ง์ด ๋ง๋ ๊ทธ๋ฆผ, ์ถ๋ ฅ๊ฐ์ ํ๋ณ์ ์ ๊ฒฝ๋ง์ด ํ๋จํ ๊ฒฐ๊ณผ์.
- ์ ๋ ฅ์ธต์ ๋ ธ์ด์ฆ๊ฐ์ด 100๊ฐ์ ํฝ์ ๊ฐ์ด ๋ค์ด๊ฐ.
- ๋๋ฒ์งธ ๋ ์ด์ด๋ ์์ฑ์ ์ ๊ฒฝ๋ง์์ ์ถ๋ ฅ๋ ๊ฐ์ ๋ชจ์ต
- ์ธ๋ฒ์งธ ์ถ๋ ฅ์ธต์ ๊ฐ์ง์ธ์ง ์ง์ง์ธ์ง ํ๋จํ ๊ฒฐ๊ณผ.
๊ฒฐ๊ณผ ํ์ธ ํจ์ ์ ์
๋ง๋ ์ ๊ฒฝ๋ง๋ค์ ํ๋ จ์ํค๊ณ ์ ํ๋๋ฅผ ํ์ธํด์ผํจ.
def plot_generated_images(generator) :
noise = numpy.random.normal(loc=0, scale=1, size=[100,100])
generated_images = generator.predict(noise)
generated_images = generated_images.reshape(100,28,28)
plt.figure(figsize=(10,10))
for i in range(generated_images.shape[0]) :
plt.subplot(10,10, i+1)
plt.imshow(generated_images[i], interpolation='nearest')
plt.axis('off')
plt.tight_layout()
def plot_generated_images(generator) ํ๋ผ๋ฏธํฐ๋ ์ด๋ค ์์ฑ์๋ก ๊ทธ๋ฆด์ง ์ค์ .
noise = numpy.random.normal(loc=0, scale=1, size=[100,100]) ์์ฑ์์ ๋ฃ์ด์ค ๋ ธ์ด์ฆ ๊ฐ.
๊ท ์ผํ ๊ฐ์ ์์ฑํ๋๋ก ์ ๊ท ๋ถํฌ ํจ์ normal์ฌ์ฉ.
์ฒซ๋ฒ์งธ ์ธ์๊ฐ์ ํ๊ท ์ด 0, ๋๋ฒ์งธ ์ธ์๊ฐ 1์ ํ๊ท ์์ ์ผ๋งํผ ๋จ์ด์ ธ ์๋์ง (-1 ~ 1 ์ฌ์ด์ ๊ฐ), ๋ง์ง๋ง ์ธ์๊ฐ์ ๋ ธ์ด์ฆ 100๊ฐ ์์ฑํ๊ณ ๊ฐ ๋ ธ์ด์ฆ๋ ์ซ์ 100๊ฐ์ฉ์ผ๋ก ๊ตฌ์ฑ๋์ด์๋ค๋ ๋ป.
์ฆ, ํจ์๋ฅผ ํธ์ถํ ๋๋ง๋ค 100๊ฐ์ ๊ทธ๋ฆผ์ ๊ทธ๋ ค๋ฌ๋ผ๋ ๋ช ๋ น์ด๋ค.
generated_images = generator.predict(noise) generated๋ ์ ๊ฒฝ๋ง ๋ชจ๋ธ์ด๊ธฐ์ ์์์ ๋ง๋ ๋ ธ์ด์ฆ๊ฐ์ ์ ๊ฒฝ๋ง์ ๋ฃ์ด์ ์์ธกํ๋ผ๋ ๋ช ๋ น.
generated_images = generated_images.reshape(100,28,28) ๊ทธ๋ฆผ์ ํํ๊ฐ 1 * 784์ ํํ์ด๊ธฐ์ 28 * 28 ์ฌ์ด์ฆ๋ก ๋ฐ๊ฟ.
plt.figure(figsize=(10,10)) ๊ทธ๋ฆผ์ ํฌ๊ธฐ๋ 10 * 10์ผ๋ก ์ค์ .
for i in range(generated_images.shpae[0]) 100๊ฐ์ ๊ทธ๋ฆผ์ด๋ 100๋ฒ ๋ฐ๋ณต.
plt.subplot(10,10, i+1) ์์น๋ฅผ ์ง์ ํด์ฃผ๊ณ ,
plt.imshow(generated_images[i], interpolation='nearest') ์ด๋ฏธ์ง๋ฅผ ์ถ๋ ฅํจ. interpolationํจ์๋ ๊ทธ๋ฆผ์ ์ถ๋ ฅํ ๋, ๊ฐ ํฝ์ ์ ์ด๋ป๊ฒ ๋ํ๋ผ์ง ๊ฒฐ์ ํจ. i๋ฒ์งธ ๊ทธ๋ฆผ์ ์์น๋ generated_images[i]์ ๋ฃ์
plt.axis('off') ๊ทธ๋ฆผ ์ด๋ฆ์ ๋ฃ์ง ์์. plt.tight_layout() ๊ทธ๋ฆผ ํ๋ฉด์ ์ถ๋ ฅ.
GAN ํ๋ จ
batch_size = 128
epochs = 5000
for e in tqdm(range(epochs)) :
noise = numpy.random.normal(0,1,[batch_size, 100])
generated_images = g.predict(noise)
image_batch = mnist_data[numpy.random.randint(low=0, high= mnist_data.shape[0], size = batch_size)]
x = numpy.concatenate([image_batch, generated_images])
y_dis = numpy.zeros( 2* batch_size)
y_dis[:batch_size] = 1
d.trainable = True
d.train_on_batch(x, y_dis)
noise = numpy.random.normal(0,1, [batch_size, 100])
y_gen = numpy.ones(batch_size)
d.trainable = False
gan.train_on_batch(noise, y_gen)
if e==0 or e % 1000 == 0 :
plot_generated_images(g)
batch_size = 128๋ก ์ค์ . epochs = ์ด 5000๋ฒ ๋๋๋ก ์ค์ .
tqdm()์ ์งํ๊ณผ์ ์ ์๊ฐํํ์ฌ ๋ณด์ฌ์ฃผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ. ์งํํ์๋ฐ์ด๋ค.
noise = numpy.random.normal(0,1,[batch_size, 100])
์์ฑ์์๊ฒ ์ค ๋ ธ์ด์ฆ๊ฐ ์ ๊ท๋ถํฌํจ์์ฌ์ฉํ์ฌ batch_size๋งํผ์ ๊ฐ์๋งํผ ์์ฑ. ์์ฑ๋ ๊ฐ ๋ฐ์ดํฐ๋ ์ซ์ 100๊ฐ๋ก ๊ตฌ์ฑ๋์ด ์๋ค๋ ์๋ฏธ.
generated_images = g.predict(noise)
์์ฑ์ ์ ๊ฒฝ๋ง ๋ชจ๋ธ์ ๋ ธ์ด์ฆ๋ฅผ ์ ๋ ฅํ์ฌ ๊ทธ๋ฆผ์ ๊ทธ๋ฆฌ๋๋ก ๋ง๋๋ ๋ช ๋ น์ด.(ํ์ต)
image_batch = mnist_data[numpy.random.randint(low=0, high= mnist_data.shape[0], size = batch_size)]
mnist ๋ฐ์ดํฐ์ ์ด ํ์ฌ 6๋ง๊ฐ๋ก ์ค์ ํด ๋์๋๋ฐ ์ด์ค์์ batch_size ๊ฐ์(128๊ฐ)๋ง ๋๋ค์ผ๋ก ๋ฝ์์ ๊ฐ์ ธ์ด. ํ์ตํ ๋ ๋ง๋ค ๋ค์ํ ๋ชจ์์ ์๊ธ์จ๋ฅผ ํ์ตํ ์ ์๊ฒ ์ค์ ํ ๊ฒ. ์ฒซ๋ฒ์งธ(low=0)๋ถํฐ mnist_data.shape[0](mnist๋ฐ์ดํฐ์ ๊ฐ์) ์์ batch_size๋งํผ๋ง ๋๋ค์ผ๋ก ๊ณ ๋ฆ.
x = numpy.concatenate([image_batch, generated_images])
numpy๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ concatenate๋ ํฉ์น๋ ํจ์์ ์ง์ง๊ทธ๋ฆผ๊ณผ ๊ฐ์ง๊ทธ๋ฆผ์ ํ์ค๋ก ๋ถ๊ฒ ๋ง๋ค์ด์ x์ ๋ฃ์. ๊ฐ ๊ทธ๋ฆผ์ 128๊ฐ๋งํผ ์์ผ๋ x๋ ์ด 256๊ฐ์ ๋ฐ์ดํฐ๋ก ์ด๋ฃจ์ด์ ธ์์. ๊ฐ ๋ฐ์ดํฐ์๋ -1 ~ 1 ์ฌ์ด์ ๊ฐ์ด 784๊ฐ์ฉ ๋ค์ด์์.
y_dis = numpy.zeros( 2* batch_size)๋ก 256๊ฐ์ ๋ฐ์ดํฐ ๊ฐ์ 0์ผ๋ก ๋ง๋ค์ด์ฃผ๊ณ ,
y_dis[:batch_size] = 1๋ก ์ด์ค ์ฒซ๋ฒ์งธ๋ก ๋ค์ด์จ ๋ฐ์ดํฐ 128๊ฐ๋ง ๊ฐ์ 1๋ก ์ค์ ํด์ค.
์ด์ ํ๋ณ์๋ ์ฒ์๋์ค๋ 128๊ฐ์ ๋ฐ์ดํฐ๋ ์ง์ง, ๋์ค์ ๋ค์ด์จ 128๊ฐ๋ ๊ฐ์ง๋ผ๋ ๊ฒ์ ์ ์ ์์. (distinguish = ๊ตฌ๋ณํ๋ค)
d.trainable = True ํ๋ณ์ ์ ๊ฒฝ๋ง์ด ํ์ตํ ์ ์๋๋ก(True) ์ค์ .
d.train_on_batch(x, y_dis) ์ ๊ฒฝ๋ง์ ํ์ต์ํด.
์ ๋ ฅ๋ฐ์ดํฐ๊ฐ์ x, ์ถ๋ ฅ๋ฐ์ดํฐ๊ฐ์ y_dis๋ก ์ค์ . ์ด์ ์ ๋ ฅ๋ฐ์ดํฐ๋ฅผ ์ฃผ๋ฉด ํ๋ณ์๋ฅผ ํตํด ๋์จ ์ถ๋ ฅ๊ฐ๊ณผ ์ ๋ต ๋ฐ์ดํฐ์ ๊ฒฐ๊ณผ๊ฐ์ ๋น๊ตํ์ฌ ์ค์ฐจ๋ฅผ ์ค์ผ ์ ์์.
ํ๋ณ์๋ ํ์ต์ ์์ผฐ์ผ๋, ์ด์ ์์ฑ์๋ฅผ ํ์ต์ํด.
noise = numpy.random.normal(0,1, [batch_size, 100]) ์๋ก์ด ๋ ธ์ด์ฆ๊ฐ ์์ฑ.
y_gen = numpy.ones(batch_size) gan์ ๋ฃ์ด์ค ๊ฐ์ ๋ชจ๋ 1๋ก ์ค์ .
๊ฐ์ง๊ทธ๋ฆผ๊ณผ ์ง์ง๊ทธ๋ฆผ ๋ชจ๋ ์ง์ง๋ก ์คํดํ๋๋ก ๋ง๋ฌ.
d.trainable = False ํ๋ณ์์ ํ์ต์ ๊ทธ๋ง์ํด. ํ์ตํ์ง ์๊ณ ํ๋จ๋ง ํจ.
gan.train_on_batch(noise, y_gen) gan์ ๋ ธ์ด์ฆ๊ฐ์ ์ ๋ ฅ๋ฐ์ดํฐ๋ก ๋ฃ๊ณ ์ถ๋ ฅ๊ฐ์ ๋ชจ๋ ์ง์ง๋ผ๊ณ ํ๊ณ ๋ฃ์ด์ ํ์ต์ํด. ์ด๋ฌ๋ฉด GAN์ ํ๋ณ์๊ฐ ์ง์ง ๊ทธ๋ฆผ์ด๋ผ๊ณ ์๊ฐํ ์ ์๊ฒ ์์ฑ์๋ฅผ ํ๋ จ์ํด.
ํ๋ณ์ ์ ๊ฒฝ๋ง์ ๊ฑฐ์ณ์ ๋์จ ๊ฐ๊ณผ y_gen๊ณผ ๋น๊ตํ๋ฉด์ ํ๋ณ๊ฒฐ๊ณผ๊ฐ 1์ด ๋์ฌ ๋ ๊น์ง ์์ฑ์๋ฅผ ํ์ต์ํด.
if e==0 or e % 1000 == 0 : plot_generated_images(g) ์ฒซ๋ฒ์งธ ์ํฌํฌ์ ๊ฐ 1000๋จ์์ ์ํฌํฌ์ผ๋ ์์ฑ์๊ฐ ๋ง๋ ๊ทธ๋ฆผ์ ์ถ๋ ฅํจ.
#ํ๊ธฐ
์๊ฐ๋ณด๋ค ์์ฑ๋ ์ซ์๊ฐ ๊ทธ์ ๊ทธ๋ฐ๊ฒ ๊ฐ๋ค. 6๋ง๊ฐ์ค์ ๋ฐฐ์น์ฌ์ด์ฆ๋ฅผ 128๊ฐ๋ง ์ ํํ์ ๋, ์ฌ๊ธฐ์ ๊น๋ํ ๋ฐ์ดํฐ๋ค์ด ์๊ฑธ๋ฆฌ๋ฉด ๊ฒฐ๊ณผ๊ฐ์ด ์์ข์์ง๋ ๊ฒ ๊ฐ๋ค. ์กฐ๊ธ๋ง ์์ ์ ํ๋ฉด ๊ฒฐ๊ณผ๊ฐ ์ข์ ๊ฒ ๊ฐ๋ค.