近些年来,随着生成模型的作用越来越大。我们可以使用生成模型做一些无中生有的事情,比如风格颜色填充、图片高清化、图片补全修复等等。本文要讲的就是如何使用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()

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

上传一张效果图:

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐