当前位置: 首页 > news >正文

好的结构设计网站优质友情链接

好的结构设计网站,优质友情链接,铜仁网站建设,网络营销4c1 算法步骤 上一篇提到的GAN的最优化问题是,本文记录如何求解这一问题。 首先为了表示方便,记,这里让最大的可视作常量。 第一步,给定初始的,使用梯度上升找到 ,最大化。关于梯度下降,可以参考笔者另一篇…

1 算法步骤

上一篇提到的GAN的最优化问题是G^{*}=\arg\min\limits_{G}\max\limits_{D}V(G,D),本文记录如何求解这一问题。

首先为了表示方便,记\max\limits_{D}V(G,D)=L(G),这里让V(G,D)最大的D=D^{*}可视作常量。

第一步,给定初始的G_{0},使用梯度上升找到 D_0^{*},最大化L(G_0)。关于梯度下降,可以参考笔者另一篇文章《BP神经网络原理-CSDN博客》误差反向传播的部分。

第二步,使用梯度下降法,找到G最佳的参数\theta_{G}.其中\eta为学习率。

\theta_{G}\leftarrow \theta_{G}-\eta\frac{\partial{L(G)}}{\theta_{G}}得到G_{1}

 之后这两步交替进行。

这里的L(G)是有max运算的,可以被微分吗?答案是可以的

引用李宏毅老师的例子,f(x)是有max运算的,相当于分段函数,在求微分的时候,根据当前x落在哪个区域决定微分的形式如何。

2 算法与JS散度的关系

上述算法第一步训练D时本质是增大JS散度,第二步训练G时看起来是减小JS散度,但实际上不完全等同。

如下图所示,左侧表示算法第一步根据G_{0}得到了最优的D_0^{*}。当进行到算法第二步,需要根据D_0^{*}找到一个更小的JS散度,如右图所示,G选择了G_{1}从而使得V(G_1, D)<V(G_0, D)。虽然此时JS散度更小,但是由于G_{0}更换成了G_{1}D_0^{*}将更新参数变成D_1^{*},此时JS散度更大了。只能说不能让G更新得太多,否则不能达到减小JS散度的目标。回到文物造假的例子,造假者收到鉴宝者的反馈后,应该微调技艺,而不是彻底更换技艺,否则只能从头来过。

从快速收敛的角度来说,G应该不能更新太过,但是如果太小也忽略了G更好的形式,可能陷入局部最优。

3 实际训练过程

实际训练时,我们是无法计算出真实数据或生成数据实际的期望的,只能通过抽样近似得到期望。因此实际的做法如下:

3.1 第一步,初始化

初始化生成器G和判别器D

3.2 第二步,固定G,训练D

从分布函数(如高斯分布)中随机抽样出m个样本\left \{ z^1,z^2,...z^m \right \}输入给G,输出m个样本\left \{ \tilde{x}^1,\tilde{x}^2,..\tilde{x}^m \right \}G本质上概率分布转化器——将高斯分布的噪声转变成样本的分布。从真实数据中随机抽样出m个样本\left \{ x^1,x^2,...x^m \right \},将二者输入给D。训练D的参数使其接收x_{1}时打出0分,接收x_{2}时打出1分,即最大化\tilde{V}=\frac{1}{m}\sum_{i=1}^m{log{D(x^i)}}+\frac{1}{m}\sum_{i=1}^m{log{(1-D(\tilde{x}^i))}}

建模成分类或回归问题均可。

使用梯度上升法,\theta_d\leftarrow \theta_d+\eta\nabla\tilde{V}(\theta_d)

实际中需要更新多次,使得V值最大。这一步实际上只找到了一个\max\limits_{D}V(G,D)的下限(lower bound),原因是:(1)训练次数不会非常大,没法训练到收敛;(2)即使能收敛,也可能只是一个局部最优解;(3)推导时假设了D可以是任意的函数,即针对不同的x都给出最高的值,但实际中这个假设不成立。

3.3 第三步,固定D,训练G

从分布函数(如高斯分布)中随机抽样出另外m个样本\left \{ z^1,z^2,...z^m \right \}

更新G的参数\theta_G使得下式最小:

\tilde{V}=\frac{1}{m}\sum_{i=1}^m{log{D(x^i)}}+\frac{1}{m}\sum_{i=1}^m{log{(1-D(G(z^i)))}}

其中第一项与G无关,因此只需要看第二项。

根据上文的讨论,这里一般只训练一次,避免G改变过多,无法收敛。

实践中是将GD合在一起作为一个大的神经网络,前几层是G,后几层是D,中间有一个隐含层是G的输出,就是GAN希望得到的输出。第二步和第三步可分别固定神经网络中的某几层参数不动,训练其它层参数。

4 Python实现

关于GAN的代码,参考了https://github.com/junqiangchen/GAN。项目可以产生数字图片和人脸图片,其中人脸图片的生成使用了GAN的变种——WGAN,之后会专门讨论,本文讨论最原始的GAN模型。

4.1 使用新版tensorflow需要修改的地方

原始的代码直接运行是不通的,需要做一些调整;原始代码采用的是旧版Tensorflow(V1),如果安装了新版TensorFlow(V2)也需要做调整;有些包如果安装的新版同样不支持部分API,需要替换。具体如下表所示

问题调整方法备注
部分文件路径不对

调整路径,例如

from GAN.face_model import WGAN_GPModel

调整为

from GAN.genface.face_model import WGAN_GPModel
其他几处不再赘述
imresize报错

 例如

from scipy.misc import imresize

调整为

from skimage.transform import resize
最新版本scipy不支持此函数,将
imresize(test_image, (init_width * scale_factor, init_height * scale_factor))

替换为

resize(
Image.fromarray(test_image).resize(init_width * scale_factor, init_height * scale_factor))
imsave
报错

例如

scipy.misc.imsave(path, merge_img)

调整为

import cv2cv2.imwrite(path, merge_img * 255)

最新版本scipy不支持此函数,替换成cv2。个人认为最后应该乘255,因为原始数据是0~1的数据,直接存会存成几乎黑白的图片,需要还原
使用新版tensorflow的问题
import tensorflow as tf

替换为

import tensorflow.compat.v1 as tftf.compat.v1.disable_eager_execution()
新版tensorflow提供了向下兼容的compat.v1的使用方式,统一替换即可。同时要取消eager_execution模式,新版默认是“即时计算”模式,如果兼容旧版则应取消该模式。

4.2 GAN的代码解析

代码位置:gan/GAN/genmnist/mnist_model.py, class名为GANModel

4.2.1 Generator

定义在_GAN_generator函数中,总结为以下要点:

(1)含有五层网络,除最后一层,其他层在进入下一层之前都用batch_normalization归一化+relu激活函数

g4 = tf.contrib.layers.batch_norm(g4, epsilon=1e-5, is_training=self.phase, scope='bn4')
g4 = tf.nn.relu(g4)

(2)每一层都定义w和b,使用truncated_normal,即截断异常值的正态分布

tf.truncated_normal_initializer

(3)第1~2层使用全连接层,即使用w乘输入,并加上b偏置

tf.matmul(g1, g_w2) + g_b2

(4)第3~4层使用反卷积运算。是卷积运算的逆过程,关于反卷积的介绍笔者正在整理

tf.nn.conv2d_transpose(x, W, output_shape, strides=[1, strides, strides, 1], padding='SAME')

(5)第5层使用卷积运算,并使用tanh激活函数

g5 = convolution_2d(g4, g_w5)

4.2.2 Discriminator

与Generator类似,简述如下:

(1)共4层,其中1、2层使用卷积,3、4层使用全连接

(2)卷积后使用平均池化

d1 = average_pool_2x2(d1)

(3)最后一层使用sigmoid将输出控制在0~1之间

out = tf.nn.sigmoid(out_logit)

4.2.3 损失函数

Generator的损失函数为

-tf.reduce_mean(tf.log(self.D_fake))

对应前文提到的\frac{1}{m}\sum_{i=1}^m{log{(1-D(G(z^i)))}}。注意这里是用-\frac{1}{m}\sum_{i=1}^m{log{D(G(z^i))}},方向是一样的,之后笔者会讨论他们的区别。

Discriminator的损失函数为

-tf.reduce_mean(tf.log(self.D_real) + tf.log(1 - self.D_fake))

对应前文提到的\tilde{V}=\frac{1}{m}\sum_{i=1}^m{log{D(x^i)}}+\frac{1}{m}\sum_{i=1}^m{log{(1-D(\tilde{x}^i))}}

4.2.5 训练

定义D和G的训练函数,使得各自损失函数最小化。

trainD_op = tf.train.AdamOptimizer(learning_rate, beta1).minimize(self.d_loss, var_list=D_vars)
trainG_op = tf.train.AdamOptimizer(learning_rate, beta1).minimize(self.g_loss, var_list=G_vars)

先让D预训练30次,然后D和G交替训练。为什么先让D预训练30次?笔者认为D本质上就是个图片分类器,可以不依赖于G,比较好训练,预训练可以加快收敛速度。

训练时使用feed“喂数据”

feed_dict={self.X: batch_xs, self.Z: z_batch, self.phase: 1}

其中self.X表示真实的图片,self.Z表示噪声,self.phase表示batchnorm训练阶段还是测试阶段。

4.2.6 预测

生成随机噪声Z之后,喂给G,即可生成图片

outimage = self.Gen.eval(feed_dict={self.Z: z_batch, self.phase: 1}, session=sess)

不过笔者对这里的phase有些疑问,是否应该设置为0?恕笔者对Tensorflow不熟,代码解析有些走马观花,没有深究细节以及为什么这么写,等功力提高再回过头来优化。

至此,原始GAN的算法以及Python实现已介绍完毕,下一篇笔者将拓展讨论一些细节并介绍GAN的变种。

http://www.khdw.cn/news/57454.html

相关文章:

  • 比较多人用什么网站做推广百度客服号码
  • java做网站电话注册win优化大师有用吗
  • 做网站菠菜什么意思搜索引擎优化的英文缩写是什么
  • 做网站有未来吗今日军事新闻最新消息新闻
  • 个人网页设计作品赏析福州短视频seo网站
  • wordpress牧风seo页面如何优化
  • 网页设计与制作教程期末考试题保定seo博客
  • 网站建设开发方式包括购买短视频代运营方案策划书
  • 网站建设长期待摊费用百度搜图
  • 做网站网页需要多久seo网络营销的技术
  • 做电商网站哪家好推广下载
  • 做网站需要先搞目录么仁茂网络seo
  • 网站推广方式案例代运营一般收费
  • 做哪种网站赚钱seo免费
  • 网站建设 怎么设置在线客服网站设计规划
  • 地方门户网站模板如何线上推广引流
  • 哈尔滨信息网租房信息免费推广seo
  • 各大网站博客怎么做推广云搜索app官网
  • 江津区做网站在线建站平台
  • 加强网站基础建设西安seo顾问公司
  • 即墨网站建设哪家好南昌百度推广公司
  • 制作网站找哪个公司好国家职业技能培训学校
  • 短信轰炸网站开发域名停靠
  • 电子商务网站开发的新开网店自己如何推广
  • wordpress做网站卡吗网站优化推广的方法
  • 陇西哪里能学做网站如何建立网站服务器
  • 如何看网站是用什么框架做的seo公司服务
  • php能区别电脑网站和手机网站吗怎么嵌入到phpcmsseo自学网视频教程
  • 网站模板整站资源大数据培训班需要多少钱
  • 河南新蔡有做网站建设的吗可口可乐搜索引擎营销案例