GAN生成网络

未分类 2019-04-01 2,106 次浏览 Comments Off on GAN生成网络

GAN

协同进化

画家与鉴赏家

在一般的监督式神经网络学习过程中,需要告诉神经网络它自己的输出是否“正确”,也就是给出一个误差,然后神经网络根据这个误差去更新自身的参数。但是在很多时候,我们并不能对一些抽象的东西给出一个确切的“误差”大小,比如画作的风格相似度,语气的情感,这些都是人类很难具体准确量化的。既然神经网络自己最大的特点就是能够收集处理这样的数据,找出其中的抽象特征,为何不让神经网络自己来扮演这样一个“裁判”或者说“监督者”的角色呢。

这个的难点在于如何保证“裁判”有足够的裁断能力,这决定了被训练的网络是否能接收到正确的误差值,但事实上在一开始的时候,被训练的网络能力很差,此时误差值的准确度影响不大,我们让“监督者”网络同样参与一个学习与进化过程,不断提升自己的鉴别能力。

莫烦大神有一个画家与画家朋友的能力的比喻:一开始画家的能力很差,画不出好的画作,画家的朋友的审美也很差,分辨不出名画与画家的画的区别,于是我们给画家的朋友看一些名画,画家的朋友渐渐能够分辨出名画了,他给他的画家朋友指出了他的画与名画的区别,于是画家根据朋友的建议改进自己的绘画能力,利用一些随机灵感创作更多的画。画家的朋友继续提升自己的鉴赏能力,也不断地给画家建议,直到最后,画家的朋友能够很清楚的分辨名画了,但是他却不能分辨出他朋友的画和名画了,这样就实现了一个协同进化。

应用

由于GAN是利用现实的数据样本来提升自己“创作”的能力,而且最后达到的目的是“以假乱真”,所以GAN生成网络具有极强的模仿能力,如果给出一些面孔,它能创造出不存在的面孔,如果给出一些画作,它能够创造出具有欺骗性的“赝品”。甚至在抠图时,能够自动计算出被去掉的部分背后的图案。

关键代码

略去基本的网络创建等步骤,直接分析代码

artist_paintings = artist_work() #创建一些“名画”
G_idear = torch.randn(BATCH_SIZE, N_IDEAS) # 创建灵感
G_paintings = G(G_idear) # 根据一些随机“灵感”去创作一幅画

prob_artist0 = D(artist_paintings)  # 去学习名画,让D网络逐步提高这个概率
prob_artist1 = D(G_paintings)       # 去看G画的画,判断是不是名画,让G逐步提高这个概率

# D_loss = torch.mean(torch.log(1. - prob_artist0) - torch.log(1. - prob_artist1)) # 若不好理解,可以写成这种形式,效果类似
D_loss =  - torch.mean(torch.log(prob_artist0) + torch.log(1. - prob_artist1)) # 提升D的能力,希望能同时提高认出名画和画家画的概率
G_loss = torch.mean(torch.log(1. - prob_artist1))  # 网络更新的方式是最小化误差,所以用1-这个概率,这个概率越小,更新的程度越大

# G_loss实质为,G没能成功骗到D的几率,即G的画作与原画的差距
# D_loss实质为,D认为G画作与名画的相似度,加上D没认出名画的几率
# 此处为反向传递的步骤
opt_D.zero_grad()
D_loss.backward(retain_graph=True)      # reusing computational graph
opt_D.step()

opt_G.zero_grad()
G_loss.backward()
opt_G.step()

微信扫一扫,分享到朋友圈

GAN生成网络
梓沨

站长 INTP,生物搬砖工