通俗易懂的生成式对抗网络(GAN)讲解
话说深度学习框架,大家最能想到的是卷积神经网络(CNN),这玩意大家用来做叫图像识别的东西,很火。可是呢,深度学习是不断发展的,不断地有新的玩意出来。在2014年的时候,一种叫做生成式对抗网络(GAN)的东西横空出世了。
发明者是一个叫做Lan Goodfellow的男人,先说一下这个姓有多牛批。Good翻译成中文就是“好”,Fellow翻译过来就是“人”,加在一块就叫做“好人”。前面的名是Lan,翻译成中文可以谐音为“老”。姓名加在一块就是“老好人”,牛批吧!不光名字N批,牛的一批的还有他发明的GAN网络。(这个笑话是高恩阳老师发明的)
这个网络叫做GAN,“干”。高老师曾经教GAN时候说过:不要怂,就是干!听名字我们就知道,GAN当中是有两个东西在互相打架,打架的东西我们叫做生成器(Generative)和判别器(Discriminative)。那么GAN网络是什么一种网络呢?是生成器G和判别器D打架的网络,打架打到什么程度呢?两者实力平衡到50%即可。
这个网络能干啥呢,它能够自动生成图像,比如我们往里面导入一些人脸图片,它就会生成一些在这个世界上不存在的人的图片。(哇,听起来可怕呀,鬼魂来了!)
接下来我来详细地介绍一下“干”是怎么干的。首先呢,我们得有输入样本,比如我们现在有6W张28*28大小的数字图片,每个图片上面都是数字,这些图片来自于库:mnist_uint8。
我们随便取出一个图都是28*28大小的图。
它的意思指的是里面有784个长度为1的小正方形小块。这些小块按照长28,宽28来排列,形成一个正方形图片。每个小正方形中呢,有一个0~255的数值,0代表的是黑色,255代表白色,中间值就是从黑色过渡到白色的一个灰色。
我们把第一张图第一行28个小正方形的数值照写,第二行呢,把它拉到第一行的末尾,这样数值就有56个了。接下来把第三行拉到末尾,数值就有84个,。。。,以此类推,把第二十八行拉到末尾,这样就形成了一个1*784的数列(一行,784列),每一个格中都有一个0~255的数值。然后我们把第二张图按同样方法处理,放到第二行。然后我们把第三张图处理,放到第三行,。。。,以此类推把第6W张图处理,放到第6W行。这样,我们就形成了一个60000*784的数列。
形成之后,把数列中的每一个数都除以255,进行归一化处理,除以255是因为这些值都是在0~255之间,那么我们就会得到60000*784个0~1之间的数据。
之后,我们把6W张图的正确数字(0~9)给它导入进去(没用,但是需要讲解下),导入的是啥样子呢,看下图:
大家看,上面图中有6W行,10列,每个小方格中写的或者是0或者是1,这个是啥意思呢,举个例子,比如第一行,第五列是1,其它的都是0,这说明,这个数字是4(第一个数代表0)。比如第二行,第七列是1,说明这个数字是6。
生成完事儿了,我们就要开始重要的步骤啦。要是卷积神经网络,我们就要把输入的图片作为自变量,把最后图像的正确数字作为便签,然后训练。但是“干”不是做图像识别的,它是生成新的,你没有见过的图片。所以我们图片的数字就不用导入了。我们要做的是输入一个6W*1的一个行列式,每个小格子里面写的都是1。为啥要写1呢,我们假设,这些真实的输入样本图,我们就默认为是1。我们生成的假图,我们就叫做0。
好了,我们这样自变量和标签都写完了,我们使用它们的默认名字分别是:train_x、train_y。
接着我们开始造假的图了,怎么造?随机生成。比如我们生成6W*100的一个0~1之间随机数的数列。取名为test_x。
再生成一个6W*1的数列,类似于最开始生成的那个,里面小格都是0,取名为test_y,为什么都是0,因为是我们随机生成的数列,假的!
下一步呢,我们要创建BP神经网络,BP神经网络的原理请参照我的微信公众号里面:http://mp.weixin.qq.com/s/EJy0BT1wYnsMGEniQh6HYw
里面有一个“第二部分-BP神经网络推导过程”,可以下来看看,前面的内容都可以跳过,从4分30秒开始看。
我们首先创建一个输入层为100,输出层为784的BP网络,我们叫第一网络。这个网络用来把6W*100的行列式转化成6W*784的行列式。
下面核心开始了,我们创建一个D网络,也叫判别器网络。这个BP网络有三层,输入层784个自变量,中间层100个自变量,输出层1个自变量。为啥呢,因为真实数据train_x是784列,输出的train_y是1列。我们再创建一个G网络,也叫做生成器网络。这个BP网络有四层,输入层100个、输出层1个。中间层分别是784和100。这是因为test_x列数为100,test_y列数为1,784是与我们第一网络一致,100是与上面的D网络一致。还有一点要注意:这三个BP网络的其它参数,一定要全部都一致。
下一步我们就要开始训练三个网络了,怎么训练?
(1)首先我们训练第一网络,首先初始化三个网络,得到一系列随机生成的权值w和偏置量b(如果没学过BP的话,同时也不想看,那么你就把训练(红字)的过程想象成黑箱即可)。
(2)然后把G网络中的输入层与第一个中间层的权值分享给第一网络,让第一网络的权值w、偏置量b与G网络一致。分享之后,训练一次第一网络,得到一个6W*784的行列式。
(3)然后我们设定一个数值,比如是1000,然后我们从上面得到的6W个数据中随机地提取出1000行。接着我们从train_x里面也就是真实数据中也提取出1000行,把这个合并成2000行、784列的一个行列式。它们所对应的输出(0和1)也给合并,形成2000行,1列的标签行列式。
(4)把这2000组输入数据和2000组标签导入D网络中进行训练。训练结束后会得到D网络的权值和偏置量。然后我们把得到的权值和偏置量赋予G网络,怎么赋予呢?我们D网络的神经元个数是[784 100 1],而G网络是[100 784 100 1]。那么我们把D网络第一层的权值赋予G网络的第二层,第二层赋予第三层。
(5)接下来我们训练G网络,怎么训练呢,我们把刚才的随机提取的1000组假的数据作为自变量,然后把1000*1的全是1的行列式作为标签,注意:这里是1不是0,为什么是1呢,因为我们这里要把假的数据当作是真的数据来训练。训练后我们得到了G网络的权值和偏置量。
(6)我们设定一个值比如是1500,开始时候设为0次,如果我们循环的次数小于1500次,那么返回步骤(2)循环,如果大于的话,执行(7)。还有一种情况也是执行(7):就是我们通过D网络训练后,所得出的2000行1列的行列式给它所有的值四舍五入,然后求平均值,如果为0.5±0.05,这代表着打架的G、D双方实力持平。
(7)我们训练完成之后呢,我们随机生成n行,列100的测试数据,然后带入到第一网络中,得到n*784的数据,我们把每一行抽出来还原成28*28的一个矩阵,得到n个矩阵。最后我们把矩阵的每一个值都乘以255,然后输出成图片。这些图片就是最上面说的假图。至此GAN网络训练与测试完毕。
大家觉得讲的怎么样,如果大家喜欢的话,麻烦转推一下,或者给几个赞哦!
————————————————
如果对我的课程感兴趣的话,欢迎关注小木希望学园-微信公众号:
mutianwei521
也可以扫描二维码哦!
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:通俗易懂的生成式对抗网络(GAN)讲解 - Python技术站