Skip to content

Commit 64a8440

Browse files
committed
第8章代码及详解
1 parent 1134e90 commit 64a8440

File tree

74 files changed

+661
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+661
-0
lines changed

chapter8/GAN.py

+127
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import keras
2+
from keras import layers
3+
import numpy as np
4+
import os
5+
from keras.preprocessing import image
6+
7+
# GAN生成网络
8+
latent_dim = 32
9+
height = 32
10+
width = 32
11+
channels = 3
12+
13+
generator_input = keras.Input(shape=(latent_dim,))
14+
15+
x = layers.Dense(128 * 16 * 16)(generator_input)
16+
x = layers.LeakyReLU()(x)
17+
x = layers.Reshape((16, 16, 128))(x)
18+
19+
x = layers.Conv2D(256, 5, padding='same')(x)
20+
x = layers.LeakyReLU()(x)
21+
22+
x = layers.Conv2DTranspose(256, 4, strides=2, padding='same')(x)
23+
x = layers.LeakyReLU()(x)
24+
25+
x = layers.Conv2D(256, 5, padding='same')(x)
26+
x = layers.LeakyReLU()(x)
27+
x = layers.Conv2D(256, 5, padding='same')(x)
28+
x = layers.LeakyReLU()(x)
29+
30+
x = layers.Conv2D(channels, 7, activation='tanh', padding='same')(x)
31+
generator = keras.models.Model(generator_input, x)
32+
generator.summary()
33+
34+
# GAN鉴别网络
35+
discriminator_input = layers.Input(shape=(height, width, channels))
36+
x = layers.Conv2D(128, 3)(discriminator_input)
37+
x = layers.LeakyReLU()(x)
38+
x = layers.Conv2D(128, 4, strides=2)(x)
39+
x = layers.LeakyReLU()(x)
40+
x = layers.Conv2D(128, 4, strides=2)(x)
41+
x = layers.LeakyReLU()(x)
42+
x = layers.Conv2D(128, 4, strides=2)(x)
43+
x = layers.LeakyReLU()(x)
44+
x = layers.Flatten()(x)
45+
46+
x = layers.Dropout(0.4)(x)
47+
48+
x = layers.Dense(1, activation='sigmoid')(x)
49+
50+
discriminator = keras.models.Model(discriminator_input, x)
51+
discriminator.summary()
52+
53+
discriminator_optimizer = keras.optimizers.RMSprop(lr=0.0008, clipvalue=1.0, decay=1e-8)
54+
discriminator.compile(optimizer=discriminator_optimizer, loss='binary_crossentropy')
55+
56+
# 对抗网络
57+
discriminator.trainable = False
58+
59+
gan_input = keras.Input(shape=(latent_dim,))
60+
gan_output = discriminator(generator(gan_input))
61+
gan = keras.models.Model(gan_input, gan_output)
62+
63+
gan_optimizer = keras.optimizers.RMSprop(lr=0.0004, clipvalue=1.0, decay=1e-8)
64+
gan.compile(optimizer=gan_optimizer, loss='binary_crossentropy')
65+
66+
# GAN训练过程
67+
(x_train, y_train), (_, _) = keras.datasets.cifar10.load_data()
68+
69+
# 选择青蛙类别
70+
x_train = x_train[y_train.flatten() == 6]
71+
72+
# 正规化数据
73+
x_train = x_train.reshape((x_train.shape[0],) + (height, width, channels)).astype('float32') / 255.
74+
75+
iterations = 10000
76+
batch_size = 20
77+
save_dir = 'save_dir'
78+
79+
# 训练循环
80+
start = 0
81+
for step in range(iterations):
82+
# 在latent space中随机取点
83+
random_latent_vectors = np.random.normal(size=(batch_size, latent_dim))
84+
85+
# 解码成合成图像
86+
generated_images = generator.predict(random_latent_vectors)
87+
88+
# 把它们与真实图像混合
89+
stop = start + batch_size
90+
real_images = x_train[start: stop]
91+
combined_images = np.concatenate([generated_images, real_images])
92+
labels = np.concatenate([np.ones((batch_size, 1)), np.zeros((batch_size, 1))])
93+
94+
# 在标签中加噪声
95+
labels += 0.05 * np.random.random(labels.shape)
96+
97+
# 训练鉴别器
98+
d_loss = discriminator.train_on_batch(combined_images, labels)
99+
100+
# 在latent space中随机取点
101+
random_latent_vectors = np.random.normal(size=(batch_size, latent_dim))
102+
103+
# 把标签全部设置为真
104+
misleading_targets = np.zeros((batch_size, 1))
105+
106+
# 训练生成器,鉴别器的权重被frozen
107+
a_loss = gan.train_on_batch(random_latent_vectors, misleading_targets)
108+
109+
start += batch_size
110+
if start > len(x_train) - batch_size:
111+
start = 0
112+
113+
if step % 100 == 0:
114+
# 保存模型权重
115+
gan.save_weights('gan.h5')
116+
117+
# 打印loss
118+
print('discriminator loss:', d_loss)
119+
print('adversarial loss:', a_loss)
120+
121+
# 保存一个生成的图片
122+
img = image.array_to_img(generated_images[0] * 255., scale=False)
123+
img.save(os.path.join(save_dir, 'generated_frog' + str(step) + '.png'))
124+
125+
# 保存一个真实图片,用来对比
126+
img = image.array_to_img(real_images[0] * 255., scale=False)
127+
img.save(os.path.join(save_dir, 'real_frog' + str(step) + '.png'))

chapter8/VAE.py

+117
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import keras
2+
from keras import layers
3+
from keras import backend as K
4+
from keras.models import Model
5+
import numpy as np
6+
from keras.datasets import mnist
7+
from keras.utils import plot_model
8+
import matplotlib.pyplot as plt
9+
from scipy.stats import norm
10+
11+
# VAE encoder网络
12+
img_shape = (28, 28, 1)
13+
batch_size = 16
14+
latent_dim = 2 # latent space的维度
15+
16+
input_img = keras.Input(shape=img_shape)
17+
18+
x = layers.Conv2D(32, 3, padding='same', activation='relu')(input_img)
19+
x = layers.Conv2D(64, 3, padding='same', activation='relu', strides=(2, 2))(x)
20+
x = layers.Conv2D(64, 3, padding='same', activation='relu')(x)
21+
x = layers.Conv2D(64, 3, padding='same', activation='relu')(x)
22+
shape_before_flattening = K.int_shape(x)
23+
24+
x = layers.Flatten()(x)
25+
x = layers.Dense(32, activation='relu')(x)
26+
27+
z_mean = layers.Dense(latent_dim)(x)
28+
z_log_var = layers.Dense(latent_dim)(x)
29+
30+
31+
# latent space取样函数
32+
def sampling(args):
33+
z_mean, z_log_var = args
34+
epsilon = K.random_normal(shape=(K.shape(z_mean)[0], latent_dim),
35+
mean=0.,
36+
stddev=1.)
37+
return z_mean + K.exp(z_log_var) * epsilon
38+
39+
40+
z = layers.Lambda(sampling)([z_mean, z_log_var])
41+
42+
# VAE decoder网络
43+
decoder_input = layers.Input(K.int_shape(z)[1:])
44+
45+
# 不取样到正确的位置
46+
x = layers.Dense(np.prod(shape_before_flattening[1:]),
47+
activation='relu')(decoder_input)
48+
49+
x = layers.Reshape(shape_before_flattening[1:])(x)
50+
x = layers.Conv2DTranspose(32, 3, padding='same',
51+
activation='relu', strides=(2, 2))(x)
52+
x = layers.Conv2D(1, 3, padding='same', activation='sigmoid')(x)
53+
54+
decoder = Model(decoder_input, x)
55+
z_decoded = decoder(z)
56+
57+
58+
# 自定义一个计算VAE loss的层
59+
class CustomVariationalLayer(keras.layers.Layer):
60+
61+
def vae_loss(self, x, z_decoded):
62+
x = K.flatten(x)
63+
z_decoded = K.flatten(z_decoded)
64+
xent_loss = keras.metrics.binary_crossentropy(x, z_decoded)
65+
kl_loss = -5e-4 * K.mean(
66+
1 + z_log_var - K.square(z_mean) - K.exp(z_log_var), axis=-1)
67+
return K.mean(xent_loss + kl_loss)
68+
69+
def call(self, inputs):
70+
x = inputs[0]
71+
z_decoded = inputs[1]
72+
loss = self.vae_loss(x, z_decoded)
73+
self.add_loss(loss, inputs=inputs)
74+
return x
75+
76+
77+
y = CustomVariationalLayer()([input_img, z_decoded])
78+
79+
vae = Model(input_img, y)
80+
vae.compile(optimizer='rmsprop',
81+
loss=None)
82+
vae.summary()
83+
plot_model(vae, show_shapes=True, to_file='model.png')
84+
85+
(x_train, _), (x_test, y_test) = mnist.load_data()
86+
87+
x_train = x_train.astype('float32') / 255.
88+
x_train = x_train.reshape(x_train.shape + (1,))
89+
x_test = x_test.astype('float32') / 255.
90+
x_test = x_test.reshape(x_test.shape + (1,))
91+
92+
vae.fit(x=x_train, y=None,
93+
shuffle=True,
94+
epochs=10,
95+
batch_size=batch_size,
96+
validation_data=(x_test, None))
97+
98+
# 从2维latent space中取样并解码成图像
99+
n = 15
100+
digit_size = 28
101+
figure = np.zeros((digit_size * n, digit_size * n))
102+
103+
grid_x = norm.ppf(np.linspace(0.05, 0.95, n))
104+
grid_y = norm.ppf(np.linspace(0.05, 0.95, n))
105+
106+
for i, yi in enumerate(grid_x):
107+
for j, xi in enumerate(grid_y):
108+
z_sample = np.array([[xi, yi]])
109+
z_sample = np.tile(z_sample, batch_size).reshape(batch_size, 2)
110+
x_decoded = decoder.predict(z_sample, batch_size=batch_size)
111+
digit = x_decoded[0].reshape(digit_size, digit_size)
112+
figure[i * digit_size: (i + 1) * digit_size,
113+
j * digit_size: (j + 1) * digit_size] = digit
114+
115+
plt.figure(figsize=(10, 10))
116+
plt.imshow(figure, cmap='Greys_r')
117+
plt.show()
+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import keras
2+
import numpy as np
3+
from keras import layers
4+
import random
5+
import sys
6+
7+
# 下载并解析数据
8+
path = keras.utils.get_file('nietzsche.txt',
9+
origin='https://s3.amazonaws.com/text-datasets/nietzsche.txt')
10+
text = open(path).read().lower()
11+
print('Corpus length:', len(text))
12+
13+
# 向量化序列字符
14+
# 提取序列字符的最大长度
15+
maxlen = 60
16+
17+
# 取样一个新的序列每step个字符
18+
step = 3
19+
20+
# 用下面的list保存提取出来的序列
21+
sentences = []
22+
23+
# 用下面的list保存targets(接下来的字符)
24+
next_chars = []
25+
26+
# 取样
27+
for i in range(0, len(text) - maxlen, step):
28+
sentences.append(text[i: i + maxlen])
29+
next_chars.append(text[i + maxlen])
30+
print('Number of sequences:', len(sentences))
31+
32+
# 语料库中独一无二字符的list
33+
chars = sorted(list(set(text)))
34+
print('Unique characters:', len(chars))
35+
# 用字典映射字符和它们在chars中的下标
36+
char_indices = dict((char, chars.index(char)) for char in chars)
37+
38+
# 使用one-hot把字符编码成二进制数组
39+
print('Vectorization...')
40+
x = np.zeros((len(sentences), maxlen, len(chars)), dtype=np.bool)
41+
y = np.zeros((len(sentences), len(chars)), dtype=np.bool)
42+
for i, sentence in enumerate(sentences):
43+
for t, char in enumerate(sentence):
44+
x[i, t, char_indices[char]] = 1
45+
y[i, char_indices[next_chars[i]]] = 1
46+
47+
# 构建网络模型
48+
model = keras.models.Sequential()
49+
model.add(layers.LSTM(128, input_shape=(maxlen, len(chars))))
50+
model.add(layers.Dense(len(chars), activation='softmax'))
51+
52+
# 模型编译
53+
optimizer = keras.optimizers.RMSprop(lr=0.01)
54+
model.compile(loss='categorical_crossentropy', optimizer=optimizer)
55+
56+
57+
# 取样函数
58+
def sample(preds, temperature=1.0):
59+
preds = np.asarray(preds).astype('float64')
60+
preds = np.log(preds) / temperature
61+
exp_preds = np.exp(preds)
62+
preds = exp_preds / np.sum(exp_preds)
63+
# multinomial函数用来取样
64+
# 第一个参数代表每次实验的实验次数
65+
# 第二个参数代表样本的概率分布
66+
# 第三个参数代表实验几次
67+
probas = np.random.multinomial(1, preds, 1)
68+
return np.argmax(probas)
69+
70+
71+
# 生成文本的循环
72+
for epoch in range(1, 60):
73+
print('epoch', epoch)
74+
# 让模型在训练数据上训练一个epoch
75+
model.fit(x, y, batch_size=128, epochs=1)
76+
77+
# 随机选一个初始文本
78+
start_index = random.randint(0, len(text) - maxlen - 1)
79+
generated_text = text[start_index: start_index + maxlen]
80+
print('---Generating with seed: "' + generated_text + '"')
81+
82+
for temperature in [0.2, 0.5, 1.0, 1.2]:
83+
print('------ temperature:', temperature)
84+
generated_text = text[start_index: start_index + maxlen]
85+
sys.stdout.write(generated_text)
86+
87+
# 生成400个字符
88+
for i in range(400):
89+
sampled = np.zeros((1, maxlen, len(chars)))
90+
for t, char in enumerate(generated_text):
91+
sampled[0, t, char_indices[char]] = 1.
92+
93+
preds = model.predict(sampled, verbose=0)[0]
94+
next_index = sample(preds, temperature)
95+
next_char = chars[next_index]
96+
generated_text += next_char
97+
generated_text = generated_text[1:]
98+
99+
sys.stdout.write(next_char)
100+
sys.stdout.flush()
101+
print()

chapter8/deep-dream-test.jpg

56.5 KB
Loading

0 commit comments

Comments
 (0)