使用DCGAN实现人脸图像生成

DCGAN介绍

原始的GAN网络在训练过程中生成者生成图像质量不太稳定,无法得到高质量的生成者网络,导致这个问题的主要原因是生成者与判别者使用相同的反向传播网络,对生成者网络的改进就是用卷积神经网络替代原理的MLP实现稳定生成者网络,生成高质量的图像。这个就是Deep Convolutional Generative Adversarial Network (DCGAN)的由来。相比GAN,DCGAN把原来使用MLP的地方都改成了CNN,同时去掉了池化层,改变如下:

  • 判别器使用正常卷积,最后一层使用全连接层做预测判别
  • 生成器根据输入的随机噪声,通过卷积神经网络生成一张图像
  • 无论是生成器还是判别器都在卷积层后面有BN层
  • 生成器与判别器分别使用relu与leaky relu作为激活函数, 除了生成器的最后一层
  • 生成器使用转置/分步卷积、判别器使用正常卷积。

最终DCGAN的网络模型如下:

其中基于卷积神经网络的生成器模型如下:

判别器模型如下:

代码实现:

生成器:

class Generator:
    def __init__(self, depths=[1024, 512, 256, 128], s_size=4):
        self.depths = depths + [3]
        self.s_size = s_size
        self.reuse = False

    def __call__(self, inputs, training=False):
        inputs = tf.convert_to_tensor(inputs)
        with tf.variable_scope(‘g‘, reuse=self.reuse):
            # reshape from inputs
            with tf.variable_scope(‘reshape‘):
                outputs = tf.layers.dense(inputs, self.depths[0] * self.s_size * self.s_size)
                outputs = tf.reshape(outputs, [-1, self.s_size, self.s_size, self.depths[0]])
                outputs = tf.nn.relu(tf.layers.batch_normalization(outputs, training=training), name=‘outputs‘)
            # deconvolution (transpose of convolution) x 4
            with tf.variable_scope(‘deconv1‘):
                outputs = tf.layers.conv2d_transpose(outputs, self.depths[1], [5, 5], strides=(2, 2), padding=‘SAME‘)
                outputs = tf.nn.relu(tf.layers.batch_normalization(outputs, training=training), name=‘outputs‘)
            with tf.variable_scope(‘deconv2‘):
                outputs = tf.layers.conv2d_transpose(outputs, self.depths[2], [5, 5], strides=(2, 2), padding=‘SAME‘)
                outputs = tf.nn.relu(tf.layers.batch_normalization(outputs, training=training), name=‘outputs‘)
            with tf.variable_scope(‘deconv3‘):
                outputs = tf.layers.conv2d_transpose(outputs, self.depths[3], [5, 5], strides=(2, 2), padding=‘SAME‘)
                outputs = tf.nn.relu(tf.layers.batch_normalization(outputs, training=training), name=‘outputs‘)
            with tf.variable_scope(‘deconv4‘):
                outputs = tf.layers.conv2d_transpose(outputs, self.depths[4], [5, 5], strides=(2, 2), padding=‘SAME‘)
            # output images
            with tf.variable_scope(‘tanh‘):
                outputs = tf.tanh(outputs, name=‘outputs‘)
        self.reuse = True
        self.variables = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope=‘g‘)
        return outputs

判别器:

class Discriminator:
    def __init__(self, depths=[64, 128, 256, 512]):
        self.depths = [3] + depths
        self.reuse = False

    def __call__(self, inputs, training=False, name=‘‘):
        def leaky_relu(x, leak=0.2, name=‘‘):
            return tf.maximum(x, x * leak, name=name)
        outputs = tf.convert_to_tensor(inputs)

        with tf.name_scope(‘d‘ + name), tf.variable_scope(‘d‘, reuse=self.reuse):
            # convolution x 4
            with tf.variable_scope(‘conv1‘):
                outputs = tf.layers.conv2d(outputs, self.depths[1], [5, 5], strides=(2, 2), padding=‘SAME‘)
                outputs = leaky_relu(tf.layers.batch_normalization(outputs, training=training), name=‘outputs‘)
            with tf.variable_scope(‘conv2‘):
                outputs = tf.layers.conv2d(outputs, self.depths[2], [5, 5], strides=(2, 2), padding=‘SAME‘)
                outputs = leaky_relu(tf.layers.batch_normalization(outputs, training=training), name=‘outputs‘)
            with tf.variable_scope(‘conv3‘):
                outputs = tf.layers.conv2d(outputs, self.depths[3], [5, 5], strides=(2, 2), padding=‘SAME‘)
                outputs = leaky_relu(tf.layers.batch_normalization(outputs, training=training), name=‘outputs‘)
            with tf.variable_scope(‘conv4‘):
                outputs = tf.layers.conv2d(outputs, self.depths[4], [5, 5], strides=(2, 2), padding=‘SAME‘)
                outputs = leaky_relu(tf.layers.batch_normalization(outputs, training=training), name=‘outputs‘)
            with tf.variable_scope(‘classify‘):
                batch_size = outputs.get_shape()[0].value
                reshape = tf.reshape(outputs, [batch_size, -1])
                outputs = tf.layers.dense(reshape, 2, name=‘outputs‘)
        self.reuse = True
        self.variables = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope=‘d‘)
        return outputs

损失函数与训练

def loss(self, traindata):
    """build models, calculate losses.
    Args:
        traindata: 4-D Tensor of shape `[batch, height, width, channels]`.
    Returns:
        dict of each models‘ losses.
    """
    generated = self.g(self.z, training=True)
    g_outputs = self.d(generated, training=True, name=‘g‘)
    t_outputs = self.d(traindata, training=True, name=‘t‘)
    # add each losses to collection
    tf.add_to_collection(
        ‘g_losses‘,
        tf.reduce_mean(
            tf.nn.sparse_softmax_cross_entropy_with_logits(
                labels=tf.ones([self.batch_size], dtype=tf.int64),
                logits=g_outputs)))
    tf.add_to_collection(
        ‘d_losses‘,
        tf.reduce_mean(
            tf.nn.sparse_softmax_cross_entropy_with_logits(
                labels=tf.ones([self.batch_size], dtype=tf.int64),
                logits=t_outputs)))
    tf.add_to_collection(
        ‘d_losses‘,
        tf.reduce_mean(
            tf.nn.sparse_softmax_cross_entropy_with_logits(
                labels=tf.zeros([self.batch_size], dtype=tf.int64),
                logits=g_outputs)))
    return {
        self.g: tf.add_n(tf.get_collection(‘g_losses‘), name=‘total_g_loss‘),
        self.d: tf.add_n(tf.get_collection(‘d_losses‘), name=‘total_d_loss‘),
    }

def train(self, losses, learning_rate=0.0002, beta1=0.5):
    """
    Args:
        losses dict.
    Returns:
        train op.
    """
    g_opt = tf.train.AdamOptimizer(learning_rate=learning_rate, beta1=beta1)
    d_opt = tf.train.AdamOptimizer(learning_rate=learning_rate, beta1=beta1)
    g_opt_op = g_opt.minimize(losses[self.g], var_list=self.g.variables)
    d_opt_op = d_opt.minimize(losses[self.d], var_list=self.d.variables)
    with tf.control_dependencies([g_opt_op, d_opt_op]):
        return tf.no_op(name=‘train‘)

训练与运行


开始

2个epoch之后

5个epoch之后

OpenCV+tensorflow系统化学习路线图,推荐视频教程:
计算机视觉从入门到实战

原文地址:http://blog.51cto.com/gloomyfish/2348169

时间: 2024-10-11 01:08:30

使用DCGAN实现人脸图像生成的相关文章

php基础之gd图像生成、缩放、logo水印和简单验证码实现

php基础之gd图像生成.缩放.logo水印和简单验证码实现 阅读目录 图像生成 缩略图 水印生成 验证码 gd 库是php最常用的图片处理库之一(另外一个是imagemagick),可以生成图片.验证码.水印.缩略图等等.要使用gd库首先需要开启gd库扩 展,windows系统下需要在php.ini中将extension=php_gd2.dll 前边的分号去掉然后重启web服务器,linux系统下一般在编译php时已经开启gd库扩展,要是没有开启gd库扩展则需要先编译安装freetype ,j

文档生成工具doxygen+图像生成工具GraphViz

文档生成工具doxygen+图像生成工具GraphViz 虽然jdk自带的javadoc也很好用,不过使用doxygen+GraphViz 的组合可以生成许多强大的图(类图.协作图.文件包含/被包含图.函数调用/被调用图.类继承体系图等),另外,doxygen支持直接生成chm文档,支持LaTeX公式,如果你有一个支持php的服务器,生成的html还可以加入一个搜索框. doxygen是开源的C语言软体,可以在它的官方网站上下载到软体和源码:http://www.stack.nl/~dimitr

OpenGL ES学习笔记(二)——平滑着色、自适应宽高及三维图像生成

首先申明下,本文为笔者学习<OpenGL ES应用开发实践指南(Android卷)>的笔记,涉及的代码均出自原书,如有需要,请到原书指定源码地址下载. <Android学习笔记--OpenGL ES的基本用法.绘制流程与着色器编译>中实现了OpenGL ES的Android版HelloWorld,并且阐明了OpenGL ES的绘制流程,以及编译着色器的流程及注意事项.本文将从现实世界中图形显示的角度,说明OpenGL ES如何使得图像在移动设备上显示的更加真实.首先,物体有各种颜色

最简单的分形图像生成算法

本文将提供一段完整地生成一幅分形图像文件的C语言代码,并且极为简单.我相信这应该是最简单的分形图像生成算法.大部分的分形图像代码也都很短,但一有递归迭代就难以理解了.而这段代码则很好懂,并且其生成的图像会使人意想不到. #include <iostream> #include <cmath> #include <cstdlib> #define DIM 1000 void pixel_write(int,int); FILE *fp; int main() { fp =

php基础 gd图像生成、缩放、logo水印和验证码

gd库是php最常用的图片处理库之一(另外一个是imagemagick),可以生成图片.验证码.水印.缩略图等等. 图像生成 <?php /* 用windows画图板画图 1.新建空白画布(指定宽高) 2.创建颜料.(红,r 绿g 蓝b,三原色组成的. 三原色由弱到强各可以选0-255之间) 3.画线,写字,画图形,填充等 4.保存/输出图片 5.销毁画布 */ //用gd库来画图,仍是以上5个步骤. // 1:造画布,以资源形式返回 imagecreatetruecolor(宽,高); $im

支持单色条码图像生成的条形码控件Barcode Professional

Barcode Professional for .NET Windows Forms条形码控件是一款灵活和强大的.NET组件(.NET DLL 类库),它让您轻松地添加条码生成和打印功能到您的.NET应用程序中.支持几乎所有当前常用的条码:Code 39, Code 128, GS1-128, GS1 DataBar (RSS-14), EAN 13 & UPC, Postal (USPS, British Royal Mail, Australia Post, DHL,等), Data Ma

虚拟视点图像生成004

这几天的成果主要有: 1.由于深度图像本身的缺陷,给原始的深度图像加上预处理,首先是对深度图像进行形态学闭运算,大小为3*3的方形块.然后进行中值滤波,大小为5*5. cv::Mat element3(3, 3, CV_8U, cv::Scalar(1)); cv::morphologyEx(imageDepth, imageDepth, cv::MORPH_CLOSE, element3); cv::morphologyEx(imageDepth2, imageDepth2, cv::MORP

Halcon学习之四:有关图像生成的函数

1.copy_image ( Image : DupImage : : ) 复制image图像 2.region_to_bin ( Region : BinImage : ForegroundGray, BackgroundGray,Width, Height : ) 将区域Region转换为一幅二进制图像BinImage. ForegroundGray, BackgroundGray分别为前景色灰度值和背景色灰度值. Width, Height为Region的宽度和高度. 3.region_t

Agg:PPM格式图像生成

PPM是一个Linux下的简单图像格式,可以用Xnview打开.Agg的教程第一个,就是生成PPM格式的图像.PPM格式定义参见:http://en.wikipedia.org/wiki/Netpbm_format.以下是一个简单的画点程序: buffer.cpp #include <stdio.h> #include <string.h> #include "agg_rendering_buffer.h" const int HEIGHT = 480; con