开发者社区> veetsin> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

GAN生成对抗网络学习笔记

简介: 一、GAN是Generative Adversarial Nets的缩写,是由Ian Goodfellow14年提出的,这个东西和深度学习里其他很多东西一样,看表面原理其实很好理解,就是两个网络不断对抗互相学习,最终得到一个比较好的结果,但是想搞清楚原理并且能从头推一遍公式其实还是要花不少时间的,尤其是原作里很多细节并没有展开讲,因此我觉得还是比较有必要把推导的过程记录下来的。
+关注继续查看

一、简介
GAN是Generative Adversarial Nets的缩写,是由Ian Goodfellow14年提出的,这个东西和深度学习里其他很多东西一样,看表面原理其实很好理解,就是两个网络不断对抗互相学习,最终得到一个比较好的结果,但是想搞清楚原理并且能从头推一遍公式其实还是要花不少时间的,尤其是原作里很多细节并没有展开讲,因此我觉得还是比较有必要把推导的过程记录下来的。当然,原始的GAN存在很多问题,之后再仔细写写原始GAN的缺点以及原始GAN的一些变种。

我们先来建立一个感性的认识:GAN就是一个相互博弈相互提高,最终实现生成的数据的分布和真实的数据分布重合的过程。首先要牢记,我们提出GAN的目的是人工生成数据,因此,GAN的一个网络为生成器generator,其次我们为了能生成以假乱真的数据,需要把一个啥也不会的生成器不断提升,此时用到的就是判别器discriminator,它的功能就是去鉴定生成器生成的数据。对于一个判别器,当它无法判断生成器生成的数据是真是假时,我们就得到了一个最优的生成器,然后再用生成器生成数据去训练判别器,再用判别器去鉴定生成的数据以提高判别器,循环往复直至都无法提高,有点像武侠小说中左右互搏一样,自己和自己打。

二、理论分析
我之前看过其他的博客或者一些教程,一般上来都会介绍一些会用到的知识,但是我个人畏难情绪比较严重,上来讲好多没见过的概念会让我觉得比较害怕,所以自己写的话我会直接上公式:
1
这个公式看上去很复杂,但是不要慌,问题不大,一步步来。
首先,这个公式我们只需要理解就可以了,很多时候先理解了含义再想怎么来的会比直接想怎么来的更简单。根据概念,我们先要有最优的判别器和最优的生成器,那么我们就可以定义一个D(x)和G(x),其中D(x)是判别器,得到的是x属于真实数据的概率,G(x)是生成器根据输入x生成的数据。有了这两个之后我们回头来看式子,D(x)就是x属于真实数据的概率,G(z)就是根据输入z得到的生成的数据,D(G(z))得到的就是生成数据是真实数据的概率,这项越大说明判别器越挫,竟然把生成的数据判断为是真实数据,因此对于最优判别器,logD(x)的期望要最大,D(G(z))的期望要最小,1-D(G(z))的期望要最大,V要最大;对于最优生成器,D(G(z))的期望要最大(生成器想骗过判别器),1-D(G(z))的期望要最小,V要最小,这样我们就得到了这个函数的意义,然后再对其取对数得到GAN的损失函数。

了解了损失函数的含义,我们直接来看具体的优化过程:
2
其实很简单,就三步:1、优化判别器。2、优化生成器。3、循环
至此算是建立起了对GAN的基础认识,对于非专业的人来讲我觉得了解到这一步已经可以把不了解的人骗的一愣一楞的了,接下来的都是一些证明和公式推导的细节,其中对于为什么pg(x)可以收敛到pdata(x),我看了很多讲解的博客都是一笔带过,我简单讲一下我的理解。。
这张是最优判别器的值的推导,只需要把期望化成积分的形式代入,然后就都是一些高中数学的推导。
3_jpeg
这张是在得到了最优的判别器后,把损失函数改写成-log4与JS散度的和的形式,其中JS散度是用来衡量两个概率分布的距离的一个量,大于等于0,当且仅当两个概率分布相等时为0(具体可以看wiki),因此此时的损失函数最小为0,也就是我们的生成器的任务也完成了。顺带说一句,这个地方我试过令pdata(x) = a , pg(x)=b,想上面一样去用初等数学的内容去进行函数分析,但是却失败了,我后来想了想,上面之所以能对D(x)进行求导因为那是一个判别函数,其余两项关于它的导数都为0,下面的式子中无论是关于pdata还是关于pg亦或是关于x求导都会出现你中有我我中有你的情况,从而无法化简。
4_jpeg
到这里为止我们就证明了GAN的最优解的存在,也就是真实数据的分布等于生成数据的分布,符合我们的感性认识,接下来就是对于该函数收敛的证明,也就是对于我们的优化过程合理性的证明。

5
原文中对于收敛的证明叙述了很多,提到了次倒数啊上确界啊之类的,我开始没看明白,后来也看了很多博客,全部都是一笔带过或者直接翻译,我尝试理解了一下这段话,个人感觉核心就是一句话:这个凸函数每个点的导数都属于这个凸函数的导数。原因在于只要证明了函数每个点的导数都属于函数的导数,当G和D有了足够的量,并且每次的更新量足够小,也就可以保证了梯度下降了有效性,并且最终函数可以收敛。

以上算是我对于GAN学习的一些记录,写的很简陋(可以说是很原始了,还有手写的,,,),网上写的好的有很多,比如这篇还有b站上台大李宏毅老师的视频课等等。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Java学习笔记(九):面向对象④ —— 继承性
Java学习笔记(九):面向对象④ —— 继承性
17 0
学习C++笔记283
C++ 类 & 对象
13 0
学习C++笔记83
C++ 修饰符类型
32 0
一位Java初学者的学习笔记
一位Java初学者的学习笔记
2232 0
网络安全学习笔记
<h3 style=""> <span style="font-size:15px; line-height:1.6"> </span><span style="font-size:1.2rem; line-height:1.6">跨站脚本攻击(XSS Cross Site Script)</span> </h3> <div style=""> <span style="line-hei
1872 0
+关注
5
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载