Generative Adversarial Network 是深度学习中非常有趣的一种方法。GAN最早源自Ian Goodfellow的这篇论文。LeCun对GAN给出了极高的评价:

“There are many interesting recent development in deep learning…The most important one, in my opinion, is adversarial training (also called GAN for Generative Adversarial Networks). This, and the variations that are now being proposed is the most interesting idea in the last 10 years in ML, in my opinion.” – Yann LeCun

那么我们就看看GAN究竟是怎么回事吧:

如上图所示,GAN包含两个互相对抗的网络:G(Generator)和D(Discriminator)。正如它的名字所暗示的那样,它们的功能分别是:

Generator是一个生成器的网络,它接收一个随机的噪声,通过这个噪声生成图片,记做G(z)。
Discriminator是一个鉴别器网络,判别一张图片或者一个输入是不是“真实的”。它的输入x是数据或者图片,输出D(x)代表x为真实图片的概率,如果为1,就代表100%是真实的图片,而输出为0,就代表不可能是真实的图片。
在训练过程中,生成网络G的目标就是尽量生成真实的图片去欺骗判别网络D。而D的目标就是尽量把G生成的图片和真实的图片分别开来。这样,G和D构成了一个动态的“博弈过程”。在最理想的状态下,G可以生成足以“以假乱真”的图片G(z)。对于D来说,它难以判定G生成的图片究竟是不是真实的,因此D(G(z)) = 0.5。

最后,我们就可以使用生成器和随机输入来生成不同的数据或者图片了。

上面的描述大家可能都能理解,但是把它变成数学语言,可能你就蒙B了。

“GANçš„æ ¸å¿ƒåŽŸç†â€çš„å›¾ç‰‡æœç´¢ç»“æžœ

如上图所示,x是输入,z是随机噪声。D(x)是鉴别器的判定数据为真的概率,D(G(z))是判定生成数据为真的概率。生成器希望这个D(G(z))越大越好,这个时候整个表达式的值应该变小。而鉴别器的目的是能够有效区分真实数据和假数据,所以D(x)应该趋向于变大,D(G(z))趋向于变小,整个表达式就变大。也就是说训练过程,生成器和辨别器互相对抗,一个使上述表达式变小,另一个使其变大,最后训练趋向于平衡,而生成器这时候应该生成真假难辨的数据,这就是我们的最终目的。

上图是GAN算法训练的具体过程,这里我们不做过多的解释,直接运行一个例子。

“GAN”的图片搜索结果

我们用MINST数据集来看看如何使用TensorflowJS来训练一个GAN,模拟生成手写数字。

代码见我的codepen

function gen(xs) {
const l1 = tf.leakyRelu(xs.matMul(G1w).add(G1b));
const l2 = tf.leakyRelu(l1.matMul(G2w).add(G2b));
const l3 = tf.tanh(l2.matMul(G3w).add(G3b));
return l3;
}

function disReal(xs) {
const l1 = tf.leakyRelu(xs.matMul(D1w).add(D1b));
const l2 = tf.leakyRelu(l1.matMul(D2w).add(D2b));
const logits = l2.matMul(D3w).add(D3b);
const output = tf.sigmoid(logits);
return [logits, output];
}

function disFake(xs) {
return disReal(gen(xs));
}
GAN的两个网络分别用gen和disReal创建。gen是生成器网络,disReal是辨别器的网络。disFake是把生成数据用辨别器来辨别。这里的网络使用leakyrelu。使得输出在-inf到+inf,利用sigmoid映射到【0,1】,这是辨别器模型输出一个0-1之间的概率。

“leaky relu”的图片搜索结果

通常我们会创建一个比生成器更复杂的鉴别器网络使得鉴别器有足够的分辨能力。但在这个例子里,两个网络的复杂程度类似。

计算损失的函数使用 tf.sigmoidCrossEntropyWithLogits,值得注意的是,在最新的0.13版本中,这个交叉熵被移除了,你需要自己实现该方法。

训练过程如下:

async function trainBatch(realBatch, fakeBatch) {
const dcost = dOptimizer.minimize(
() => {
const [logitsReal, outputReal] = disReal(realBatch);
const [logitsFake, outputFake] = disFake(fakeBatch);

const lossReal = sigmoidCrossEntropyWithLogits(ONES_PRIME, logitsReal);
const lossFake = sigmoidCrossEntropyWithLogits(ZEROS, logitsFake);
return lossReal.add(lossFake).mean();
},
true,
[D1w, D1b, D2w, D2b, D3w, D3b]
);
await tf.nextFrame();
const gcost = gOptimizer.minimize(
() => {
const [logitsFake, outputFake] = disFake(fakeBatch);

const lossFake = sigmoidCrossEntropyWithLogits(ONES, logitsFake);
return lossFake.mean();
},
true,
[G1w, G1b, G2w, G2b, G3w, G3b]
);
await tf.nextFrame();

return [dcost, gcost];
}
训练使用了两个optimizer,

第一步,计算实际数据的辨别结果和1的交叉熵,以及生成器生成数据的辨别结果和0的交叉熵。也就是说,我们希望辨别器尽可能的判断出生成数据都是假的而实际数据都是真的。使得这两个交叉熵的均值最小。
第二步开始对抗,要让生成数据尽可能被判别为真。
下图是某个训练过程的损失:

这个是经过1000个迭代后的生成图:

大家可以尝试调整学习率,增加网络复杂度,加大迭代次数来获得更好的生成模型。

GAN的学习其实还是比较复杂的,参数和损失选择都不容易,好在有一些现成的工具可以使用,另外推荐大家去https://poloclub.github.io/ganlab/,提供了很直观的GAN学习的过程。这个也是用TensorflowJS来实现的。

参考:

https://www.msra.cn/zh-cn/news/features/gan-20170511
https://zhuanlan .www.michenggw.com zhihu.com/p/24767059
http://blog.aylien.com/introduction-www.mhylpt.com generative-adversarial-networks-code-tensorflow/
https://github.com/carpedm20/DCGAN-tensorflow
https://blog.openai.www.gcyl152.com com/generative-models/
https://zhuanlan.zhihu.com/p/45200767
https://blog.csdn.net/heyc861221/article/details/80127148

在浏览器中进行深度学习:TensorFlow.js (八)生成对抗网络 (GAN的更多相关文章

  1. 深度学习框架PyTorch一书的学习-第七章-生成对抗网络(GAN)

    参考:https://github.com/chenyuntc/pytorch-book/tree/v1.0/chapter7-GAN生成动漫头像 GAN解决了非监督学习中的著名问题:给定一批样本,训 ...

  2. 人工智能中小样本问题相关的系列模型演变及学习笔记(二):生成对抗网络 GAN

    [说在前面]本人博客新手一枚,象牙塔的老白,职业场的小白.以下内容仅为个人见解,欢迎批评指正,不喜勿喷![握手][握手] [再啰嗦一下]本文衔接上一个随笔:人工智能中小样本问题相关的系列模型演变及学习 ...

  3. TensorFlow从1到2(十二)生成对抗网络GAN和图片自动生成

    生成对抗网络的概念 上一篇中介绍的VAE自动编码器具备了一定程度的创造特征,能够"无中生有"的由一组随机数向量生成手写字符的图片. 这个"创造能力"我们在模型中 ...

  4. 深度学习-生成对抗网络GAN笔记

    生成对抗网络(GAN)由2个重要的部分构成: 生成器G(Generator):通过机器生成数据(大部分情况下是图像),目的是“骗过”判别器 判别器D(Discriminator):判断这张图像是真实的 ...

  5. 利用tensorflow训练简单的生成对抗网络GAN

    对抗网络是14年Goodfellow Ian在论文Generative Adversarial Nets中提出来的. 原理方面,对抗网络可以简单归纳为一个生成器(generator)和一个判断器(di ...

  6. CNCC2017中的深度学习与跨媒体智能

    CNCC2017中的深度学习与跨媒体智能 转载请注明作者:梦里茶 目录 机器学习与跨媒体智能 传统方法与深度学习 图像分割 小数据集下的深度学习 语音前沿技术 生成模型 基于贝叶斯的视觉信息编解码 珠 ...

  7. 深度学习-tensorflow学习笔记(1)-MNIST手写字体识别预备知识

    深度学习-tensorflow学习笔记(1)-MNIST手写字体识别预备知识 在tf第一个例子的时候需要很多预备知识. tf基本知识 香农熵 交叉熵代价函数cross-entropy 卷积神经网络 s ...

  8. 深度学习Tensorflow相关书籍推荐和PDF下载

    深度学习Tensorflow相关书籍推荐和PDF下载 baihualinxin关注 32018.03.28 10:46:16字数 481阅读 22,673 1.机器学习入门经典<统计学习方法&g ...

  9. Deep learning for visual understanding: A review 视觉理解中的深度学习:回顾 之一

    Deep learning for visual understanding: A review 视觉理解中的深度学习:回顾 ABSTRACT: Deep learning algorithms ar ...

随机推荐

  1. ElasticSearch High Level REST API【7】聚合

    获取平均值聚合示例,最大值.最小值.求和类似 public void aggregation(){ RestHighLevelClient client = elasticClient.getRest ...

  2. 转:比较spring cloud和dubbo,各自的优缺点是什么

    原文:https://blog.csdn.net/u010664947/article/details/80007767 dubbo由于是二进制的传输,占用带宽会更少 springCloud是http ...

  3. linux 开机自启动 Tomcat

    1.修改脚本文件rc.local:vim /etc/rc.d/rc.local 这个脚本是使用者自定的开机启动程序,可以在里面添加想在系统启动之后执行的脚本或者脚本执行命令 2.添加如下内容: exp ...

  4. Fiddler(二)

    该博客基于以下博客网站里的内容进行提取,实验,和补充.让我们开始 https://www.cnblogs.com/yyhh/p/5140852.html AutoResponder 允许拦截指定规则的 ...

  5. thymelef模板报错 the entity name must immediately follow the '&' in the entity reference

    thymelef模板里面是不能实用&符号的 要用&转义符代替,官网也有文档说明可以用官方的通配符代替,官方文档http://www.thymeleaf.org/doc/tutorial ...

  6. Java面试宝典2017版

    1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语法,集合的语法,io 的语法,虚拟机方面的语法. 1.一个".java&qu ...

  7. 图解HTTP总结(4)——返回结果的HTTP状态码

    HTTP状态码负责表示客户端HTTP请求的返回结果.标记服务器端的处理是否正常.通知出现的错误等工作. 状态码的类别 2XX 成功 200 OK 表示从客户端发来的请求在服务器端被正常处理了. 在响应 ...

  8. iOS-UICollectionViewController 介绍

    废话不多说,列几个列子 (几种情况下的做法): 情景一: 介绍:1. 在UIViewController 上加 UICollectionView (用代码 创建 UICollectionView). ...

  9. Android 自定义WebView 实现可以加载缓存数据

    1.自定义WebView说明 1.1.这个WebView可以加载缓存的数据.(需要后端配合,将html转换成一个字符串,主要是图片要用特殊格式) 1.2.注入了图片链接,为了方便点击webView中的 ...

  10. linux下创建用户 费元星站长

    linux下创建用户(一) Linux 系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申请一个账号,然后以这个账号的身份进入系统.用户的账号一方面可以帮助系 ...