近些年来,随着生成模型的作用越来越大。我们可以使用生成模型做一些无中生有的事情,比如风格颜色填充、图片高清化、图片补全修复等等。本文要讲的就是如何使用Tensorflow实现对抗生成网络。

1.作用从细节上来看,生成模型可以做一些无中生有的事情,比如图片高清化,智能填充(图片被遮住一部分,修复完整),使用轮廓渲染栩栩如生的图片等

2.发展限制在最大似然估计及相关策略上,很多概率计算的模拟非常困难

将piecewise linear units(线性分段单元)用在生成模型上比较困难

环境安装

安装tensorflow

pip install tensorflow

或者使用更快的gpu版

pip install tensorflow-gpu

注意:首先你要知道你自己的显卡有没有gpu,不是n卡的同学可以直接放弃了,然后还需要安装nvidia的CUDA Toolkit 和 cudnn。

安装科学计算库numpy,和作图库matplotlib

pip install numpy

pip install matplotlib

强烈推荐使用Anaconda作为python的集成环境,可以让你在环境配置上面少走很多弯路。推荐使用wheel直接安装。

生成式对抗网络(Generative Adversarial Net)对抗生成网络基本原理

对抗生成网络基本流程

对抗生成网络代码实现

基本原理

假设我们有一个生成模型G(generator),他的目的是生成一张尽量真实的狗的图片。于此同时我们有一个图像判别的模型D(discriminator),他的目的是区分这张图片中有没有真实的狗。不断的调整生成模型G和分类模型D,一直到分类模型不能将生成的图片和真实狗的图片区分出来为止,那么我们就可以认为,生成模型生成了一张真实的狗的图片。

我们的判别模型目标优化函数:

我们的生成模型目标优化函数:

基本流程

我们的GAN网络需要设计的结构如图所示:

Python代码

GAN 主要由两个部分构成:generator 和 discriminatorgenerator 主要作用是从训练数据中产生相同分布的samples

discriminator 则还是采用传统的监督学习的方法
最终达到数学层面上的"纳什均衡",全局最优
import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("/tmp/data/", one_hot=True)
这一步我们引入了库和mnist手写数字数据。假如你还不了解mnist,可以点击这里mnist imagemnist label
1.初始化训练参数
num_steps = 1000 # 迭代次数
batch_size = 128 # 批大小
learning_rate = 0.0002 # 学习率
image_dim = 784 # 28 * 28
gen_hidden_dim = 256
disc_hidden_dim = 256
noise_dim = 100
# Glorot Initialization
def glorot_init(shape):
return tf.random_normal(shape=shape, stddev=1. / tf.sqrt(shape[0] / 2.))
# 权重与偏移
weights = {
'gen_hidden1': tf.Variable(glorot_init([noise_dim, gen_hidden_dim])),
'gen_out': tf.Variable(glorot_init([gen_hidden_dim, image_dim])),
'disc_hidden1': tf.Variable(glorot_init([image_dim, disc_hidden_dim])),
'disc_out': tf.Variable(glorot_init([disc_hidden_dim, 1])),
}
biases = {
'gen_hidden1': tf.Variable(tf.zeros([gen_hidden_dim])),
'gen_out': tf.Variable(tf.zeros([image_dim])),
'disc_hidden1': tf.Variable(tf.zeros([disc_hidden_dim])),
'disc_out': tf.Variable(tf.zeros([1])),
}
设计权重向量(weight)和偏移(biases)
# Generator 生成网络
def generator(x):
hidden_layer = tf.matmul(x, weights['gen_hidden1'])
hidden_layer = tf.add(hidden_layer, biases['gen_hidden1'])
hidden_layer = tf.nn.relu(hidden_layer)
out_layer = tf.matmul(hidden_layer, weights['gen_out'])
out_layer = tf.add(out_layer, biases['gen_out'])
out_layer = tf.nn.sigmoid(out_layer)
return out_layer
# Discriminator 辨别网络
def discriminator(x):
hidden_layer = tf.matmul(x, weights['disc_hidden1'])
hidden_layer = tf.add(hidden_layer, biases['disc_hidden1'])
hidden_layer = tf.nn.relu(hidden_layer)
out_layer = tf.matmul(hidden_layer, weights['disc_out'])
out_layer = tf.add(out_layer, biases['disc_out'])
out_layer = tf.nn.sigmoid(out_layer)
return out_layer
# Network Inputs
gen_input = tf.placeholder(tf.float32, shape=[None, noise_dim], name='input_noise')
disc_input = tf.placeholder(tf.float32, shape=[None, image_dim], name='disc_input')
设计生成模型(generator)和分类模型(discriminator),并且声明输入数据
# Build Generator Network
gen_sample = generator(gen_input)
# Build 2 Discriminator Networks (one from noise input, one from generated samples)
disc_real = discriminator(disc_input)
disc_fake = discriminator(gen_sample)
# Build Loss
gen_loss = -tf.reduce_mean(tf.log(disc_fake))
disc_loss = -tf.reduce_mean(tf.log(disc_real) + tf.log(1. - disc_fake))
# 因为tensorflow梯度下降过程默认更新所有,所以我们手动设置参数
gen_vars = [weights['gen_hidden1'], weights['gen_out'],
biases['gen_hidden1'], biases['gen_out']]
disc_vars = [weights['disc_hidden1'], weights['disc_out'],
biases['disc_hidden1'], biases['disc_out']]
# 创建优化器
optimizer_gen = tf.train.AdamOptimizer(learning_rate=learning_rate)
optimizer_disc = tf.train.AdamOptimizer(learning_rate=learning_rate)
# 创建梯度下降
train_gen = optimizer_gen.minimize(gen_loss, var_list=gen_vars)
train_disc = optimizer_disc.minimize(disc_loss, var_list=disc_vars)
# Initialize the variables
init = tf.global_variables_initializer()
建立判别网络,建立两个生成网络,计算loss,梯度下降,初始化变量。
sess = tf.Session()
sess.run(init)
# Train
for i in range(1, num_steps+1)
batch_x, _ = mnist.train.next_batch(batch_size)
# 随机生成-1到1的浮点数
z = np.random.uniform(-1., 1., size=[batch_size, noise_dim])
# 训练数据为样本数据和随机初始化数据(用于生成网络)
feed_dict = {disc_input: batch_x, gen_input: z}
_, _, gl, dl = sess.run([train_gen, train_disc, gen_loss, disc_loss],
feed_dict=feed_dict)
if i % 2000 == 0 or i == 1:
print('Step%i: Generator Loss:%f, Discriminator Loss:%f' % (i, gl, dl))
训练模型
n = 6
canvas = np.empty((28 * n, 28 * n))
for i in range(n):
z = np.random.uniform(-1., 1., size=[n, noise_dim])
g = sess.run(gen_sample, feed_dict={gen_input: z})
# 反转颜色显示
g = -1 * (g - 1)
for j in range(n):
# 在 matplotlib 中画出结果
canvas[i * 28:(i + 1) * 28, j * 28:(j + 1) * 28] = g[j].reshape([28, 28])
plt.figure(figsize=(n, n))
plt.imshow(canvas, origin="upper", cmap="gray")
plt.show()

设置随机输入,反转颜色,生成测试图

上传一张效果图: