In [129]:
%matplotlib inline
In [135]:
from keras.models import Sequential
from keras.layers import Dense, Reshape
from keras.layers.core import Activation, Flatten
from keras.layers.normalization import BatchNormalization
from keras.layers.convolutional import UpSampling2D, Conv2D, MaxPooling2D
from keras.optimizers import SGD, Adam
from keras.datasets import mnist
import numpy as np
from PIL import Image
import argparse
import math
In [131]:
def generator_model():
layers = [
Dense(1024, input_dim=100),
Activation('tanh'),
Dense(7 * 7 * 128),
BatchNormalization(),
Activation('tanh'),
Reshape((7, 7, 128), input_shape=(7 * 7 * 128,)),
UpSampling2D(size=(2, 2)), # 14x14
Conv2D(64, (5, 5), padding='same'),
Activation('tanh'),
UpSampling2D(size=(2, 2)), # 28x28
Conv2D(1, (5, 5), padding='same'),
Activation('tanh')
]
model = Sequential(layers)
return model
In [132]:
gen = generator_model()
gen.summary()
In [133]:
def discriminator_model():
layers = [
Conv2D(64, (5, 5), padding='same', input_shape=(28, 28, 1)),
Activation('tanh'),
MaxPooling2D(pool_size=(2, 2)),
Conv2D(128, (5, 5)),
Activation('tanh'),
MaxPooling2D(pool_size=(2, 2)),
Flatten(),
Dense(1024),
Activation('tanh'),
Dense(1),
Activation('sigmoid')
]
model = Sequential(layers)
return model
In [90]:
dis = discriminator_model()
dis.summary()
In [25]:
def generator_containing_discriminator(generator, discriminator):
model = Sequential()
model.add(generator)
discriminator.trainable = False
model.add(discriminator)
return model
In [28]:
model = generator_containing_discriminator(gen, dis)
model.summary()
In [116]:
def combine_images(generated_images):
num = generated_images.shape[0]
width = int(math.sqrt(num))
height = int(math.ceil(float(num) / width))
shape = generated_images.shape[1:3]
image = np.zeros((height * shape[0], width * shape[1]),
dtype=generated_images.dtype)
for index, img in enumerate(generated_images):
i = int(index / width)
j = index % width
image[i * shape[0]:(i + 1) *shape[0], j * shape[1]:(j + 1) * shape[1]] = img[:, :, 0]
return image
In [113]:
def train(batch_size):
# load MNIST data
(X_train, y_train), (X_test, y_test) = mnist.load_data()
X_train = (X_train.astype(np.float32) - 127.5) / 127.5
X_train = X_train.reshape(X_train.shape[0], X_train.shape[1], X_train.shape[2], 1)
discriminator = discriminator_model()
generator = generator_model()
discriminator_on_generator = generator_containing_discriminator(generator, discriminator)
d_optim = SGD(lr=0.0005, momentum=0.9, nesterov=True)
g_optim = SGD(lr=0.0005, momentum=0.9, nesterov=True)
# generator.compile(loss='binary_crossentropy', optimizer='SGD')
# generator: trainable, discriminator: freeze
discriminator_on_generator.compile(loss='binary_crossentropy', optimizer=g_optim)
# discriminator: trainable
discriminator.trainable = True
discriminator.compile(loss='binary_crossentropy', optimizer=d_optim)
d_loss_history = []
g_loss_history = []
for epoch in range(20):
print('epoch:', epoch)
num_batches = int(X_train.shape[0] / batch_size)
print('number of batches', num_batches)
for index in range(num_batches):
noise = np.array([np.random.uniform(-1, 1, 100) for _ in range(batch_size)])
image_batch = X_train[index * batch_size:(index + 1) * batch_size]
generated_images = generator.predict(noise, verbose=0)
# train discriminator
X = np.concatenate((image_batch, generated_images))
y = [1] * batch_size + [0] * batch_size
d_loss = discriminator.train_on_batch(X, y)
d_loss_history.append(d_loss)
# train generator
noise = np.array([np.random.uniform(-1, 1, 100) for _ in range(batch_size)])
g_loss = discriminator_on_generator.train_on_batch(noise, [1] * batch_size)
g_loss_history.append(g_loss)
print('epoch: %d, batch: %d, g_loss: %f, d_loss: %f' % (epoch, index, g_loss, d_loss))
image = combine_images(generated_images)
image = image * 127.5 + 127.5
Image.fromarray(image.astype(np.uint8)).save('epoch-%03d.png' % epoch)
# save training history
with open('g_loss_history.log', 'w') as fp:
for x in g_loss_history:
fp.write('%f\n' % x)
with open('d_loss_history.log', 'w') as fp:
for x in d_loss_history:
fp.write('%f\n' % x)
before_weights = discriminator.layers[0].get_weights()[0]
d_loss = discriminator.train_on_batch(X, y)
after_weights = discriminator.layers[0].get_weights()[0]
print(np.array_equal(before_weights, after_weights))
before_weights = discriminator_on_generator.layers[1].layers[0].get_weights()[0]
g_loss = discriminator_on_generator.train_on_batch(noise, [1] * batch_size)
after_weights = discriminator_on_generator.layers[1].layers[0].get_weights()[0]
print(np.array_equal(before_weights, after_weights))
In [118]:
# 20 epoch学習
train(batch_size=128)
In [126]:
%matplotlib inline
import matplotlib.pyplot as plt
def plot_history(g_loss_fname, d_loss_fname):
g_loss_history = []
d_loss_history = []
with open(g_loss_fname, 'r') as fp:
for line in fp:
line = line.rstrip()
g_loss_history.append(float(line))
with open(d_loss_fname, 'r') as fp:
for line in fp:
line = line.rstrip()
d_loss_history.append(float(line))
plt.plot(g_loss_history, label='g_loss')
plt.plot(d_loss_history, label='d_loss')
plt.xlabel('# of batches')
plt.ylabel('loss')
plt.legend()
plt.xlim((0, len(g_loss_history)))
In [127]:
plot_history('dcgan_mnist1/g_loss_history.log', 'dcgan_mnist1/d_loss_history.log')
In [121]:
from IPython.display import Image
Image('dcgan_mnist1/epoch-001.png')
Out[121]:
In [122]:
Image('dcgan_mnist1/epoch-019.png')
Out[122]:
In [137]:
def train(batch_size):
# load MNIST data
(X_train, y_train), (X_test, y_test) = mnist.load_data()
X_train = (X_train.astype(np.float32) - 127.5) / 127.5
X_train = X_train.reshape(X_train.shape[0], X_train.shape[1], X_train.shape[2], 1)
discriminator = discriminator_model()
generator = generator_model()
discriminator_on_generator = generator_containing_discriminator(generator, discriminator)
d_optim = Adam(lr=0.001, beta_1=0.9)
g_optim = Adam(lr=0.001, beta_1=0.9)
# generator: trainable, discriminator: freeze
discriminator_on_generator.compile(loss='binary_crossentropy', optimizer=g_optim)
# discriminator: trainable
discriminator.trainable = True
discriminator.compile(loss='binary_crossentropy', optimizer=d_optim)
d_loss_history = []
g_loss_history = []
for epoch in range(20):
print('epoch:', epoch)
num_batches = int(X_train.shape[0] / batch_size)
print('number of batches', num_batches)
for index in range(num_batches):
noise = np.array([np.random.uniform(-1, 1, 100) for _ in range(batch_size)])
image_batch = X_train[index * batch_size:(index + 1) * batch_size]
generated_images = generator.predict(noise, verbose=0)
# train discriminator
X = np.concatenate((image_batch, generated_images))
y = [1] * batch_size + [0] * batch_size
d_loss = discriminator.train_on_batch(X, y)
d_loss_history.append(d_loss)
# train generator
noise = np.array([np.random.uniform(-1, 1, 100) for _ in range(batch_size)])
g_loss = discriminator_on_generator.train_on_batch(noise, [1] * batch_size)
g_loss_history.append(g_loss)
print('epoch: %d, batch: %d, g_loss: %f, d_loss: %f' % (epoch, index, g_loss, d_loss))
image = combine_images(generated_images)
image = image * 127.5 + 127.5
Image.fromarray(image.astype(np.uint8)).save('epoch-%03d.png' % epoch)
# save training history
with open('g_loss_history.log', 'w') as fp:
for x in g_loss_history:
fp.write('%f\n' % x)
with open('d_loss_history.log', 'w') as fp:
for x in d_loss_history:
fp.write('%f\n' % x)
In [ ]: