ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

AI-For-Beginners 第10课深度解析:生成对抗网络(GAN)从对抗训练到风格迁移实战

AI-For-Beginners 第10课深度解析:生成对抗网络(GAN)从对抗训练到风格迁移实战 教程人工智能机器学习深度学习【免费下载链接】AI-For-Beginners12 Weeks, 24 Lessons, AI for All!项目地址https://gitcode.com/GitHub_Trending/ai/AI-For-Beginners点击查看免费下载导读本文基于 AI-For-Beginners 课程第 10 课《生成对抗网络》Generative Adversarial Networks的官方教材展开系统讲解 GAN 的核心思想、生成器与判别器的网络架构、两阶段对抗训练流程并结合仓库内 GANTF.ipynb 与 GANPyTorch.ipynb 的完整源码给出可直接运行的全连接 GAN 与 DCGAN 实现。此外本文还将深入讲解同课的**风格迁移Style Transfer**技术并通过 StyleTransfer.ipynb 中的 Gram 矩阵损失、内容损失与全变分损失源码帮助读者掌握用预训练 CNN 做图像风格合成的方法。学完本文你将理解 GAN 难以训练的四大经典难题及其缓解策略并具备用 TensorFlow/Keras 或 PyTorch 从零训练图像生成模型的实战能力。GAN 的核心思想两个网络互相博弈在上一课自编码器 Autoencoders中我们学习了生成模型这类模型能够生成与训练数据集中样本相似的全新图片VAE变分自编码器就是典型代表。但如果要生成真正有意义的图像例如一幅合理分辨率的画作VAE 的训练往往难以收敛。这正是 GAN 所要解决的场景。生成对抗网络Generative Adversarial NetworkGAN的核心思想是让两个神经网络互相训练、彼此对抗生成器Generator输入一个随机向量噪声向量输出一张生成的图片。判别器Discriminator输入一张图片判断它是真实图片来自训练数据集还是由生成器伪造的图片。本质上判别器就是一个图像分类器。通过这种零和博弈生成器不断生成更逼真的图片以骗过判别器判别器则不断提升甄别能力最终生成器学到的分布逼近真实数据分布。判别器架构一个图像分类网络判别器的架构与普通的图像分类网络没有本质区别。最简单的情况下它可以是一个全连接分类器更常见的是采用卷积网络CNN。基于卷积网络的 GAN 称为DCGANDeep Convolutional GAN。一个 CNN 判别器通常由以下层构成若干组卷积 池化层逐步减小空间尺寸一个或多个全连接层用于提取特征向量最后的二分类器输出真/假概率。这里的池化Pooling是一种缩小图片尺寸的技术池化层通过把上一层中神经元簇的输出合并为下一层的单个神经元来降低数据的维度。生成器架构翻转的判别器生成器相对更巧妙一些可以把它看作反向的判别器。它从**潜向量latent vector出发对应于判别器中的特征向量先经过一个全连接层把向量转换到所需的尺寸/形状再通过反卷积deconvolution 上采样upscaling**逐步生成图片。这一过程与自编码器中的解码器decoder部分非常相似。注由于卷积层本质上是扫过图像的线性滤波器反卷积在逻辑上与卷积类似可以用同一类层的实现完成。GAN 的两阶段对抗训练GAN 之所以被称为对抗网络是因为生成器与判别器之间存在持续竞争。正是这一竞争过程推动双方不断提升使网络逐步生成越来越好的图片。训练过程分为两个阶段训练判别器这个任务相当直接。用生成器生成一批图片标注为 0伪造图片再从训练数据集中取一批真实图片标注为 1。计算判别器损失并执行反向传播。训练生成器这一步稍复杂因为我们不直接知道生成器的预期输出。做法是取整个 GAN 网络生成器 判别器输入随机向量期望输出为 1对应真实图片。此时需要冻结判别器的参数不希望在这一步训练它然后执行反向传播。值得注意的是训练过程中生成器和判别器的损失通常不会显著下降理想情况下两者应当震荡这恰恰反映两个网络都在持续改进自身性能。源码级实现用 Keras 从零搭建 GAN仓库中的 GANTF.ipynb 给出了完整的全连接 GAN 实现可直接在 Jupyter/Colab 中运行。以下要点来自该 Notebook 的源码生成器Dense 版generator Sequential() generator.add(Dense(256, input_shape(100,))) generator.add(LeakyReLU(alpha0.2)) generator.add(BatchNormalization(momentum0.8)) generator.add(Dense(512)) generator.add(LeakyReLU(alpha0.2)) generator.add(BatchNormalization(momentum0.8)) generator.add(Dense(1024)) generator.add(LeakyReLU(alpha0.2)) generator.add(BatchNormalization(momentum0.8)) generator.add(Dense(784, activationtanh)) generator.add(Reshape((28,28))) optimizer keras.optimizers.Adam(lr0.0002, decay8e-9) generator.compile(lossbinary_crossentropy, optimizeroptimizer, metrics[accuracy])该实现中包含三个在 GAN 中至关重要的技巧Leaky ReLU 替代 ReLU对于负数输入Leaky ReLU 不再是恒等于 0而是一条斜率很小的线性函数。这很重要因为它能在 ReLU 负半轴值为 0 的区域依然传播梯度帮助梯度下降持续更新参数。Batch Normalization用于稳定训练过程。最后一层使用tanh激活使输出值域落在 [-1, 1] 区间与输入数据的归一化范围一致。Notebook 中加载 MNIST 数据后同样执行X_train (X_train.astype(np.float32) - 127.5) / 127.5将像素从 [0, 255] 缩放到 [-1, 1]。判别器Dense 版discriminator Sequential() discriminator.add(Flatten(input_shape(28,28))) discriminator.add(Dense(784)) discriminator.add(LeakyReLU(alpha0.2)) discriminator.add(Dense(784//2)) discriminator.add(LeakyReLU(alpha0.2)) discriminator.add(Dense(1, activationsigmoid)) discriminator.compile(lossbinary_crossentropy, optimizeroptimizer, metrics[accuracy])随后将两者组合为对抗网络discriminator.trainable False adversarial Sequential() adversarial.add(generator) adversarial.add(discriminator) adversarial.compile(lossbinary_crossentropy, optimizeroptimizer)注意只有在构建对抗网络时才把判别器设为不可训练这正对应上文训练生成器时冻结判别器的步骤。两阶段训练循环Notebook 中的训练循环batch323000 次迭代完整复现了两阶段训练for cnt in range(3000): # 1) 训练判别器 random_index np.random.randint(0, len(X_train) - batch//2) legit_images X_train[random_index : random_index batch//2].reshape(batch//2, 28, 28) gen_noise np.random.normal(0, 1, (batch//2, 100)) syntetic_images generator.predict(gen_noise) x_combined_batch np.concatenate((legit_images, syntetic_images)) y_combined_batch np.concatenate((np.ones((batch//2, 1)), np.zeros((batch//2, 1)))) d_loss discriminator.train_on_batch(x_combined_batch, y_combined_batch) # 2) 训练生成器通过对抗网络 noise np.random.normal(0, 1, (batch, 100)) y_mislabled np.ones((batch, 1)) g_loss adversarial.train_on_batch(noise, y_mislabled) if cnt % 500 0: print(epoch: %d, [Discriminator :: d_loss: %f], [Generator :: loss: %f] % (cnt, d_loss[0], g_loss)) plotn(5)从运行输出可以看到判别器与生成器的损失在整个训练过程中呈震荡状态例如 epoch 0 时 d_loss≈0.60 / g_loss≈0.64到 epoch 2000 时 d_loss≈0.55 / g_loss≈2.68这正是 GAN 正常训练的表现。Notebook 结尾还给出拓展任务在完整 MNIST 数据集上训练观察生成效果能提升到什么程度。DCGAN用卷积替换全连接在 Dense 示例中生成器与判别器都用全连接网络。但众所周知处理图像时 CNN 的表现更好。**Deep Convolutional GANDCGAN**在结构上与上述示例一致区别在于生成器与判别器都改用卷积层。由于生成器要做与传统 CNN 相反的任务从特征向量生成图像实现上与自编码器的解码器类似因此在生成器中需要使用Conv2DTranspose层。DCGAN 生成器来自 GANTF.ipynb 源码generator Sequential() generator.add(Dense(128 * 7 * 7, activationrelu, input_dim100)) generator.add(Reshape((7, 7, 128))) generator.add(UpSampling2D()) generator.add(Conv2DTranspose(128, kernel_size3, paddingsame)) generator.add(BatchNormalization(momentum0.8)) generator.add(Activation(relu)) generator.add(UpSampling2D()) generator.add(Conv2DTranspose(64, kernel_size3, paddingsame)) generator.add(BatchNormalization(momentum0.8)) generator.add(Activation(relu)) generator.add(Conv2DTranspose(1, kernel_size3, paddingsame)) generator.add(Activation(tanh)) optimizer keras.optimizers.Adam(0.0001)DCGAN 判别器则以Conv2D LeakyReLU Dropout(0.25) BatchNormalization交替堆叠、逐步下采样最后接Flatten与Dense(1, activationsigmoid)。生成器参数量约为 85.6 万输入 100 维噪声、输出 28×28 单通道图像。同样仓库还提供了 GANPyTorch.ipynb方便使用 PyTorch 完成同等任务。GAN 训练中的经典难题GAN 以难训练著称官方文档总结了四类最常见的问题模式坍缩Mode Collapse生成器学会生成一张足以欺骗判别器的成功图片而不是输出多样化的图片导致生成样本缺乏多样性。对超参数敏感经常出现 GAN 完全不收敛的情况而仅仅降低学习率就可能突然实现收敛。生成器与判别器之间的平衡很多情况下判别器损失会快速降到 0导致生成器无法继续训练。克服方法包括为生成器和判别器设置不同的学习率或者在判别器损失已经过低时跳过该步判别器训练。高分辨率训练与自编码器遇到的问题一致过多卷积网络层的重建会产生伪影。通常用**渐进式增长progressive growing**解决先用低分辨率图像训练前几层再逐步解冻或添加更多层。另一种方案是在层间添加额外连接、同时训练多个分辨率可参考 Multi-Scale Gradient GANs 论文。风格迁移用损失函数重绘图片GAN 是生成艺术图像的好方法另一项有趣的技术是风格迁移Style Transfer取一张内容图content image使用**风格图style image**的滤波器以不同风格重新绘制内容图。其工作流程如下从随机噪声图像开始也可从内容图开始但为便于理解教程默认从随机噪声出发目标是得到一张既接近内容图、又接近风格图的图像这由两个损失函数决定内容损失Content Loss基于 CNN 在特定层对当前图像与内容图提取的特征计算得出风格损失Style Loss使用Gram 矩阵巧妙地在当前图像与风格图之间计算细节见示例 Notebook。为使图像更平滑、去除噪声引入全变分损失Variation Loss它计算相邻像素之间的平均距离主优化循环用梯度下降或其他优化算法不断调整当前图像最小化三者加权和构成的总损失。StyleTransfer.ipynb 中给出了具体实现加载 VGG16include_topFalse, weightsimagenet作为特征提取器通过content_loss、gram_matrix与style_loss等函数分别计算各部分损失并在多尺度层上综合风格损失每个层可配权重系数。其损失函数形式为$$\mathcal{L(x)} \alpha\mathcal{L}_c(x,i) \beta\mathcal{L}_s(x,s) \gamma\mathcal{L}_t(x)$$其中 $\mathcal{L}_c$ 为内容损失$\mathcal{L}_s$ 为风格损失$\mathcal{L}_t$ 为全变分损失$\alpha$、$\beta$、$\gamma$ 为各项权重。使用自己的图片运行该 Notebook即可体验AI 作画。总结与实战建议在本课中你学到了GAN 的对抗训练框架与生成器/判别器的角色分工判别器的图像分类架构与生成器的反卷积生成架构两阶段训练流程先训判别器、再冻结判别器训生成器以及训练损失呈现震荡的本质原因基于 Keras 的全连接 GAN 与 DCGAN 的完整实现细节LeakyReLU、BatchNormalization、tanh 输出、Adam 优化器GAN 训练的模式坍缩、超参数敏感、平衡失控与高分辨率伪影四大难题及应对策略风格迁移的原理与 Gram 矩阵损失、内容损失、全变分损失的组合方式。作为课后挑战可以重新运行本课的两个 Notebook 之一GANTF.ipynb 或 StyleTransfer.ipynb用你自己的图片重新训练 GAN 或执行风格迁移看看你能创造出什么。更进一步可将 Dense 版 GAN 升级为 DCGAN 在完整 MNIST 上训练或尝试为生成器与判别器设置不同学习率观察训练震荡与收敛的变化。赞分享教程人工智能机器学习深度学习【免费下载链接】AI-For-Beginners12 Weeks, 24 Lessons, AI for All!项目地址https://gitcode.com/GitHub_Trending/ai/AI-For-Beginners点击查看免费下载相关推荐AI-For-Beginners 第 10 课深度解析生成对抗网络GAN与风格迁移实战AI For Beginners 第 10 课深度解析生成对抗网络GAN与风格迁移实战 导读 本文基于 AI For Beginners 开源课程 第 1教程人工智能机器学习深度学习生成对抗网络 GAN 实战指南对抗式训练、训练难题与风格迁移 —— AI-For-Beginners 课程详解生成对抗网络 GAN 实战指南对抗式训练、训练难题与风格迁移 —— AI For Beginners 课程详解 本指南深入讲解 AI For Beginner教程人工智能机器学习深度学习AI-For-Beginners 课程深度解析生成对抗网络GANs原理、训练实战与风格迁移实现AI For Beginners 课程深度解析生成对抗网络GANs原理、训练实战与风格迁移实现 生成对抗网络Generative Adversarial教程人工智能机器学习深度学习创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表