4.keras实现-->生成式深度学习之用变分自编码器VAE生成图像(mnist数据集和名人头像数据集)
1.VAE和GAN
- 变分自编码器(VAE,variatinal autoencoder)
- 生成式对抗网络(GAN,generative adversarial network)
两者不仅适用于图像,还可以探索声音、音乐甚至文本的潜在空间;
- VAE非常适合用于学习具有良好结构的潜在空间,其中特定方向表示数据中有意义的变化轴;
- GAN生成的图像可能非常逼真,但它的潜在空间可能没有良好结构,也没有足够的连续型。
自编码,简单来说就是把输入数据进行一个压缩和解压缩的过程。 原来有很多 Feature,压缩成几个来代表原来的数据,解压之后恢复成原来的维度,再和原数据进行比较。它是一种非监督算法,只需要输入数据,解压缩之后的结果与原数据本身进行比较。

在实践中,这种经典的自编码器不会得到特别有用或具有良好结构的潜在空间。它们也没有对数据做多少压缩。因此,它们已经基本上过时了(Keras 0.x版本还有AutoEncoder这个层,后来直接都删了)。但是,VAE向自编码器添加了一点统计魔法,迫使其学习连续的、高度结构化的潜在空间。这使得VAE已成为图像生成的强大工具。变分编码器和自动编码器的区别就在于,传统自动编码器的隐变量z的分布是不知道的,因此我们无法采样得到新的z,也就无法通过解码器得到新的x。下面我们来变分,我们现在不要从x中直接得到z,而是得到z的均值和方差,然后再迫使它逼近正态分布的均值和方差,则网络变成下面的样子:

然而上面这个网络最大的问题是,它是断开的。前半截是从数据集估计z的分布,后半截是从一个z的样本重构输入。最关键的采样这一步,恰好不是一个我们传统意义上的操作。这个网络没法求导,因为梯度传到f(z)以后没办法往前走了。为了使得整个网络得以训练,使用一种叫reparemerization的trick,使得网络对均值和方差可导,把网络连起来。这个trick的idea见下图:

实际上,这是将原来的单输入模型改为二输入模型了。因为服从标准正态分布,所以它乘以估计的方差加上估计的均值,效果跟上上图直接从高斯分布里抽样本结果是一样的。这样,梯度就可以通上图红线的方向回传,整个网络就变的可训练了。

VAE的工作原理:
(1)一个编码器模块将输入样本input_img转换为表示潜在空间中的两个参数z_mean和z_log_variance;
(2)我们假定潜在正态分布能够生成输入图像,并从这个分布中随机采样一个点:z=z_mean + exp(z_log_variance)*epsilon,其中epsilon是取值很小的随机张量;
(3)一个解码器模块将潜在空间的这个点映射回原始输入图像。
因为epsilon是随机的,所以这个过程可以确保,与input_img编码的潜在位置(即z-mean)靠近的每个点都能被解码为与input_img类似的图像,从而迫使潜在空间能够连续地有意义。潜在空间中任意两个相邻的点都会被解码为高度相似的图像。连续性以及潜在空间的低维度,将迫使潜在空间中的每个方向都表示数据中一个有意义的变化轴,这使得潜在空间具有非常良好的结构,因此非常适合通过概率向量来进行操作。
VAE的参数通过两个损失函数来进行训练:一个是重构损失(reconstruction loss),它迫使解码后的样本匹配初始输入;另一个是正则化损失(regularization loss),它有助于学习具有良好结构的潜在空间,并可以降低训练数据上的过拟合。
实现代码如下:
编码自编码器是更现代和有趣的一种自动编码器,它为码字施加约束,使得编码器学习到输入数据的隐变量模型。 |
|
import keras
|
卷积层的输入必须是3维的(长,宽,1或者3) keras不需要输入batch的大小,fit时候再设置 shape_before_flattening (None, 14, 14, 64) |
encoded = layers.Flatten()(encoded)
|
z_mean ---> <tf.Tensor 'dense_5/BiasAdd:0' shape=(?, 2) dtype=float32> K.shape(z_mean) ---> |
#潜在空间采样的函数 |
在keras中,任何对象都应该是一个层,如果代码不是内置层的一部分, 我们应该将其包装到一个Lambda层(或自定义层)中 Keras的Lambda层以一个张量函数为参数,对输入的数据按照张量函数的要求做映射。 本质上就是Keras layer中.call()的快捷方式。先定义运算逻辑 K.int_shape(z) ---> (None,2) None应该是batch_size |
#VAE解码器网络,将潜在空间点映射为图像 |
|
#用于计算VAE损失的自定义层 |
正则化损失 + 重构损失 我们一般认为采样函数的形式为loss(input,target),VAE的双重损失不符合这种形式。 因此,损失的设置方法为:编写一个自定义层,并在其内部使用内置的add_loss层方法 来创建一个你想要的损失 |
#训练VAE
|
|
from keras.datasets import mnist
|
x_train.shape (600, 28, 28) |
vae.fit(x_train,None, |
一旦训练好了这样的模型,我们就可以使用decoder网络将任意潜在空间向量 转换为图像 |
#从二维潜在空间中采样一组点的网络,并将其解码为图像
|
因为训练时候就用了600个数据,所以效果很差....电脑实在带不动,┭┮﹏┭┮ 以后有服务器再试试,7777777 |
小结: 用深度学习进行图像生成,就是通过对潜在空间进行学习来实现的,这个潜在空间能够捕捉到关于图像数据集的统计信息。 通过对潜在空间中的点进行采样和编码,我们可以生成前所未见的图像。
网上的代码大部分都是关于mnist数据集的,直接load_dataset就完事了,我找到了名人头像的数据集celebrity_data,用这个数据集做vae更有趣一点。
import keras
|
|
train_imgs = glob.glob('./celebrity_data/train/*.jpg')
|
Image读出来的是PIL的类型,而skimage.io读出来的数据是numpy格式的 import Image as img 输出可以看出Img读图片的大小是图片的(width, height);而skimage的是(height,width, channel) |
height,width = imageio.imread(train_imgs[0]).shape[:2]
|
训练集里面的图片都是218*178*3的,训练的时候我也没有改大小,直接放进去训练的 |
def imread(f):
|
train_data_generator是训练集图片生成器,每次生成一个图片 |
img_shape = (img_xdim,img_ydim,3)
|
这部分和上面基于minist数据集的encoder部分一样 |
#将图片转换为二维向量 nxf_image = nxf_image.reshape((1,)+nxf_image.shape)
|
这里是我在测试encoder,随机输入一张图片,输出了二维的一个值,一个是均值,一个是方差,encoder没有编译, 也没有fit,就相当于将多维图片降维成二维的一组 |
# 潜在空间采样的函数
|
这部分也是一样的,解码操作,随机生成一个点(均值,方差)放入decoder中,看看生成的图片能不能和原来的图片一样 |
# 用于计算VAE损失的自定义层
|
VAE的两个损失,由于keras自带的损失函数没有同时有正则损失和重构损失,所以需要自定义一个损失层, 使用call函数来定义该损失层的功能 |
def sample(path):
|
sample函数,我就随机输入两个值(encoder的输出值),看看能不能生成一个相似的图片 |
参考文献:
【2】变分自编码器(Variational Autoencoder, VAE)通俗教程
【5】vae 名人数据集的使用
4.keras实现-->生成式深度学习之用变分自编码器VAE生成图像(mnist数据集和名人头像数据集)的更多相关文章
- 4.keras实现-->生成式深度学习之用GAN生成图像
生成式对抗网络(GAN,generative adversarial network)由Goodfellow等人于2014年提出,它可以替代VAE来学习图像的潜在空间.它能够迫使生成图像与真实图像在统 ...
- 4.keras实现-->生成式深度学习之DeepDream
DeepDream是一种艺术性的图像修改技术,它用到了卷积神经网络学到的表示,DeepDream由Google于2015年发布.这个算法与卷积神经网络过滤器可视化技术几乎相同,都是反向运行一个卷积神经 ...
- 从零开始学会GAN 0:第一部分 介绍生成式深度学习(连载中)
本书的前四章旨在介绍开始构建生成式深度学习模型所需的核心技术.在第1章中,我们将首先对生成式建模领域进行广泛的研究,并从概率的角度考虑我们试图解决的问题类型.然后,我们将探讨我们的基本概率生成模型的第 ...
- 深度学习课程笔记(九)VAE 相关推导和应用
深度学习课程笔记(九)VAE 相关推导和应用 2018-07-10 22:18:03 Reference: 1. TensorFlow code: https://jmetzen.github.io/ ...
- 用MXnet实战深度学习之一:安装GPU版mxnet并跑一个MNIST手写数字识别
用MXnet实战深度学习之一:安装GPU版mxnet并跑一个MNIST手写数字识别 http://phunter.farbox.com/post/mxnet-tutorial1 用MXnet实战深度学 ...
- 转:TensorFlow和Caffe、MXNet、Keras等其他深度学习框架的对比
http://geek.csdn.net/news/detail/138968 Google近日发布了TensorFlow 1.0候选版,这第一个稳定版将是深度学习框架发展中的里程碑的一步.自Tens ...
- PyTorch中使用深度学习(CNN和LSTM)的自动图像标题
介绍 深度学习现在是一个非常猖獗的领域 - 有如此多的应用程序日复一日地出现.深入了解深度学习的最佳方法是亲自动手.尽可能多地参与项目,并尝试自己完成.这将帮助您更深入地掌握主题,并帮助您成为更好的深 ...
- 学习《深度学习与计算机视觉算法原理框架应用》《大数据架构详解从数据获取到深度学习》PDF代码
<深度学习与计算机视觉 算法原理.框架应用>全书共13章,分为2篇,第1篇基础知识,第2篇实例精讲.用通俗易懂的文字表达公式背后的原理,实例部分提供了一些工具,很实用. <大数据架构 ...
- 【神经网络与深度学习】Caffe使用step by step:使用自己数据对已经训练好的模型进行finetuning
在经过前面Caffe框架的搭建以及caffe基本框架的了解之后,接下来就要回到正题:使用caffe来进行模型的训练. 但如果对caffe并不是特别熟悉的话,从头开始训练一个模型会花费很多时间和精力,需 ...
随机推荐
- 五、K3 WISE 开发插件《K3 Wise 群发短信配置开发(一)之短信平台配置》
开发环境:K/3 Wise 13.0 目录 一.创建短信数据库 二.配置短信接口 三.设置帐套关键字 四.查询短信余额 一.创建短信数据库 打开帐套管理: 账号默认为Admin,密码不填: 菜单“系统 ...
- LeetCode 37 Sudoku Solver(求解数独)
题目链接: https://leetcode.com/problems/sudoku-solver/?tab=Description Problem : 解决数独问题,给出一个二维数组,将这个数独 ...
- [转]F5 BIG-IP负载均衡器配置实例与Web管理界面体验
转载:http://www.zyan.cc/f5_big_ip/ 前言:最近一直在对比测试F5 BIG-IP和Citrix NetScaler负载均衡器的各项性能,于是写下此篇文章,记录F5 BIG- ...
- 查看运行中的Java其配置的堆大小
一.背景 有题目中的需求,也不是空穴来风:前一阵给公司搭建了一个持续集成服务器,Jenkins.最近发现,运行一段时间后,就变慢了. 随便一个操作,cpu就飙高了.然后就思考会不会是内存不够用,频繁G ...
- ftp主动与被动模式详解
FTP是仅基于TCP的服务,不支持UDP.与众不同的是FTP使用2个端口,一个数据端口和一个命令端口(也可叫做控制端口).通常来说这两个端口是21(命令端口)和20(数据端口).但FTP工作方式的不同 ...
- tars环境部署
author: headsen chen date: 2018-10-18 12:35:40 注意:依据Git上的tars搭建步骤整理而来 参考: https://max.book118.com/h ...
- JavaScript通知浏览器,更改通知数目
http://lab.ejci.net/favico.js/ http://www.zhangxinxu.com/study/201607/web-notifications.html http:// ...
- VC++ 学习笔记3 获取编辑框字符串
边界框添加字符串比较简单 可以直接在对话框的空间上面点击右键添加变量,变量类型为CString 在此取名为m_NUM 直接使用m_NUM就是编辑框的CString, 举例: 在messagebox显 ...
- [转][darkbaby]任天堂传——失落的泰坦王朝(上)
前言: 曾经一再的询问自我;是否真的完全了解任天堂这个游戏老铺的真实本质?或许从来就没有人能够了解,世间已经有太多的真相被埋没在谎言和臆测之中.作为 一个十多年游龄的老玩家,亲眼目睹了任天堂从如日 ...
- yii---左查询使用
看到一些做关联查询的示例,例如使用hasMany(一对多),还是有一个hasOne(一对一)的,没有细看,下面是我看到的一个比较好用的一个: $query = (new \yii\db\Query() ...

