网站 备案已注销,宁波网站推广大全,访问自己做的网站,设计公司logo图标1 算法步骤
上一篇提到的GAN的最优化问题是#xff0c;本文记录如何求解这一问题。
首先为了表示方便#xff0c;记#xff0c;这里让最大的可视作常量。
第一步#xff0c;给定初始的#xff0c;使用梯度上升找到 ,最大化。关于梯度下降#xff0c;可以参考笔者另一篇…1 算法步骤
上一篇提到的GAN的最优化问题是本文记录如何求解这一问题。
首先为了表示方便记这里让最大的可视作常量。
第一步给定初始的使用梯度上升找到 ,最大化。关于梯度下降可以参考笔者另一篇文章《BP神经网络原理-CSDN博客》误差反向传播的部分。
第二步使用梯度下降法找到最佳的参数.其中为学习率。
得到 之后这两步交替进行。
这里的是有max运算的可以被微分吗答案是可以的
引用李宏毅老师的例子是有max运算的相当于分段函数在求微分的时候根据当前x落在哪个区域决定微分的形式如何。 2 算法与JS散度的关系
上述算法第一步训练时本质是增大JS散度第二步训练时看起来是减小JS散度但实际上不完全等同。
如下图所示左侧表示算法第一步根据得到了最优的。当进行到算法第二步需要根据找到一个更小的JS散度如右图所示选择了从而使得。虽然此时JS散度更小但是由于更换成了将更新参数变成此时JS散度更大了。只能说不能让更新得太多否则不能达到减小JS散度的目标。回到文物造假的例子造假者收到鉴宝者的反馈后应该微调技艺而不是彻底更换技艺否则只能从头来过。
从快速收敛的角度来说应该不能更新太过但是如果太小也忽略了更好的形式可能陷入局部最优。 3 实际训练过程
实际训练时我们是无法计算出真实数据或生成数据实际的期望的只能通过抽样近似得到期望。因此实际的做法如下
3.1 第一步初始化
初始化生成器和判别器。
3.2 第二步固定G训练D
从分布函数如高斯分布中随机抽样出m个样本输入给输出m个样本。本质上概率分布转化器——将高斯分布的噪声转变成样本的分布。从真实数据中随机抽样出m个样本将二者输入给。训练的参数使其接收时打出0分接收时打出1分即最大化
建模成分类或回归问题均可。
使用梯度上升法
实际中需要更新多次使得V值最大。这一步实际上只找到了一个的下限(lower bound)原因是1训练次数不会非常大没法训练到收敛2即使能收敛也可能只是一个局部最优解3推导时假设了可以是任意的函数即针对不同的x都给出最高的值但实际中这个假设不成立。
3.3 第三步固定D训练G
从分布函数如高斯分布中随机抽样出另外m个样本
更新的参数使得下式最小 其中第一项与无关因此只需要看第二项。
根据上文的讨论这里一般只训练一次避免改变过多无法收敛。
实践中是将和合在一起作为一个大的神经网络前几层是后几层是中间有一个隐含层是的输出就是GAN希望得到的输出。第二步和第三步可分别固定神经网络中的某几层参数不动训练其它层参数。
4 Python实现
关于GAN的代码参考了https://github.com/junqiangchen/GAN。项目可以产生数字图片和人脸图片其中人脸图片的生成使用了GAN的变种——WGAN之后会专门讨论本文讨论最原始的GAN模型。
4.1 使用新版tensorflow需要修改的地方
原始的代码直接运行是不通的需要做一些调整原始代码采用的是旧版TensorflowV1如果安装了新版TensorFlowV2也需要做调整有些包如果安装的新版同样不支持部分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, epsilon1e-5, is_trainingself.phase, scopebn4)
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], paddingSAME)
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))
对应前文提到的。注意这里是用方向是一样的之后笔者会讨论他们的区别。
Discriminator的损失函数为
-tf.reduce_mean(tf.log(self.D_real) tf.log(1 - self.D_fake))
对应前文提到的
4.2.5 训练
定义D和G的训练函数使得各自损失函数最小化。
trainD_op tf.train.AdamOptimizer(learning_rate, beta1).minimize(self.d_loss, var_listD_vars)
trainG_op tf.train.AdamOptimizer(learning_rate, beta1).minimize(self.g_loss, var_listG_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}, sessionsess)
不过笔者对这里的phase有些疑问是否应该设置为0恕笔者对Tensorflow不熟代码解析有些走马观花没有深究细节以及为什么这么写等功力提高再回过头来优化。
至此原始GAN的算法以及Python实现已介绍完毕下一篇笔者将拓展讨论一些细节并介绍GAN的变种。