DeepLearningAI-2025-笔记-全-

DeepLearningAI 2025 笔记(全)

P10:【2025版】第10课:GAN组件详解与深度卷积GAN 🧠

在本节课中,我们将深入学习构建生成对抗网络(GAN)的核心组件。上周我们初步体验了构建一个基本GAN的过程,本周我们将深入剖析这些组件,并探讨如何利用它们来改进图像生成的效果。

概述

我们将逐一检查上周使用过的组件,并学习专门用于改进图像生成型GAN的技术。这包括激活函数(如ReLU和Sigmoid)、批量归一化卷积操作填充与步幅,以及上采样转置卷积。理解这些组件是构建更强大GAN模型,特别是用于图像生成的深度卷积生成对抗网络的重要基础。


激活函数:ReLU与Sigmoid

上一节我们概述了本周的学习内容,本节中我们来看看神经网络中两个关键的激活函数:ReLU和Sigmoid。激活函数为神经网络引入了非线性,使其能够学习复杂模式。

以下是两种常见激活函数的介绍:

  • ReLU (Rectified Linear Unit):这是最常用的激活函数之一。它将所有负值置零,正值保持不变。其公式简单,能有效缓解梯度消失问题,并加速训练。
    • 公式f(x) = max(0, x)
  • Sigmoid:它将输入值压缩到(0, 1)的区间内。在GAN中,生成器(Generator)的输出层常使用Sigmoid,将数据映射到有效的像素值范围(如0到255归一化后的0到1);判别器(Discriminator)的输出层也用它来输出一个概率值。
    • 公式f(x) = 1 / (1 + e^(-x))

批量归一化

了解了激活函数如何引入非线性后,我们来看看另一个加速和稳定训练的技术:批量归一化。它通过规范化每一层输入的分布,可以减少内部协变量偏移,允许使用更高的学习率。

其核心操作是对一个批次(Batch)的数据进行标准化处理,然后进行缩放和平移。


卷积、填充与步幅

现在,让我们回顾卷积神经网络的基础操作。这些是处理图像数据的核心,无论是判别器识别图像,还是生成器构造图像都离不开它们。

以下是卷积相关的三个核心概念:

  • 卷积:通过一个小的滤波器(或卷积核)在输入图像上滑动并计算点积,从而提取局部特征(如边缘、纹理)。
  • 填充:在输入图像的边缘周围添加额外的像素(通常为0)。这有助于控制输出特征图的空间尺寸,防止图像在多次卷积后变得过小。
  • 步幅:指滤波器每次滑动时移动的像素数。步幅增大,输出特征图的尺寸会减小,这可以降低计算量并扩大感受野。

上采样与转置卷积

上一节我们回顾了用于下采样的卷积操作,本节中我们来看看生成器如何“放大”或构造图像。在生成器中,我们需要将一个小的高维向量(如随机噪声)逐步“解码”成一张完整的图像,这个过程需要增加数据的空间尺寸。

以下是两种常用的上采样方法:

  • 上采样:一种简单的放大方法,例如使用最近邻插值或双线性插值来增加特征图的高度和宽度。它不包含可学习的参数。
  • 转置卷积:有时被不太准确地称为“反卷积”。它是一种可学习的上采样操作,通过学习的卷积核来重建更大尺寸的特征图。它是构建生成器,特别是DCGAN的关键组件。

总结

本节课中,我们一起学习了构建和改进图像生成GAN模型的核心组件。我们从ReLU和Sigmoid激活函数的作用开始,探讨了批量归一化对训练稳定性的贡献。接着,我们回顾了卷积、填充和步幅这些基础但至关重要的操作。最后,我们对比了上采样转置卷积,理解了生成器如何构造图像。掌握这些组件,为我们接下来动手构建一个更强大的深度卷积生成对抗网络奠定了坚实的理论基础。

P11:【2025版】11.激活函数的基本属性 🧠 - 小土堆Pytorch教程

在本节课中,我们将要学习神经网络中激活函数的基本概念、核心属性及其重要性。激活函数是构建深度学习模型的关键组件,理解其工作原理对于掌握神经网络至关重要。


概述

激活函数是一个数学函数,它接收任意实数作为输入(即其定义域),并输出一个特定范围内的数值。激活函数通常是非线性且可微分的函数。在深度神经网络中,激活函数通常被用在某些层之间,尤其是在进行分类等复杂任务时。本教程将详细解释激活函数的概念、其必须满足的属性,以及它们在神经网络中的作用。


激活函数的作用

上一节我们概述了激活函数的基本定义,本节中我们来看看它在神经网络中的具体位置和作用。

考虑一个用于预测图像是否为猫的神经网络。该网络可能有两个隐藏层和多个输入特征。例如,X0 可能代表毛色,X1 代表动物大小,以及其他各种特征。网络的最终输出是一个介于0到1之间的概率值,表示“是猫”的可能性。

那么,网络中间的所有节点是如何工作的呢?这些节点共同构成了整个神经网络的架构。要理解这一点,我们需要从单个节点的操作开始。


单个节点的计算过程

一个节点从前一层接收信息,并进行两项主要计算。我们可以用一条虚线将这个过程分开来看。

首先,节点计算一个值 z。这里的 i 表示当前是第几个节点(例如,第一个节点 i=1),l 表示当前所在的层(例如,第一层 l=1)。

z 的计算公式是前一层所有输出的加权和:

公式: z_i^l = Σ (w_ij^l * a_j^{l-1}) + b_i^l

其中:

  • a_j^{l-1} 是前一层(第 l-1 层)第 j 个节点的输出。
  • w_ij^l 是连接前一层第 j 个节点到当前层第 i 个节点的权重。
  • b_i^l 是当前节点的偏置项。
  • 求和范围 j0n(前一层节点的总数)。

这部分计算通常被称为线性层,因为它只涉及输入的线性加权组合。

在计算完 z 之后,节点会应用一个激活函数 g。节点的最终输出 a 是激活函数作用于 z 的结果:

公式: a_i^l = g(z_i^l)


激活函数的两个核心属性

上一节我们介绍了节点如何计算 za,本节中我们重点看看激活函数 g 本身。激活函数必须满足两个核心属性:非线性可微分

1. 可微分性

激活函数需要是可微分的,这意味着它必须有导数(或者说梯度)。这一点至关重要,因为神经网络通过反向传播算法来训练和更新其参数(权重和偏置)。反向传播需要计算损失函数相对于每个参数的梯度,这个过程依赖于链式法则,要求网络中每一层的变换(包括激活函数)都是可微分的,以便梯度能够从输出层一直传递回输入层。

2. 非线性

激活函数必须是非线性的。如果神经网络中只使用线性运算(即没有非线性激活函数),那么无论堆叠多少层,整个网络都可以被等价地简化为一个单一的线性变换。

公式推导(简化理解):
假设有两层线性变换:layer2_output = W2 * (W1 * X + b1) + b2
这可以合并为:layer2_output = (W2 * W1) * X + (W2 * b1 + b2)
W_combined = W2 * W1b_combined = W2 * b1 + b2
最终得到:layer2_output = W_combined * X + b_combined,这仍然只是一个线性回归模型。

因此,非线性激活函数的引入,确保了堆叠的多个层能够真正构建出复杂的、非线性的函数,从而让神经网络有能力学习数据中复杂的模式和关系。线性回归本身就是一个带有偏置项的线性层,缺乏处理复杂非线性问题的能力。


总结

本节课中我们一起学习了激活函数的基本属性。

  1. 作用:激活函数是神经网络层之间的非线性变换单元,它决定了节点的最终输出 a
  2. 核心属性:激活函数必须同时具备非线性可微分两个属性。
    • 非线性确保了多层神经网络不会退化为简单的线性模型,使其能够学习和表示复杂的函数。
    • 可微分确保了反向传播算法可以顺利进行,使得网络能够通过梯度下降来学习和优化参数。
  3. 灵活性:只要满足非线性和可微分的条件,理论上任何自定义函数都可以用作激活函数。研究人员会通过实验来探索不同激活函数在不同任务上的效果。

理解激活函数的这些基本属性,是深入学习各种具体激活函数(如Sigmoid、ReLU、Tanh等)及其应用场景的重要基础。

P12:常见的激活函数 🧠

在本节课中,我们将学习深度学习模型中至关重要的组件——激活函数。激活函数为神经网络引入了非线性,使其能够学习和模拟复杂的数据模式。我们将重点介绍四种最常用的激活函数:ReLU、Leaky ReLU、Sigmoid 和 Tanh,并探讨它们各自的特性、优缺点。

概述 📋

激活函数是神经网络中的非线性变换,它决定了神经元是否应该被激活。没有激活函数,无论神经网络有多少层,其输出都将是输入的线性组合,从而无法学习复杂的模式。本节将详细介绍四种常见的激活函数,帮助你理解它们的工作原理及适用场景。

1. ReLU(修正线性单元)⚡

上一节我们介绍了激活函数的重要性,本节中我们首先来看看最受欢迎的激活函数之一——ReLU。

ReLU 函数的定义非常简单:它取输入值 z 和 0 之间的最大值。其数学公式如下:

g(z) = max(0, z)

这意味着,如果输入 z 是正数,输出就等于 z;如果 z 是负数或零,输出则为 0。从图形上看,ReLU 函数在正数区域是一条斜率为 1 的直线,在负数区域则是一条值为 0 的水平线,形状类似于一个“曲棍球棍”。这种特性使其成为一个非线性函数。

以下是 ReLU 函数的关键特点:

  • 非线性:其“曲棍球棍”形状打破了线性关系。
  • 计算高效:只涉及简单的比较和赋值操作。
  • 缓解梯度消失:在正数区域,梯度恒为 1,有助于梯度在深层网络中传播。

然而,ReLU 也存在一个显著的问题。

2. Leaky ReLU(带泄漏的修正线性单元)💧

上一节我们了解到 ReLU 在输入为负时输出为零,这可能导致“神经元死亡”问题。为了解决这个问题,我们来看看 ReLU 的一个变体——Leaky ReLU。

Leaky ReLU 对 ReLU 进行了微调:当输入 z 为负时,它不再输出 0,而是输出一个很小的、非零的值。其数学公式通常定义为:

g(z) = max(αz, z)

其中,α 是一个很小的超参数(例如 0.01)。这意味着,当 z 为负时,输出是一个很小的斜率(α)乘以 z,从而确保导数不为零。

以下是 Leaky ReLU 的主要改进:

  • 解决“死亡ReLU”问题:负值区域有一个小的斜率,使得梯度可以继续反向传播。
  • 保持稀疏性:虽然负值区域有输出,但值非常小,依然保持了 ReLU 的部分稀疏激活特性。
  • 超参数 α:通常设置为一个很小的固定值(如 0.01),也可以作为可学习的参数。

在实践中,ReLU 仍然被广泛使用,但 Leaky ReLU 在处理某些问题时能提供更稳定的训练效果。

3. Sigmoid 函数 📈

前面我们介绍了两种基于线性修正的激活函数。现在,我们来看看两种形状相似、但输出范围不同的经典函数。首先是 Sigmoid 函数。

Sigmoid 函数将任何实数输入“挤压”到 (0, 1) 区间内,其形状是一个平滑的“S”形曲线。其数学公式为:

g(z) = 1 / (1 + e^{-z})

z 为正且很大时,输出趋近于 1;当 z 为负且绝对值很大时,输出趋近于 0;当 z 为 0 时,输出为 0.5。

以下是 Sigmoid 函数的常见用途与问题:

  • 输出为概率:由于其输出在 0 到 1 之间,它经常被用作二分类模型输出层的激活函数,以表示概率。
  • 梯度消失问题:在函数的“尾部”(即当 z 的绝对值很大时),Sigmoid 函数的导数趋近于 0。这会导致在反向传播时,梯度难以更新较早层的权重,使得网络训练缓慢甚至停滞,这被称为“梯度消失”或“饱和”问题。
  • 非零中心化:其输出恒大于 0,这可能导致后续层的输入始终为正,影响梯度下降的效率。

因此,Sigmoid 函数现在较少用于神经网络的隐藏层。

4. Tanh(双曲正切)函数 🔄

与 Sigmoid 函数形状相似但输出范围不同的是 Tanh 函数。它解决了 Sigmoid 函数非零中心化的问题。

Tanh 函数同样是一个“S”形曲线,但它将输入“挤压”到 (-1, 1) 区间内。其数学公式为:

g(z) = (e^{z} - e^{-z}) / (e^{z} + e^{-z})

Tanh 函数是零中心化的,即当输入为 0 时,输出也为 0。这使得其输出均值更接近 0,有助于加速收敛。

以下是 Tanh 函数的特点:

  • 零中心化:输出范围在 -1 到 1 之间,改善了梯度流动。
  • 与 Sigmoid 的关系tanh(z) = 2 * sigmoid(2z) - 1
  • 同样存在梯度消失:和 Sigmoid 一样,在 |z| 很大时,Tanh 函数的导数也会趋近于 0,导致梯度消失问题。

尽管存在梯度消失问题,Tanh 在循环神经网络(RNN)等模型中仍有应用。

总结 🎯

本节课我们一起学习了深度学习中四种常见的激活函数:

  1. ReLU:计算高效,能缓解梯度消失,但存在“神经元死亡”风险。
  2. Leaky ReLU:ReLU 的改进版,通过引入一个小的负斜率来解决“死亡”问题。
  3. Sigmoid:将输出压缩到 (0,1),常用于输出层表示概率,但易导致梯度消失和训练缓慢。
  4. Tanh:将输出压缩到 (-1,1),是零中心化的,但同样面临梯度消失的挑战。

每种激活函数都有其适用的场景和局限性。在实际构建神经网络(包括后续将要学习的 GAN)时,ReLU 及其变体通常是隐藏层的首选,而 Sigmoid 或 Tanh 可能用于特定的输出层。理解这些函数的特性,将帮助你更好地设计和调试神经网络模型。

P13:【2025版】13. 批归一化详解 🧠 - 小土堆Pytorch教程

在本节课中,我们将要学习批归一化(Batch Normalization)的核心概念。我们将了解它如何加速并稳定神经网络的训练过程,特别是在训练生成式对抗网络(GAN)这类复杂模型时。课程将首先回顾归一化对训练的影响,然后解释内部协变量偏移的含义,最后将所有这些概念与批归一化联系起来,帮助你建立直观理解。


训练神经网络需要大量时间,尤其是在进行非常酷的应用时。

生成式对抗网络在训练过程中往往比较脆弱。

它们不像分类器那样直接。有时,生成器和判别器的技能并不总是那么一致。它们本可以更好。出于这些原因,所有可以加速并稳定训练的技巧对于这些模型都至关重要。

批标准化已被证明在这方面非常有效。

所以让我们开始。我会提醒你归一化对训练的影响。

我会向你展示内部协变量偏移的含义以及为什么会发生。

最后,你将能够将所有这些与批标准化联系起来。

并且你会对这为何加速并稳定神经网络的训练产生一些直觉。


一个简单的神经网络示例 🐱

假设你有一个非常简单的神经网络,有两个输入变量:x1表示大小,x2表示毛色。有一个激活输出。这个示例基于这些特征判断是否是猫。

并且让我们假设x1的分布在这里。你的数据集大小通常以这种方式围绕一个中等大小的示例分布。例如,非常少的极端小或极端大的例子。而毛色分布的偏斜稍微向更高的值倾斜。在这里,具有更高的均值和更低的标准差。

所以假设这里的更高值代表更深的毛色。当然,请注意,比较毛色的相同值,与比较苹果与橘子有点类似,因为深色毛发和大体型并没有实际的相关性。然而,这些不同分布的结果会影响神经网络的学习方式。

输入分布差异带来的问题 ⚠️

例如,如果它试图达到这个局部最小值。

并且输入数据分布差异很大,这个成本函数会被拉长。

因此权重的变化,与每个输入的关系会有不同的影响,对成本函数的影响各不相同。这使得训练相当困难。这会减慢训练速度,并且高度依赖于权重的初始化。

此外,如果新的训练或测试数据有。

假设,颜色非常浅,因此数据分布可能会改变或以某种方式变化。

那么成本函数的形式也可能会改变。所以可以看到这里稍微圆一些,并且最小值的位置也可能会移动。即使决定某物是否为猫的真实情况保持不变。

标签没有改变。这就是所谓的协变量偏移。这在训练集和测试集之间经常发生,如果没有采取预防措施。

输入归一化的效果 📊

数据分布如何变化。但如果输入变量x1x2被归一化。

意味着新输入变量x1'x2'的分布,将更加相似。将更加相似,说意味着等于零,标准差等于一。

那么成本函数也会在这些两个维度上显得更平滑、更平衡。

作为结果,训练实际上会容易得多,并且可能更快。

无论原始输入变量的分布如何变化。

例如,从训练到测试,归一化变量的均值和标准差会被归一到相同的位置。所以围绕均值零和标准差一。

并且对于训练数据,这是通过批处理统计量来完成的。因此,在你训练每个批次时,你计算平均值和标准差。

并将它们调整为零均值和一标准差。对于测试数据,你所做的是,你可以查看统计量,这些统计量是在训练过程中收集的,并用它们来使测试数据更接近训练数据,以进行归一化。这种协变量偏移的影响将显著降低。

这就是输入变量归一化的主要效果:平滑成本函数,减少协变量偏移。然而,协变量偏移不应该是一个问题。

如果,你只确保,你的数据集的分布与你建模的任务相似。

所以测试集与你的训练集相似,在分布方面。

内部协变量偏移 🔄

神经网络就像我所展示的这个,实际上是容易受到称为内部协变量偏移的东西的影响。

这就意味着内部隐藏层的协变量偏移。

所以,取神经网络的第一个隐藏层的激活输出的输出,看这里这个节点。在训练模型时,影响激活值的所有权重都会被更新。因此,激活中的值的分布会随着训练的变化而变化,并且会受到这种训练过程的影响。

这使得训练过程变得困难。由于与输入变量分布变化相似的偏移。例如,毛色,只对内部节点有影响,这些节点比颜色和大小的意义更抽象。

批归一化的解决方案 🛠️

现在批标准化试图解决这个问题。

并基于每个输入批次计算的统计数据对所有这些内部节点进行标准化。这样做的目的是减少内部协变量偏移。这还具有平滑成本函数的额外好处,从而使神经网络更容易训练并加快整个训练过程。

批标准化中的“批”字意味着使用批次统计。

随着您继续本周的视频,您将更熟悉这一点。


总结 📝

本节课中我们一起学习了批归一化的核心原理。

批标准化平滑了成本函数并减少了内部协变量偏移的影响。它用于加快和稳定训练,在建立伟大的GANs时非常有用。

需要注意的一点是,虽然批标准化对我们的GAN和更广泛的神经网络非常有效。

内部协变量偏移的理论背后并不具有决定性。我们仍在寻找其他原因的证据。

P14:【2025版】14. 批归一化过程 📊 - 小土堆Pytorch教程

在本节课中,我们将学习批归一化的核心概念与工作原理。批归一化是深度学习中一项重要的技术,它通过规范化神经网络中间层的激活值分布,来加速训练并提升模型稳定性。我们将从零开始理解其计算过程,并了解其在训练与测试阶段的差异。

批归一化概述

批归一化听起来可能有些复杂,但其过程相当直接。虽然你可以从零开始实现它,但像PyTorch这样的深度学习框架已经内置了此功能。本教程将向你展示它是如何工作的。

你将了解批归一化操作,以及它在训练和测试期间的不同之处。批归一化的目标是创建归一化的值分布。

批归一化的工作流程

假设我们有一个包含两个隐藏层的神经网络。它有多个输入和一个输出。为了解释批归一化如何工作,我们将聚焦于其中一个内部的隐藏层。

从输入开始,这里的 Z 来自前一层的所有节点。批归一化会考虑批次中每个样本的张量 Z_i。例如,你可以有一个批次大小为32,那么你就会有32个 Z 值。需要提醒的是,这里的下标 i 表示这是该层中的第 i 个节点,而上标 l 表示这是第 l 层。

因此,批归一化会取一个批次(例如32个样本)的 Z 值,并希望将其归一化,使其均值为0,标准差为1。

以下是实现这一目标的具体步骤:

  1. 计算批次均值与方差:首先,计算该批次数据的均值 μ 和方差 σ²

    • 均值公式:μ = (1/m) * Σ Z_i,其中 m 是批次大小。
    • 方差公式:σ² = (1/m) * Σ (Z_i - μ)²
  2. 归一化:然后,使用计算出的均值和方差对每个 Z 值进行归一化,得到

    • 归一化公式:Ẑ = (Z - μ) / √(σ² + ε)
    • 这里添加了一个极小的常数 ε(例如 1e-5),是为了防止分母为零,确保数值稳定性。

引入可学习参数

在得到归一化值 之后,批归一化层会引入两个可学习的参数:缩放因子 γ 和偏移量 β。这些参数在训练过程中通过梯度下降进行学习。

其目的是确保网络能将 Z 值归一化为对当前任务最优的分布,而不是强制其始终保持均值为0、标准差为1。这是批归一化与简单的输入归一化的主要区别。

以下是应用可学习参数的步骤:

  1. 缩放与偏移:使用学习到的 γβ 对归一化后的值 进行缩放和偏移。
    • 最终输出公式:Y = γ * Ẑ + β

这个经过缩放和偏移后的值 Y,随后会被送入激活函数(如ReLU),作为下一层的输入。

训练与测试模式的差异

在训练和测试期间,批归一化的行为有所不同,这是为了保证模型的稳定性。

在训练时,我们使用当前小批次的统计数据(均值和方差)进行归一化。这带来了两个好处:一是减少了计算量,无需等待整个数据集;二是引入了轻微噪声,可能起到正则化的效果。

在测试/推理时,我们不再使用单个批次的统计数据。因为同一个样本在不同批次中,会因批次统计量的不同而被归一化成不同的值,导致预测不稳定。

为了解决这个问题,在测试时我们使用的是在整个训练集上计算得到的运行均值运行方差。这些统计量在训练过程中通过移动平均的方式不断更新,训练结束后便固定下来。测试时的计算过程与训练时类似,只是替换了使用的统计量:

  • 测试时归一化公式:Ẑ_test = (Z - μ_running) / √(σ²_running + ε)

你无需过度担心这些统计量的具体维护细节。像TensorFlow和PyTorch这样的框架会自动跟踪这些运行统计量。你只需要创建一个批归一化层,当模型切换到评估模式(model.eval())时,框架会自动使用运行统计量。

核心要点总结

本节课我们一起学习了批归一化的完整过程。我们来总结一下关键点:

  • 与标准归一化的区别:批归一化在训练时使用每个小批次的统计量,而非整个数据集,这提升了训练效率。
  • 引入灵活性:通过可学习的参数 γβ,网络可以学习最适合当前任务的分布,而不被强制约束为零均值和单位方差。
  • 保证预测稳定性:在测试时,使用训练阶段积累的运行统计量,确保了相同输入在不同时间会得到相同的输出。
  • 框架支持:现代深度学习框架完整实现了训练和测试时的整个流程,开发者只需正确调用即可。

批归一化是构建稳定、高效深度学习模型的重要工具,理解其原理将帮助你在构建GAN或其他复杂模型时更好地应用它。在接下来的课程中,我们还将接触到更多先进的归一化技术。

P15:【2025版】15. 卷积回顾 🧠 - 小土堆Pytorch教程

在本节课中,我们将要学习卷积(Convolution)这一核心概念。卷积是图像处理的关键部分,也是许多生成对抗网络(GAN)架构中的重要组成部分。

概述:什么是卷积?

卷积允许你在图像的不同区域检测关键特征。例如,使用特定的滤波器(Filter)可以识别图像中的眼睛、鼻子或耳朵等特征。这些滤波器通过扫描图像来定义各种特征。

卷积的工作原理

上一节我们介绍了卷积的基本概念,本节中我们来看看卷积具体是如何工作的。我们将通过一个简单的例子来理解卷积操作。

图像与滤波器

假设我们有一张5x5的灰度图像。图像中的每个小方块代表一个像素,其值在0到255之间。0表示完全黑色的像素,255表示完全白色的像素,灰色值介于两者之间。

滤波器(也称为卷积核)是一个实数值矩阵,其确切的值是在神经网络的训练过程中学习得到的。例如,一个用于检测眼睛的滤波器,其值会被训练成能对图像中的“眼睛”模式产生高响应。

卷积操作步骤

卷积操作本身非常简单。以下是其计算过程:

  1. 对齐与相乘:将滤波器覆盖在输入图像的左上角区域。
  2. 计算点积:将滤波器中的每个值与对应位置的图像像素值相乘。
  3. 求和:将所有乘积结果相加,得到一个单一的输出值。
  4. 滑动与重复:将滤波器向右滑动一个位置(步长通常为1),重复步骤1-3,直到覆盖图像的整个宽度。
  5. 换行:当到达图像右边界后,将滤波器向下移动一行,并从最左侧重新开始,重复上述过程,直到扫描完整张图像。

这个过程可以用以下伪代码描述:

# 假设 input_image 是输入图像, kernel 是滤波器
output_height = (input_height - kernel_height) + 1
output_width = (input_width - kernel_width) + 1
output = zeros_matrix(output_height, output_width)

![](https://github.com/OpenDocCN/dsai-notes-zh/raw/master/docs/dlai25/img/ccf98e693d2bb897e8c8a88622207296_23.png)

for i in range(output_height):
    for j in range(output_width):
        # 提取当前图像区域
        region = input_image[i:i+kernel_height, j:j+kernel_width]
        # 计算点积并求和
        output[i, j] = sum(region * kernel)

一个具体例子

假设我们有一个学习到的3x3滤波器,其值为 [1, 0, -1](这是一个简化的垂直边缘检测器)。我们将其应用到一个5x5的灰度图像上。

从图像左上角开始,滤波器与图像的第一个3x3区域对齐。我们将每个对应的值相乘(例如,图像像素值乘以滤波器的1、0或-1),然后将所有乘积相加,得到的结果就是输出特征图(Feature Map)的第一个值。

接着,将滤波器向右滑动一个像素,重复计算,得到第二个值。如此反复,直到生成一个3x3的输出特征图。

这个特定的滤波器是一个垂直线检测器。当它扫过图像中的垂直边缘时,计算出的值会非常高,从而在输出特征图中突出显示该边缘的位置。

从特征到高级概念

单一的滤波器(如边缘检测器)只能捕捉基础特征。然而,通过组合多层这样的滤波器,神经网络能够逐步构建出更抽象、更高级的概念。

例如,第一层卷积可能检测到简单的边缘和角落;第二层可能将这些边缘组合成眼睛或鼻子的轮廓;更深的层则可能识别出完整的脸部结构。这就是卷积神经网络(CNN)能够理解复杂图像内容的原理。

总结

本节课中我们一起学习了卷积的核心知识。我们了解到,卷积是图像处理中用于识别模式的关键操作。它通过滤波器扫描图像的每一部分,进行乘加运算,从而检测从简单边缘到复杂物体的一系列特征。理解这个基础操作,是掌握卷积神经网络和现代计算机视觉技术的基石。

在接下来的课程中,我们将探讨对卷积操作的一些调整和优化,例如步长(Stride)、填充(Padding)等,这些将帮助我们更有效地构建网络。

P16:【2025版】16. 填充和步幅 🧩

在本节课中,我们将学习卷积神经网络中的两个重要概念:填充步幅。它们是调整卷积操作、控制输出特征图尺寸以及平衡计算效率的关键技术。

上一节我们介绍了基础的卷积操作,本节中我们来看看如何通过调整步幅和填充来优化这个过程。

回顾卷积操作

卷积是一种简单的操作,用于在图像的不同区域检测特征。在之前的视频中,展示了如何将卷积核应用到图像上。接下来,将展示一些调整卷积操作的方法。

理解步幅 🚶‍♂️

步幅决定了卷积核在输入图像上每次滑动的距离。以下是关于步幅的详细说明。

当你将一个3x3的卷积滤波器应用到图像上时,首先计算滤波器与图像左上角3x3区域的元素级乘积。

然后,你向右移动一个像素,进行相同的计算。

接着,你将滤镜向下移动一个像素,并从最左侧重新开始。

这个过程持续进行,直到到达图像的右下角。这种每次向右或向下移动一个像素的方式,被称为使用步长1

所以,你每次移动一个像素,步长为1。

向右移动的步长不必与向下移动的步长相同。例如,你的步长可以是向右2个像素,向下4个像素。

你的步幅越大,卷积核覆盖的图像区域就越少,这能为你的滤波器节省更多的计算空间。

但同时,更大的步幅会使计算速度更快。这绝对是一个需要在覆盖率和计算效率之间进行的权衡。

所以,步幅为2意味着每次你向右移动两步。

你的滤波器从左上角开始,但现在每次向右移动两个像素。

因为它在上下两个方向也移动,所以你在那里向下移动两个像素,因此只进行一次计算。

这更快。正如你所见,步幅决定了过滤器访问图像的多少部分。

在这个例子中,卷积的结果现在是一个更小的2x2矩阵。

因为你只访问了四个3x3区域中的滤波器,两个在上,两个在下。

理解填充 🖼️

填充是基本卷积的另一种调整。以下是关于填充的详细说明。

观察这个3x3的图像和2x2的滤波器。这里的像素值并不重要,所以已经把它们放在外面了。当你计算步幅为1的卷积时,在这种情况下,你将访问图片的四个部分。

分别是左上角、右上角、左下角和右下角。最后,中心像素被访问了四次,角落的像素只被访问一次,而边缘的其他像素被访问两次。这意味着中心保存的信息比边缘的信息获得更多的关注,这通常是正确的。

这是一个问题。假设边缘的特征是你关心的,例如,这可能是图像中一只完整的狗,或者可能是狗的一部分,比如它的鼻子。这是有用的信息,你想要确保你的滤波器对整个图像施加同等重要的强调。

为了解决这个问题,你可以给图像添加一个边框,这样所有的信息都出现在这个新图片的中心,就像被框起来的图片。

这叫做填充。填充的大小可以根据你的滤波器和图片的大小而变化。填充的值可以是任何实际值,但通常被设置为零,这叫做零填充

所以,在你进行卷积计算之前,滤波器会扫描图像及其边框。

但这次,结果是图像中的每个原始像素都被访问了相同的次数。真正访问次数少的只是新添加的边框像素。这是因为现在图像中的每个原始像素都位于中心,被那个边框所包围。

总结 📝

本节课中我们一起学习了卷积神经网络中的两个核心调整参数。

  • 步幅:告诉滤波器如何扫描图像,它影响输出特征图的大小以及原始像素被访问的频率。步幅越大,输出尺寸越小,计算越快,但可能丢失一些空间信息。

    • 公式:若输入尺寸为 \(n \times n\),滤波器尺寸为 \(f \times f\),步幅为 \(s\),则输出尺寸约为 \(\lfloor \frac{n - f}{s} + 1 \rfloor \times \lfloor \frac{n - f}{s} + 1 \rfloor\)
  • 填充:就像在图像周围放置一个边框,以便给图像的边缘像素和中心像素相同的重要性。最常用的是零填充。

    • 公式:若填充大小为 \(p\),则输出尺寸变为 \(\lfloor \frac{n + 2p - f}{s} + 1 \rfloor \times \lfloor \frac{n + 2p - f}{s} + 1 \rfloor\)

通过合理设置步幅和填充,我们可以控制特征图的尺寸,保护边缘信息,并在模型的表达能力和计算成本之间取得平衡。

P17:池化与上采样 🧠

在本节课中,我们将学习卷积神经网络中两个重要的操作:池化与上采样。池化用于减小输入数据的尺寸,而上采样则用于增加其尺寸。理解这两个概念对于构建和理解现代深度学习模型至关重要。

池化操作 📉

上一节我们介绍了卷积神经网络的基本概念,本节中我们来看看池化操作。池化是一种用于减小输入图像或特征图尺寸的操作,它通过取特定区域(如2x2窗口)内的平均值或最大值来实现。这样做可以降低后续层的计算成本,同时保留最重要的信息。

以下是池化操作的核心特点:

  • 目的:降低输入数据的空间尺寸(高度和宽度),减少参数和计算量,并提取最显著的特征。
  • 常见类型
    • 最大池化:取窗口内的最大值。公式可表示为:输出值 = max(窗口内所有值)
    • 平均池化:取窗口内的平均值。
    • 最小池化:取窗口内的最小值。
  • 关键属性:池化层没有可学习的参数。它只是对输入数据应用一个固定的数学规则(如取最大值)。

让我们通过一个最大池化的例子来具体理解。假设我们有一个4x4的灰度图像,使用一个2x2的池化滤波器,步长为2。

原始输入(4x4):

[[10, 12, 20, 18],
 [ 8, 14, 45, 22],
 [15,  9, 25, 30],
 [11,  7, 40, 35]]

池化过程:

  1. 第一个2x2窗口 [[10,12],[8,14]] 的最大值是 14
  2. 第二个窗口 [[20,18],[45,22]] 的最大值是 45
  3. 第三个窗口 [[15,9],[11,7]] 的最大值是 15
  4. 第四个窗口 [[25,30],[40,35]] 的最大值是 40

因此,经过最大池化后,我们得到一个2x2的输出:

[[14, 45],
 [15, 40]]

这个过程提炼了每个区域最显著(值最大)的信息。

上采样操作 🔍

了解了如何通过池化缩小尺寸后,本节我们来看看与之相反的操作——上采样。上采样的目标是增加输入数据的尺寸,将低分辨率图像转换为高分辨率图像。这需要为新增的像素点推断出合理的值。

以下是上采样操作的要点:

  • 目的:增加输入数据的空间尺寸。
  • 常见方法
    • 最近邻上采样:为输出图像的每个像素,分配输入图像中距离最近的像素值。这是一种简单快速的方法。
    • 双线性插值:根据输入中最近的2x2邻域像素,通过线性插值计算输出像素值。这种方法能产生更平滑的结果。
  • 关键属性:与池化类似,基本的上采样层也没有可学习的参数,它遵循固定的插值或填充规则。

以最近邻上采样为例,将一个2x2图像上采样到4x4。

原始输入(2x2):

[[1, 3],
 [4, 2]]

上采样过程(放大2倍):

  1. 将每个输入像素值复制到一个2x2的块中。
  2. 左上角像素 1 复制到输出的左上2x2区域。
  3. 右上角像素 3 复制到输出的右上2x2区域。
  4. 左下角像素 4 复制到输出的左下2x2区域。
  5. 右下角像素 2 复制到输出的右下2x2区域。

最终得到4x4输出:

[[1, 1, 3, 3],
 [1, 1, 3, 3],
 [4, 4, 2, 2],
 [4, 4, 2, 2]]

在实际应用中,我们通常无需手动实现这些上采样算法,因为深度学习框架(如PyTorch、TensorFlow)已经提供了封装好的函数。

总结 📚

本节课中我们一起学习了卷积神经网络中的池化与上采样操作。

  • 池化(如最大池化)用于减小特征图尺寸,提取关键特征,并降低计算复杂度。它是一个无参数的固定操作。
  • 上采样(如最近邻插值)用于增大特征图尺寸,为后续处理或输出做准备。它同样是一个无参数的固定操作。
  • 两者都与卷积操作不同,没有需要训练的可学习权重

理解这两个基础操作,是掌握更复杂网络结构(如编码器-解码器结构的U-Net等)的重要一步。在接下来的课程中,我们将看到它们如何被应用到实际的神经网络模型中。

P18:【2025版】18. 转置卷积 🧩

在本节课中,我们将学习转置卷积。这是一种用于上采样的技术,它使用可学习的滤波器来扩大输入数据的尺寸。我们将了解其工作原理,并探讨它可能带来的一个特殊问题。


概述

你已经熟悉了卷积、池化和上采样层。本节我们将介绍转置卷积。转置卷积是一种上采样方法,它通过一个可学习的滤波器来放大输入尺寸。然而,这种方法的输出可能会产生一个被称为“棋盘格问题”的特殊现象。


转置卷积的工作原理

上一节我们介绍了转置卷积的基本概念。本节中我们来看看它的具体计算过程。

转置卷积的操作程序与常规卷积非常相似。以下是一个使用2x2输入、2x2滤波器、步幅为1,上采样到3x3输出的示例过程。

以下是计算步骤的分解:

  1. 从输入的左上角像素开始,将其与滤波器中的2x2权重值相乘。
  2. 将相乘的结果保存在输出特征图左上角的2x2区域中。
  3. 将滤波器向右移动一步(步幅为1),在下一个像素上重复相同的相乘操作。
  4. 将滤波器向下移动一步,在下一个像素上重复操作。
  5. 在整个输入上重复此过程,当输出位置重叠时,将新的乘积结果与之前的结果相加。

通过这样的计算,输出中的某些像素值会受到输入中多个值的影响,而有些则只受单个值影响。


转置卷积的问题

了解了转置卷积如何工作后,我们来看看它存在的一个问题。

转置卷积的一个核心问题是输出像素受输入影响的程度不均匀。例如,输出特征图的中心像素被访问了四次,并受到所有输入像素的影响。而输出特征图的角落像素可能只被访问一次,仅受单个输入像素影响。

这种不均匀的影响会导致输出出现一种类似棋盘格的图案,这被称为棋盘格问题。以下图片展示了一个转置卷积的真实输出,其中放大的圆圈区域清晰地显示了这种棋盘格效应。


总结与现状

本节课中我们一起学习了转置卷积。

总结一下,转置卷积是一种具有可学习参数的上采样方法。它通过类似卷积反向过程的方式放大特征图尺寸。然而,其计算方式会导致输出出现棋盘格问题,即像素值分布不均匀,形成网格状伪影。

尽管存在这个问题,转置卷积在研究社区中仍然相当流行。不过,目前一种更流行的技术是先进行上采样(如双线性插值),再进行常规卷积,这种方法能有效避免棋盘格问题。

P19课程:解决GAN模式崩溃问题 🧠

在本节课中,我们将学习生成对抗网络训练中的一个常见问题——“模式崩溃”,并探索如何通过引入一种新的损失函数来解决它。

上周,我们为GAN进行了一些小的升级,以生成更好的图像。本节中,我们来看看GAN训练中的另一个主要问题。

模式崩溃问题 🔄

GAN在训练中可能陷入“模式崩溃”,即生成器反复生成相同或极其相似的样本。例如,一个训练于各种犬种的GAN可能只会生成金毛寻回犬的图像。

这个问题之所以发生,是因为判别器在持续改进,但其输出被限制在“极度虚假”或“极度真实”的二选一判断中。判别器本质上是一个分类器,它被鼓励将输出推向“0”(假)或“1”(真)。

在一次训练迭代中,如果判别器错误地认为生成器产生的金毛寻回犬图像看起来“真实”,那么生成器就会倾向于持续生成这种图像。当判别器在后续训练中修正判断,发现这些图像是“假”的时,生成器会陷入困惑,因为它没有生成其他多样性图像的“武器”,导致学习进程停滞。最终结果是网络性能非常糟糕。

问题的根源:损失函数限制 🎯

上一节我们介绍了问题现象,本节中我们来看看其根本原因。模式崩溃的根源在于传统的二元交叉熵损失函数

该损失函数迫使判别器输出一个介于0和1之间的值(尽管在0和1之间有无限个小数可能)。随着判别器改进,其输出会越来越接近极端的0或1。

其公式可以表示为:
Loss = -[y * log(p) + (1 - y) * log(1 - p)]
其中 y 是真实标签(0或1),p 是判别器的预测概率。

解决方案:引入Wasserstein损失函数 💡

本周,我们将介绍一种新的损失函数来解决此问题——Wasserstein损失(或称“推土机距离”)。

这种损失函数允许判别器(在此语境下常称为“评论家”)输出任意实数,范围可以从负无穷到正无穷。例如,它可以输出负数、4或100等值。

以下是Wasserstein损失的核心思想代码表示:

# 判别器对真实数据的输出应尽可能大
real_loss = -torch.mean(disc_real_output)
# 判别器对生成数据的输出应尽可能小(或负)
fake_loss = torch.mean(disc_fake_output)
# 总损失
total_loss = real_loss + fake_loss

这种改变解决了模式崩溃问题,因为它为生成器提供了更丰富、连续的梯度信号。判别器不再只是说“好”或“坏”,而是能表达“有多好”或“有多坏”,使得两个网络都能持续学习并探索更广阔的数据分布。

在你的实践任务中,你将实现这个重要的GAN升级。

总结 📝

本节课中,我们一起学习了GAN训练中的模式崩溃问题。我们了解到,传统二元交叉熵损失函数限制判别器的输出范围,是导致生成器多样性不足的一个关键原因。通过引入Wasserstein损失函数,允许判别器输出更广泛的数值范围,我们能为生成器提供更有效的学习信号,从而促进模型生成更多样化的结果,并保持稳定的训练过程。

🎨 P2:【2025版】生成式模型 - 小土堆PyTorch教程

在本节课中,我们将学习生成式模型的基本概念,特别是生成对抗网络(GANs)。我们将了解生成式模型与判别式模型的区别,并介绍两种主流的生成式模型架构。

1. 生成式模型与判别式模型

上一节我们介绍了课程概述,本节中我们来看看生成式模型与判别式模型的核心区别。

你可能熟悉判别式模型。判别式模型是机器学习中常用的分类模型。它们学习如何区分类别,如狗和猫。它们通常被称为分类器。判别式模型使用一组特征 x,如湿润的鼻子,或者它是否发出咕噜声。然后根据这些特征确定类别 y,即图像是否是狗或猫。换句话说,它们试图建模给定一组特征 x 时,类别为 y 的概率 P(y|x)。例如,它有湿鼻子但不咕噜,所以它很可能是一只狗。

另一方面,生成模型试图学习如何制作某个类的逼真表示。例如,一只狗的逼真图片。

以下是判别式模型与生成式模型的直观对比:

  • 判别式模型:学习条件概率分布 P(y|x)。目标是区分不同类别。
  • 生成式模型:学习联合概率分布 P(x, y)P(x)。目标是生成新的、逼真的数据样本。

2. 生成式模型的工作原理

上一节我们对比了两种模型,本节中我们来看看生成式模型具体是如何工作的。

生成模型从一些随机输入开始,这里表示为噪声 z。这可能是一个随机数字,例如三、一个负数、五或二点六。我们实际上是使用一个所有可能值的向量。重点是噪音 z 代表了随机一组值输入到生成模型中。生成模型有时也会接收一个类别 y,例如狗。并且从这些输入中,它将生成一组特征,看起来像一只真实的狗。所以,一只狗的形象,具有湿鼻子或舌头伸出等特征。

你可能会好奇为什么需要这种噪音。为什么不能直接告诉模型生成一只狗,然后它就会生成。这里的噪音主要是确保生成的东西实际上每次不是相同的狗。你很快就会看到这种主题被重复。这是因为只生成一个狗并不有趣,而且也有点没意义。所以目前可以把这看作是一些随机噪音,这也作为输入进入。

更普遍地说,生成模型试图捕捉特征 x 的概率分布 P(x|y)。例如,湿鼻子、伸出舌头、尖耳朵等特征,但总是鉴于狗的类 y,再加上噪音 z。这些模型将生成这个类 y 的真实和多样化的表示。实际上,如果你只生成狗这一个类,那么你可能不需要对这个 y 进行条件约束。相反,这只是对所有特征 x 的概率 P(x)

你可以从侧面比较看出,判别式模型和生成式模型在这里实际上有点相互映照。

在一个良好的生成模型运行中,你可以得到这些鹅啄食的图片。而在另一个运行中,你可以得到一只西藏獒犬的图片。如果你继续多次运行它,没有任何限制,你将会得到更多代表你生成模型训练数据集的图片。这可能看起来像很多可爱的拉布拉多寻回犬。

3. 主流生成式模型架构

上一节我们了解了生成式模型的基本流程,本节中我们来看看两种最受欢迎的生成式模型架构。

有许多类型的生成模型,我将简要向你介绍最受欢迎的那些:变分自编码器(VAE)和生成对抗网络(GANs)。

变分自编码器 (VAE)

VAE使用两个模型工作:一个编码器和一个解码器。这些通常是神经网络。

它们首先通过将真实图像喂入编码器来学习。例如,一张逼真的狗图片。然后编码器的任务是找到一种很好的方式来表示这张图像,在这个扭曲的潜在空间中。假设它找到了这里,假设这个点在潜在空间中可以用这组数字表示:[6.2, -0.321]

现在VAE会做以下操作:它将这个潜在表示,或者接近它的点,通过解码器。解码器的目标是重建编码器之前看到的真实图像。所以假设解码器已经训练得很好。但是在一开始,解码器可能无法重建图像。也许这只狗的后代会有邪恶的眼睛。

训练后,我们实际上可以去掉编码器。我们可以在潜在空间中随机选择点,比如这里,解码器将学会生成一张真实狗的图片。

我刚才描述的是大部分自编码器。变分自编码器的一部分,变分的部分实际上在训练过程中向整个模型注入一些噪声。编码器不是将图像编码到潜在空间的单一点中,而是将图像编码到一个整个分布中。然后从那个分布中采样一个点,喂给解码器,以便生成一个真实的图像。这添加一些噪声,因为这个分布上的不同点可以被采样。

生成对抗网络 (GANs)

GANs以一种相当不同的方式工作。它们也由两个模型组成:一个生成器和一个判别器。

生成器输入一些随机噪音 z,就像你之前看到的那样,例如 [1, 2, 3, 5] 作为一个向量,并将这些输入到这个生成器中。当然,还可以选择狗的种类,但如果我们只是想生成狗,我们不需要输入那个。作为输出,它可以随时间生成同一只狗。当然,一开始它生成的图像可能不真实。

生成器的角色,在某种程度上它与VAE中的解码器非常相似。不同之处在于没有指导编码器来决定输入到生成器中的噪声向量应该看起来像什么。

相反,有一个判别器在看假的和真实的图像,同时试图理清哪些是真实的,哪些是虚假的。判别器本身是一个判别式模型,其任务是区分“真实图像”和“生成器生成的假图像”这两个类别。

随着时间的推移,每个模型都在试图超越彼此。生成器试图生成足以骗过判别器的假图像,而判别器则试图更准确地区分真假。因此,这些模型彼此竞争。这就是为什么它们在名字中被称为“对抗性的”——生成对抗网络。

你可以想象两个模型在训练中就像肌肉随着时间的推移在彼此竞争中增长。直到他们达到一个点,我们再次不再需要第二个模型了。生成器可以输入任何随机噪声并生成一张逼真的图像。例如,一组随机数向量 [-5, 6, 2, 8],可以生成这只可爱的拉布拉多寻回犬。

在这门专业化课程期间,你将专注于生成对抗网络(GANs)。但请随意阅读更多关于VAE的内容,如果你发现它们有趣。不要担心,如果你还不完全理解GAN的工作原理。我将更深入地研究它们的架构,在接下来的视频中他们将学到的方式。

4. 总结

本节课中我们一起学习了生成式模型的核心知识。

总之,生成模型学习产生逼真的例子,就像一位艺术家可以画出看起来像照片的画作。例如,产生那些可爱的狗的照片。一个生成模型有点像一个艺术家,他正在尝试学习如何创作超写实艺术。

同时,判别模型能够区分不同的类别,比如一只狗或一只猫。但是当然,你也看到了,一个判别模型可以是一个生成模型的子组件,例如GAN中的判别器,其类别为“真实”和“伪造”。

有许多种生成模型,但在本系列课程中,你将学习GAN。本周末结束的时候,你可以构建自己的生成对抗网络(GAN),它能够生成手写数字。

P20:模式坍塌 🎭 - 小土堆Pytorch教程

在本节课中,我们将要学习生成对抗网络训练中一个常见且棘手的问题——模式坍塌。我们将了解什么是概率分布中的“模式”,以及模式坍塌是如何在GAN的训练过程中发生的。

概述

传统GAN在训练时,使用二元交叉熵损失函数,可能会面临模式坍塌和梯度消失等问题。本节将介绍模式坍塌的直观概念,并解释其成因。后续课程会介绍如何通过修改架构和损失函数来克服这些问题。

什么是模式?

在数据分布中,模式是指观察值高度集中的区域。

例如,正态分布中的均值就是该分布的单一模式。当然,也存在具有多个模式的分布,其均值不一定是模式之一。因此,双峰分布有两个模式,多峰分布则有多个模式。

更直观地说,特征空间上概率密度分布的任何一个峰值,都是该分布的一个模式。

以手写数字为例

我们用手写数字数据集来举例。假设数字由特征 x1x2 两个维度来表示。

不同的 (x1, x2) 值对可以用来表示不同的手写数字。在这种情况下,概率密度分布将是一个具有许多峰值的曲面,每个峰值对应一个数字。这绝对是一个多峰分布,有十个不同的模式。

例如,所有数字“7”的不同样本,都会由相似的 (x1, x2) 值对来表示。这些值对都代表“7”。其中,均值点(用红色标出)所代表的“平均7”,看起来就像一个标准的数字7。

在三维表示中,这些峰值像山峰一样凸起,海拔越高(概率密度越大)用颜色越深的圆圈表示。

不同的特征对 (x1, x2) 会产生这些手写数字“5”和“7”。而在“5”和“7”之间的区域,概率密度非常低。因此,生成一个介于“5”和“7”之间的混合数字的概率非常低。

在真实数据集中,可能存在“5”和“7”的混合体,但对应的 (x1, x2) 值对出现的概率极低,位于产生中间形态数字的空白空间。

所以,同一数字的不同样本会在特征空间中被分组,在该区域内浓度很高。最常见的写法(即该数字的均值)位于对应模式峰的中心。因此,基于特征 x1x2 的概率密度分布会有十个模式,每个数字对应一个。

许多用于训练GAN的真实数据分布都是像这样的多模态分布。

什么是模式坍塌?

我将继续使用手写数字的例子,来展示模式坍塌的直观含义。

“坍塌”这个词听起来像是某些东西崩塌或减少。在模式坍塌中,听起来就像是分布崩塌到单一或更少的模式上,即一些模式正在消失。

以下是模式坍塌可能发生的过程:

  1. 一个已经学会识别手写数字的判别器,除非生成的图像看起来像“1”或“7”,否则能正确分类大多数数字。
  2. 这可能意味着判别器在其损失函数中陷入了一个局部最小值,它正确分类了大多数数字,除了那些看起来像“1”和“7”的数字。
  3. 这个信息被传递给生成器。生成器查看判别器的反馈,并学习如何在下一轮中欺骗判别器。
  4. 生成器发现,所有被判别器错误分类的图像,看起来都像“1”或“7”。
  5. 于是,它开始生成大量看起来像那些数字的图像。
  6. 这些生成的图像在下一轮被传递给判别器。
  7. 然后,判别器可能错误分类了每一张图片,除了那张看起来更像“7”的图片。
  8. 生成器得到这些反馈,并看到判别器当前的弱点是那些看起来像手写“1”的图像。
  9. 这次,它产生的所有图像都看起来像那个数字“1”。
  10. 至此,生成器的输出分布“坍塌”到了所有可能手写数字分布中的单一模式上。

最终,判别器可能会意识到这一点,并通过跳出那个局部最小值来学会识别生成器伪造的手写数字“1”。但生成器也可能迁移到分布的另一个模式(例如数字“7”),然后GAN又会坍塌到那个新模式。或者,生成器可能无法找出其他可以多样化的方向。

总结

本节课中,我们一起学习了模式坍塌的概念。

  • 模式是特征空间上概率分布的峰值。
  • 现实世界的数据集包含许多与每个可能类别相关的模式,就像手写数字数据集一样。
  • 模式坍塌发生在生成器学会通过只产生整个训练数据集中的单一类别样本(例如只生成手写数字“1”)来欺骗判别器时。

这是很不幸的,因为当生成器被优化以欺骗判别器时,它牺牲了生成样本的多样性,导致无法捕捉真实数据的完整分布。理解这个问题是解决它的第一步。

🧠 P21:【2025版】21. BCE损失的问题 - 小土堆Pytorch教程

在本节课中,我们将要学习在生成对抗网络中,使用二元交叉熵损失函数时可能遇到的问题。我们将回顾BCE损失函数的形式,理解它对生成器和判别器目标的影响,并重点分析由此可能引发的梯度消失问题。


📊 BCE损失函数回顾

上一节我们介绍了GAN的基本概念,本节中我们来看看其传统训练中使用的损失函数。

二元交叉熵损失函数是GAN训练中常用的损失函数。它衡量的是分类器对真实数据和生成数据错误分类的平均成本。

以下是BCE损失函数的标准形式:

公式:

L(D, G) = E[log(D(x))] + E[log(1 - D(G(z)))]

其中:

  • D(x) 是判别器对真实数据 x 的预测概率。
  • D(G(z)) 是判别器对生成数据 G(z) 的预测概率。
  • E 表示期望值。

这个公式包含两项:

  1. 第一项 E[log(D(x))] 对应真实数据。判别器希望最大化此项,即正确地将真实数据识别为“真”。
  2. 第二项 E[log(1 - D(G(z)))] 对应生成数据。判别器希望最小化此项(即让 D(G(z)) 接近0),从而正确地将生成数据识别为“假”。

对于生成器 G 而言,它的目标恰恰相反:它希望最大化判别器对生成数据的误判概率 D(G(z)),即最小化 E[log(1 - D(G(z)))]。这种生成器与判别器之间的对抗性目标,构成了一个极小极大博弈


⚖️ 极小极大博弈与训练目标

通过上述极小极大博弈,GAN的宏观训练目标得以实现:让生成数据 G(z) 的分布 P_g 无限接近真实数据 x 的分布 P_data

核心目标公式:

min_G max_D L(D, G) ≈ min_G divergence(P_data || P_g)

这个博弈过程近似于在最小化真实分布与生成分布之间的某种差异。

在训练过程中:

  • 判别器 D 会自然地试图最大化自身区分真假的能力,拉开 P_dataP_g 的距离。
  • 生成器 G 则试图学习并调整 P_g,使其向 P_data 靠拢,以“欺骗”判别器。

🎭 判别器与生成器的角色差异

然而,让我们退一步,重新审视生成器和判别器的角色差异。

判别器的任务相对简单:它只需要输出一个介于0到1之间的标量值,表示输入为“真”的概率。

生成器的任务则复杂得多:它需要将一个随机噪声向量 z 映射为一个高维、结构化的输出(例如一张图片),这个输出需要包含丰富的特征以成功欺骗判别器。

代码示例(角色差异):

# 判别器输出:一个标量概率
discriminator_output = D(input_image)  # 例如:tensor([0.85])

![](https://github.com/OpenDocCN/dsai-notes-zh/raw/master/docs/dlai25/img/cd0f0fcb66c72375a9429285530fc72b_15.png)

# 生成器输出:一张完整的图片(高维张量)
generated_image = G(random_noise)  # 例如:tensor of shape [3, 256, 256]

这好比在博物馆鉴赏画作(判别器)与创作一幅杰作(生成器)。通常,前者比后者更容易。因此,在训练过程中,判别器的学习速度往往快于生成器,这是一个非常普遍的现象。


🧨 梯度消失问题

在训练初期,判别器能力不强,对真假数据的判断存在不确定性,其预测概率 D(G(z)) 不会极端接近0或1。此时,它能为生成器提供有效的、非零的梯度反馈,指导生成器改进。

但是,随着判别器快速变得强大,它能非常清晰地区分真假分布。对于生成的数据,判别器的预测 D(G(z)) 会趋近于0。让我们看看这如何影响生成器的梯度。

生成器的损失函数是 E[log(1 - D(G(z)))]。当 D(G(z)) → 0 时,log(1 - D(G(z))) → log(1) = 0。这个损失函数在 D(G(z)) 接近0的区域会变得非常平坦。

梯度计算:
生成器的梯度依赖于损失函数对 D(G(z)) 的导数:

∂/∂D(G(z)) [log(1 - D(G(z)))] = -1 / (1 - D(G(z)))

D(G(z)) → 0 时,梯度趋近于 -1,看似没问题。但关键在于,当判别器非常确信生成数据为假时,它对生成器参数的梯度 ∂D(G(z))/∂G 会变得非常小(接近0)。这导致最终传回生成器的总梯度 ∂L/∂G 变得极其微弱,甚至消失。

结果就是:

  • 判别器给出非常自信的判断:“真数据=1,假数据=0”。
  • 生成器因无法获得有效的梯度更新而停止学习,陷入“梯度消失”的困境。

📝 总结

本节课中我们一起学习了使用BCE损失训练GAN时的一个核心问题。

  1. 目标回顾:GAN通过极小极大博弈,旨在让生成分布 P_g 逼近真实分布 P_data
  2. 角色差异:判别器的学习任务通常比生成器更简单,导致其能力可能过早地强于生成器。
  3. 问题根源:当判别器过于强大时,它对生成数据的预测概率 D(G(z)) 会饱和(接近0),导致生成器损失函数的梯度区域变得平坦。
  4. 最终后果:生成器无法获得有意义的梯度更新,训练停滞,这就是梯度消失问题。这解释了为什么传统的BCE损失并非训练GAN的最佳选择,并可能导致模式崩溃等问题。

在后续课程中,我们将探讨如何改进损失函数(例如使用Wasserstein距离)来缓解这一问题。

P22:【2025版】22. 地球移动者距离 🚜 - 小土堆Pytorch教程

在本节课中,我们将学习一种在训练生成对抗网络(GAN)时常用的、不同于二元交叉熵(BCE)损失的成本函数——地球移动者距离(Earth Mover‘s Distance)。我们将了解它的直观含义、优势,以及它如何帮助解决GAN训练中的常见问题。

上一节我们介绍了使用BCE损失训练GAN时遇到的问题。本节中,我们来看看一种替代方案。

什么是地球移动者距离?

地球移动者距离是一种用于测量两个概率分布之间差异的度量。假设我们有一个生成的分布和一个真实的分布,它们的方差相同但均值不同(例如,都呈正态分布)。地球移动者距离衡量的就是这两个分布之间的差异。

具体而言,它通过估计“将生成的分布调整为真实分布所需付出的努力程度”来量化这种差异。

我们可以做一个直观的类比:将生成的分布想象成一堆泥土,将真实的分布想象成目标形状。那么,地球移动者距离就相当于移动并塑造这堆泥土,使其完全匹配目标形状的难度和工作量。这个“工作量”函数取决于两个因素:泥土需要移动的距离和需要移动的泥土数量

BCE损失的问题与EMD的优势

在上一部分,我们了解了EMD的直观概念。现在,我们来对比一下它和BCE损失的关键区别。

BCE损失的核心问题在于,随着判别器(Discriminator)性能的提升,它对真实样本和生成样本的判别输出会趋向于两个极端值(1和0)。这导致生成器(Generator)获得的梯度反馈变得非常微弱,从而引发梯度消失问题,使得生成器停止学习。同时,这也容易导致模式崩溃,即生成器只产生有限的几种样本。

然而,地球移动者距离不存在这样的上限。它的值可以随着两个分布差异的增大而持续增长。

这意味着,无论两个分布相距多远,地球移动者距离提供的梯度都不会趋近于零。因此,使用基于EMD的损失函数训练的GAN,不易受到梯度消失和模式崩溃问题的影响。

总结与回顾

本节课中,我们一起学习了地球移动者距离。

以下是本节课的核心要点总结:

  • 定义:地球移动者距离是衡量使一个分布等于另一个分布所需“工作量”的函数。这个工作量取决于移动的距离数量
  • 公式/代码概念:虽然其数学形式(如Wasserstein距离)涉及最优传输理论,但其优化目标常通过以下对抗形式实现:
    Loss = E[D(real)] - E[D(fake)]
    其中需要判别器D满足Lipschitz连续性约束(例如通过梯度惩罚)。
  • 优势:与BCE损失不同,EMD没有“饱和区”。即使判别器性能很好或分布差异很大,它也能提供有效的梯度,从而缓解了梯度消失问题,并降低了模式崩溃的可能性

在接下来的课程中,我们将进一步探讨如何具体计算和应用这一距离来训练更稳定的GAN模型。

P23:【2025版】23. Wasserstein损失 🧠 - 小土堆Pytorch教程

在本节课中,我们将要学习一种在生成对抗网络中常用的替代损失函数——Wasserstein损失。我们将了解它的基本概念、数学形式,并将其与传统的二元交叉熵损失进行比较。

正如你所见,传统上使用二元交叉熵损失来训练GANs,但由于其近似的函数形式,它存在许多问题。

在本视频中,我将向你介绍一种替代的损失函数。

它被称为Wasserstein损失或W损失,它近似于你在前一个视频中看到的地球移动距离。

为此,首先,你将看到一种看待二元交叉熵损失函数的替代方法。

这更简单、更紧凑,我将向你展示如何计算W损失。

我将把这项损失与二元交叉熵损失进行比较。

回顾二元交叉熵损失

上一节我们提到了传统GAN训练的问题,本节中我们来看看其核心损失函数。

二元交叉熵损失是通过一个冗长的方程计算出来的,本质上它衡量了平均而言,观察值被判别器分类为假和真的程度。判别器将一些观察值分类为假和真。

因此,生成器和GAN的目标是最大化这种成本。

因为这意味着判别器认为生成的假值看起来非常真实。

而判别器希望最小化这种成本。因此,这可以被称为最小最大化游戏。

并且用于计算二元交叉熵损失的这条很长的方程可以简化如下:对示例m的和与除法无非就是平均值或期望值。

而和里面的第一部分衡量了判别器对真实观察值的分类好坏。

当y等于1时,1表示真实。

第二项衡量生成器生成的假样本被分类为假的程度。当y等于1时,表示真实。

但是1-y(y等于0时)表示假样本。

引入Wasserstein损失

了解了二元交叉熵损失后,我们现在引入Wasserstein损失。

Wasserstein损失近似于真实分布和生成分布之间的地球移动距离。

但它比二元交叉熵损失有更好的特性。但是它看起来与二元交叉熵损失的简化形式非常相似。

在这种情况下,该函数计算判别器预测的期望值之间的差异。这里,这叫做批评家,稍后会详细介绍,所以我在这里用c来表示它。

以下是Wasserstein损失的核心公式:

W_loss = E[c(x_real)] - E[c(G(z))]

其中,c(x_real)是批评家对真实样本x的评分,c(G(z))是批评家对生成器G根据噪声向量z生成的假样本(或称为x_hat)的评分。

所以鉴别器观察这两者,它想要最大化它对真品和仿制品思考的距离。

所以它试图将这两个分布推得越远越好。同时,生成器想要最小化这个差异。

因为它想让判别器认为它的假图像尽可能接近真品。

与二元交叉熵损失的关键区别

上一节我们介绍了Wasserstein损失的形式,本节中我们来看看它与二元交叉熵损失的主要区别。

在二元交叉熵损失中,没有对函数中的log进行计算,因为判别器的输出不再局限于0到1之间。

所以为了二元交叉熵损失有意义,判别器的输出需要是0到1之间的预测。

它想要最大化它对真品和仿制品思考的距离,所以它试图将这两个分布推得越远越好。因此,GAN使用二元交叉熵损失训练的判别器的神经网络在输出层具有Sigmoid激活函数。

以便将这些值压缩在0和1之间。

Wasserstein损失,然而,它根本不需要这种要求。

所以你可以在判别器神经网络的末尾有一个线性层,并且可以产生任何实数输出。

你可以将这个输出解释为批评者认为图像有多真实。顺便说一下,我们现在称其为判别器。

因为它不再局限于0和1之间。

因为0表示假,1表示真,它不再将这些值分类为这两个或这两个类别。因此,不再进行分类。作为结果,不再有意义称其为判别器,因为它不区分这些类别。所以对于W损失。

与判别器等效的称为批评者,它试图最大化它在假样本上的评估与它在真实样本上的评估之间的距离。

以下是Wasserstein损失和二元交叉熵损失之间的一些主要区别:

  • 在二元交叉熵损失下,判别器输出一个0到1之间的值。
  • 而批评者和Wasserstein损失将输出任何数字。
  • 它们的成本函数的形式非常相似,但Wasserstein损失中不包含任何对数。这是因为它是一个衡量批评者对真实样本的预测与它对假样本的预测之间的距离。
  • 二元交叉熵损失确实测量了真实和假之间的这种距离,但以1或0作为基准。

这里重要的是,判别器被限制在0到1之间。

而批评者不再受限,并且试图尽可能多地分开两个分布。作为结果。

因为它不受限制,批评者被允许改进而不会降低对生成器的反馈。这是因为它没有消失梯度问题,这将防止模式崩溃,因为生成器总是得到有用的反馈。

总结

本节课中我们一起学习了Wasserstein损失。

总结来说,Wasserstein损失看起来与二元交叉熵损失非常相似。

但它在底层的数学表达式不那么复杂,它近似于地球移动距离,因此防止模式崩溃和管理生成器问题。

然而,这个成本函数有一个额外的条件,为了使其良好工作并且是有效的,你将在下一个视频中看到。

P24:【2025版】24. 对Wasserstein判别器加条件 🧠 - 小土堆Pytorch教程

在本节课中,我们将要学习Wasserstein GAN(WGAN)中的一个核心概念:判别器(或称批评家)需要满足的Lipschitz连续性条件。我们将解释这个条件的含义、重要性以及如何直观地理解它。


Wasserstein损失(或称W损失)解决了传统GAN面临的一些问题,例如模式崩溃和梯度消失。但要使WGAN效果良好,判别器的神经网络需要满足一个特殊的条件。

在这段视频中,你将看到对判别器神经网络提出的连续性条件意味着什么。

以及为什么当使用W损失训练GAN时,这个条件很重要。

所以请耐心等待,W损失是一个简单的表达式,它计算判别器对真实样本和生成样本输出期望值的差异。

对于真实的例子x及其对假例子的预测。

生成器G试图最小化这个表达式,试图使生成的例子尽可能接近真实例子。而判别器希望最大化这个表达式,因为它希望区分真实和假例子,它希望距离尽可能大。然而,在使用WGAN训练时,判别器有一个特殊的条件。

它需要成为所谓的一阶Lipschitz连续函数,或简称一阶L连续函数。

这个条件听起来比实际上更复杂。对于一个像判别器这样的函数(神经网络),要成为一个Lipschitz连续函数,它的梯度的范数需要小于或等于1。这意味着在任何一点,斜率不能大于1。在任何一点,它的梯度不能大于1。

要检查一个函数是否是Lipschitz连续的,你需要沿着这个函数的每一点走。

并确保斜率小于或等于1,或它的梯度小于或等于1。你可以做两件事:你可以实际上画两条线,一条在这个特定点的斜率正好是1,你在评估这个函数,并且有一个斜率是负的情况,一个你正在评估这个函数的情况。

并且你想要确保,这个函数的增长永远不会超出这些线之外,因为保持在这些线内意味着这个函数是线性增长的。

所以这里这个函数不是Lipschitz连续的,因为它在这些部分都超出了范围,它没有保持在这个绿色区域。

这表明它增长超过了线性。所以看另一个例子这里。

所以这是一个光滑曲线函数,您需要再次检查这个函数上的每个单个点,在您能够确定这是否是一个Lipschitz连续函数之前,在这里看起来有趣。

函数在这里看起来不错,它也在这里看起来不错,它看起来不错。所以让我们假设您检查了每个单个值,并且函数从不以超线性方式增长,因此这个函数是Lipschitz连续的。

对于W损失的判别神经网络,这个条件很重要,因为这样可以确保损失函数不仅连续可导,而且不会增长过多,并在训练过程中保持一定的稳定性。这也是使底层的地球移动器距离(Earth Mover‘s Distance)有效的原因,这正是W损失所基于的。

这对于训练判别器和生成器的神经网络都是必需的。

这也增加了稳定性,因为GAN学习的变化将被限制。因此,总结起来,在使用W损失训练的GAN中。

判别器需要是Lipschitz连续的,以便其底层的地球移动距离,在真实和假数据之间的比较,为了满足或尝试满足这个条件,需要进行有效的比较。在训练期间,有多种不同的方法。


本节课中我们一起学习了Wasserstein GAN中判别器需要满足的Lipschitz连续性条件。我们了解到,这个条件要求判别器函数在任何点的梯度范数不超过1,这确保了训练的稳定性和Wasserstein距离的有效性。理解这个条件是掌握WGAN工作原理的关键一步。

P25:WGAN-GP中的Lipschitz连续性强制 🧠

在本节课中,我们将学习如何在Wasserstein GAN(WGAN)中,为判别器(Critic)强制实施Lipschitz连续性条件。这是确保Wasserstein损失有效性的关键。我们将介绍两种主要方法:权重裁剪(Weight Clipping)和梯度惩罚(Gradient Penalty),并比较它们的优劣。


1. Lipschitz连续性回顾 📚

上一节我们介绍了Wasserstein损失。本节中我们来看看确保其有效的核心条件:判别器的一阶Lipschitz连续性。

判别器的一阶Lipschitz连续性意味着,该函数在任意点的梯度范数(Norm)不超过1。这可以用以下公式表示:

公式: ‖∇f(x)‖ ≤ 1

其中:

  • ∇f(x) 表示判别器函数 f 在输入 x(例如一张图像)处的梯度。
  • ‖·‖ 通常指L2范数(即欧几里得距离)。

直观上,这限制了函数在每个点的“斜率”或变化率。在二维空间中,函数的图像将被限制在斜率为±1的绿色三角形区域内。


2. 强制Lipschitz连续性的方法 ⚙️

为了在训练中满足上述条件,主要有两种方法。以下是这两种方法的详细介绍。

方法一:权重裁剪(Weight Clipping)

权重裁剪是一种直接的方法。在每次梯度下降更新判别器的权重后,将所有权重强制限制在一个固定的区间 [-c, c] 内。

操作流程:

  1. 正常进行梯度下降更新权重。
  2. 遍历所有权重参数。
  3. 将任何小于 -c 的权重设置为 -c
  4. 将任何大于 c 的权重设置为 c

代码描述:

# 假设 w 是判别器的权重参数,c 是裁剪阈值(如 0.01)
w = torch.clamp(w, -c, c)

然而,这种方法存在严重缺点。将权重严格限制在固定区间内,可能会过度限制判别器的学习能力和表达能力,从而影响整个GAN的性能。它引入了额外的超参数 c,需要进行大量调整:如果 c 太小,判别器能力受限;如果 c 太大,则约束力不足。

方法二:梯度惩罚(Gradient Penalty)

梯度惩罚是一种更柔和、更有效的强制方式。它在原始的Wasserstein损失函数中添加一个正则化项,直接惩罚那些梯度范数偏离1的判别器行为。

损失函数公式:
L = E[D(x_fake)] - E[D(x_real)] + λ * E[(‖∇D(x_hat)‖ - 1)²]

其中:

  • 前两项是标准的Wasserstein损失。
  • 第三项是梯度惩罚项。
  • λ 是一个超参数,用于控制惩罚项的权重。
  • x_hat 是关键,它是在真实样本和生成样本之间随机插值得到的点。

为什么使用插值点 x_hat
理论上,我们需要判别器在整个输入空间的所有点上都满足梯度约束,但这不切实际。实践表明,通过在真实数据和生成数据的连线上进行随机采样来施加约束,效果非常好。

生成插值点 x_hat 的代码描述:

# 假设 x_real 是真实样本, x_fake 是生成样本
epsilon = torch.rand(x_real.size(0), 1, 1, 1)  # 生成随机权重
x_hat = epsilon * x_real + (1 - epsilon) * x_fake
x_hat.requires_grad_(True)  # 启用梯度计算

然后,计算判别器对 x_hat 的输出的梯度,并计算其范数与1的平方差作为惩罚。这种方法并不严格保证每一点的梯度范数都≤1,而是鼓励其接近1,被证明比权重裁剪更有效、更稳定。


3. 完整损失函数与优势总结 🏆

现在,我们将主要损失项和梯度惩罚项结合起来。

用于训练的完整损失函数表达式如下:

L_total = E[D(x_fake)] - E[D(x_real)] + λ * E[(‖∇D(x_hat)‖ - 1)²]

这个损失函数由两部分组成:

  1. Wasserstein距离近似项:驱使生成器产生更逼真的样本,同时缓解了模式崩溃问题。
  2. 梯度惩罚正则化项:对判别器实施Lipschitz连续性软约束,确保第一项的有效性。

研究表明,这种梯度惩罚方法能非常有效地让判别器在“几乎处处”满足梯度范数接近1的条件,从而显著提升WGAN的训练稳定性和生成质量。


4. 课程总结 ✨

本节课中我们一起学习了在WGAN中强制判别器满足Lipschitz连续性的两种方法。

  • 权重裁剪:通过硬性截断权重值来实施约束。方法简单,但可能因限制过强或过弱而影响性能,且需要仔细调整超参数。
  • 梯度惩罚:通过在损失函数中添加正则项来软性约束梯度范数。这种方法更为柔和有效,是当前WGAN-GP等改进模型的标准做法,虽然不提供严格保证,但在实践中能带来更稳定、更优异的训练结果。

理解并应用梯度惩罚,是成功训练Wasserstein GAN的关键一步。

P26:【2025版】26. 欢迎来到第4周 🍪

在本节课中,我们将要学习生成式模型中的一个核心概念:有条件生成。我们将通过一个简单的类比来理解它与无条件生成的区别,并了解如何实现对模型生成内容的控制。

在过去的几周里,你的模型一直在不断改进,但你对它生成的内容控制不多。这有点像在家,你不选择父母或监护人制作的饼干类型。你可能会得到燕麦葡萄干饼干,明天晚上可能是巧克力 chip 饼干。

这就是你的模型在做的,这叫做无条件生成。与之相对的是在餐厅,你可以在菜单上点菜,燕麦葡萄干饼干或巧克力 chip 饼干,或者菜单上的任何其他类型的饼干。这叫做有条件生成,你告诉模型生成不同的物品。

你指定或根据菜单条件,并调整训练过程,以便它实际上这样做。类似地,这是关于可控生成。用饼干类比,这是关于如何适应模型的输入,而不改变模型或厨师的过程。就像在烹饪中调整温度,以控制某些输出特征,如饼干的脆度或粘度。这适用于有条件和无条件的生成。

上一节我们介绍了有条件生成的基本概念,本节中我们来看看本周的具体安排。

以下是本周你将完成的两个作业:

  1. 第一个作业将引导你实现一个基础的有条件生成模型。你将学习如何将条件信息(例如“生成巧克力饼干”)编码并输入到模型中。
  2. 第二个作业将探索更高级的控制技术。你将尝试通过调整输入中的特定“旋钮”(在代码中可能体现为某些参数或向量),来精细控制生成结果的特定属性。

通过这两个练习,你将掌握让模型“按需生成”内容的基本方法。

本节课中我们一起学习了有条件生成与无条件生成的区别。我们了解到,有条件生成就像根据菜单点菜,允许我们通过提供特定的条件信息来控制模型的输出。在接下来的实践中,你将亲手实现这一机制,从而获得对生成内容的主动权。

🧠 P27:条件生成的直觉

在本节课中,我们将学习生成式对抗网络(GAN)的一个重要扩展——条件生成。我们将通过对比无条件生成,理解条件生成如何让我们控制生成样本的类别或特征。

在过去的几周里,你已经了解了生成式对抗网络(GANs)的工作原理,以及如何构建它们来生成模仿训练数据集的样本。

接下来,我们将展示如何控制输出,以获取特定类别的样本,或者使样本具有某些特定特征。

🔄 回顾:无条件生成

首先,让我们快速回顾一下你已经熟悉的无条件生成。

在无条件生成中,你得到的是随机类别的输出。你可以将其想象成一个自动售货机:你投入硬币(随机噪声向量 z),然后得到一个随机颜色的软糖(生成的图像 G(z))。

公式表示:
无条件生成输出 = G(z)

如果你想要特定颜色的软糖(例如红色),你必须不断投币(生成)直到得到它。在这个过程中,你无法控制最终会得到哪种颜色的输出。

🎯 引入:条件生成

另一方面,条件生成允许你请求来自特定类别的样本。

这就像一个更高级的自动售货机:你不仅投入硬币(随机噪声向量 z),还输入你想要的物品代码(条件标签 y),例如“红色苏打水”。然后,机器就会给你一瓶红色苏打水。

公式表示:
条件生成输出 = G(z, y)

请注意,你仍然无法控制这瓶苏打水的某些具体特性(例如最新鲜的或最满的一瓶),但你一定能得到一瓶红色苏打水,而不是蓝色糖果。这里的“硬币”和“代码”共同构成了生成器的输入。

⚖️ 核心比较

现在,你对条件生成和无条件生成的关系有了概念,让我们系统地比较一下它们。

以下是两者的主要区别:

  • 输出控制:条件生成让你从你决定的类别中获得生成的样本。无条件生成则从随机类别中获得样本。
  • 数据要求:条件生成必须使用带有标签的数据集来训练你的GAN,这些标签对应你想要生成的不同类别。无条件生成则不需要任何标签,只需要一堆真实的样本。
  • 模型输入:在条件生成中,数据集的标签会同时馈送给生成器(G)鉴别器(D),以指导网络学习生成所需类别的样本。

📝 本节总结

本节课中,我们一起学习了条件生成的核心直觉。

我们回顾了无条件生成的过程,并将其与条件生成进行了对比。关键点在于,条件生成通过在生成过程中引入额外的标签信息(y),使得我们能够控制生成样本的类别。为了实现这一点,需要使用带标签的数据集进行训练,并将标签信息同时提供给生成器和鉴别器。

在随后的课程中,你将看到如何具体修改你的GAN模型,以实现这种强大的条件生成功能。

P28:条件生成的输入 🧠

在本节课中,我们将学习条件生成对抗网络(Conditional GAN)的核心概念,特别是如何将类别信息传递给生成器和判别器,从而控制生成特定类别的样本。


概述 📋

条件生成允许你生成指定类别的样本。为了实现这一点,你需要一个带有标签的数据集,并在训练过程中将类别信息传递给生成器和判别器。

条件生成的基本原理

上一节我们介绍了无条件生成,本节中我们来看看如何为生成过程添加条件控制。

条件生成的核心在于,除了随机噪声向量,我们还需要一个向量来告诉生成器应该生成哪个类别的样本。这个向量通常是 one-hot向量,其特点是除了目标类别对应的位置为1,其余位置均为0。

例如,假设我们有一个包含不同犬种的数据集,one-hot向量 [0, 1, 0, 0, 0] 中的“1”位于第二个位置,这代表我们希望生成器生成一只“哈士奇”。

噪声向量 z 负责提供生成样本所需的随机性,确保即使在同一个类别下,也能生成多样化的样本。因此,生成器的输入变成了噪声向量和one-hot类别向量的拼接。

公式表示生成器输入:
生成器输入 = concat(噪声向量 z, one-hot类别向量 c)

判别器如何接收条件信息

为了让生成器学会生成指定类别的样本,判别器也必须知晓样本的“目标类别”。

判别器的输入是图像和对应的类别信息。判别器的任务是判断:“给定的图像是否是该指定类别的真实样本?” 这意味着,即使一张比格犬的图片非常逼真,但如果它被标记为“金毛寻回犬”,判别器也应该将其判定为“假”。

为了实现这一点,类别信息需要被整合到判别器的输入中。一种常见的方法是将类别向量(如one-hot向量)扩展成与图像尺寸相同的通道图,然后将其作为额外的通道与原始图像通道拼接在一起。

代码示例(概念性描述):

# 假设 image 形状为 [C, H, W], label_one_hot 形状为 [num_classes]
# 将标签扩展为与图像空间尺寸相同的张量
label_map = label_one_hot.unsqueeze(-1).unsqueeze(-1)  # 形状变为 [num_classes, 1, 1]
label_map = label_map.expand(-1, H, W)                 # 形状变为 [num_classes, H, W]
# 将标签通道与图像通道拼接
discriminator_input = torch.cat([image, label_map], dim=0)  # 形状为 [C+num_classes, H, W]

训练过程的动态

以下是条件GAN训练中生成器和判别器的互动过程:

  1. 生成器:接收拼接了类别信息的噪声向量,尝试生成指定类别的逼真图像。
  2. 判别器:接收真实图像及其正确标签,或生成图像及其目标标签。它学习区分“指定类别的真实图像”和“指定类别的生成图像”。
  3. 对抗博弈:生成器努力生成能以假乱真、且符合目标类别的图像来欺骗判别器;判别器则努力提升自己的鉴别能力。这个过程迫使生成器不断改进,最终学会生成高质量、符合条件约束的样本。

总结 🎯

本节课中我们一起学习了条件生成对抗网络中输入部分的关键设计:

  • 核心思想:通过引入类别信息,控制生成样本的类别。
  • 生成器输入:由随机噪声向量 z 和 one-hot 类别向量 c 拼接而成。
  • 判别器输入:由图像和扩展后的类别信息(通常作为额外通道)拼接而成。
  • 训练机制:判别器根据“图像-类别”对进行真假判断,从而引导生成器生成符合目标类别的逼真样本。

通过这种设计,我们能够引导GAN生成我们想要的特定类型的图像,这是许多高级图像生成和应用的基础。

P29:可控生成 🎛️

在本节课中,我们将学习一种名为“可控生成”的技术。这是一种在生成对抗网络(GAN)训练完成后,控制其输出图像特定特征(如年龄、发色、是否戴眼镜等)的方法。我们将了解其核心概念,并将其与之前学过的“条件生成”进行比较。


概述

可控生成允许我们在模型训练完毕后,通过调整输入给生成器的噪声向量 z,来控制生成图像的特征。这与条件生成不同,后者在训练时就需要使用带标签的数据来指定类别。

可控生成是什么?

可控生成是一种控制GAN生成输出的方法。它专注于控制你希望在输出图像中呈现的特征,即使模型已经训练完毕。

例如,对于一个生成人脸的GAN,你可以控制图像中人物的年龄、是否戴太阳镜、视线方向或感知性别。这是通过调整输入给生成器的噪声向量 z 来实现的。

一个直观的例子

假设我们有一个噪声向量 z,输入生成器后得到一张红发女性的图像。

# 伪代码示意
z = torch.randn(1, latent_dim)  # 原始噪声向量
image_red_hair = generator(z)   # 生成红发图像

如果我们调整 z 中代表“发色”的特征方向,就可能得到一张蓝发女性的图像。

z_modified = z + alpha * direction_hair_color  # 沿特定方向调整
image_blue_hair = generator(z_modified)        # 生成蓝发图像

这非常酷。在下一节课中,我们将学习如何精确地调整 z

可控生成 vs. 条件生成

为了更好地理解可控生成,我们将其与条件生成进行快速比较。研究人员常用“可控生成”这个术语,虽然其定义有时并不完全清晰,有时它也包括条件生成,因为两者都以某种方式控制GAN。

以下是两者的主要区别:

  • 可控生成:你可以得到具有你想要的特定特征的示例,例如老年人、绿头发、戴眼镜的脸。它通常控制连续的特征(如年龄大小),并且可以在模型训练进行。
  • 条件生成:你可以得到你想要的特定类别的示例,比如“人类”或“鸟类”。当然,你也可以指定“戴太阳镜的人”。这通常需要在训练时使用标记数据集来实现。

简而言之,条件生成是“指定类别”,而可控生成更侧重于“调整特征的强度或数值”。你可能不想为每种发色都标注数据,可控生成可以帮你做到这一点。它更多是关于在潜在空间中找到代表特定特征的方向。

最后,正如你刚刚学到的,可控生成是通过调整输入噪声向量 z 来实现的,而条件生成则需要将表示类别的额外信息附加到噪声向量 z 上一起输入。

总结

本节课我们一起学习了可控生成。总结来说:

  • 可控生成让你能够控制生成对抗网络输出中的特征
  • 与条件生成对比,它通常不需要带标签的训练数据集
  • 为了以可控的方式改变输出,我们需要对输入的噪声向量 z 进行特定方向的调整。

通过掌握这种方法,我们可以在不重新训练模型的情况下,灵活地操控生成内容的各种属性。

P3:真实生活中的GAN 🎭 - 小土堆Pytorch教程

在本节课中,我们将要学习生成对抗网络(GAN)在现实世界中的各种酷炫应用。我们将看到GAN如何从生成逼真人脸发展到动画艺术作品,并了解一些大公司是如何利用这项技术的。

概述:GAN的惊人表现

即使GAN在2014年才被提出,它已经在多项任务中取得了惊人的表现。

如果你还没有见过GAN的一些成果,那么接下来你将会感到惊喜。在本视频中,我将向你展示GAN的一些酷炫应用,例如生成逼真的人类面孔和动画著名的艺术作品。

然后,你将看到一些大公司正在使用GAN进行的令人惊叹的项目。

GAN的演进历程 🚀

上一节我们概述了GAN的潜力,本节中我们来看看它自诞生以来的发展轨迹。

一条来自Ian Goodfellow(他被广泛认为是GAN的创造者)的推文,展示了GAN多年来改进的惊人可视化效果。

你可以看到GAN的进展:从2014年生成的黑白且不太像人类的面孔,发展到今天实际上更好。自那时起,进步只增不减。

在2020年初,Nvidia发布了StyleGAN2,可以生成分辨率极高、看起来像专业照片的图像。这些图像具有柔和的背景效果,很容易让人认为这些人是真实的,但他们实际上并不存在,这令人惊讶。

GAN的多样化应用 🖼️

上一节我们回顾了GAN的发展,本节中我们来看看GAN不局限于人像的多样化生成能力。

GAN可以从它们接收到的训练数据中学习,因此它们不限于复制人类面孔。这里是同一个模型,但这次生成的是猫。如果你仔细观察,可以看到一些非常奇怪的图像,因为并非每个生成的例子都是完美的。在这种情况下,这里确实有一些看起来像猫,但我当然不知道那具体是什么。

这同样是一件很酷的事情:你可以观察带有文字的图像。因为如前所述,生成模型试图模仿你训练它们的数据分布。在这种情况下,训练数据是从网络上抓取的所有猫的图片,这当然包括许多带有 meme 文字的猫 meme。有趣的是,这些生成的猫 meme 上的文字实际上并不构成真正的单词,因为生成模型的目标是建模视觉真实感,而不是语言。话说回来,其中一些生成的图像看起来非常可爱和真实。

图像转换与风格迁移 🐴➡️🦓

了解了GAN的生成能力后,我们来看看它在图像转换领域的应用。

GAN也可以进行图像转换,这意味着它们可以将一个域的图像转换为另一个域。

例如,它们可以将一匹马的图像转换为斑马的图像,反之亦然。真正有趣的是,你不需要具体的、动作完全相同的斑马和马的配对图片,只需要将风格转移过来。

从草图到照片级渲染 🎨

上一节我们看到了GAN转换现有图像的能力,本节中我们来看看GAN如何辅助创作。

GAN可以帮助你绘画。这个模型可以将一幅风景画的草图变成照片级的真实图像。

所以你可以在左边看到笔触,这是一个将不同物体(如云、山、湖)的粗糙笔触组合在一起的草图。然后,GAN能够从这个非常粗糙的草图中生成一个非常逼真的场景。

因此,如果一个人能够用很少的几笔和颜色做出粗糙的草图,那么GAN就可以将它们转化为逼真的图片。

肖像动画与3D生成 🗿

GAN的能力不仅限于2D图像生成和转换,它还能让静态肖像“活”起来。

GAN也可以拍摄静物肖像(例如蒙娜丽莎),并用任何真实人脸的动作来动画化它。驱动动画的真实人脸甚至不必看起来像所说的蒙娜丽莎。如果你联想到了《哈利·波特》中霍格沃茨会说话的肖像,在某种程度上,你的想法是对的。GAN就是魔法。

GAN不会止步于2D图像,它们还可以生成3D物体,如椅子和桌子。这些可以应用于生成设计等领域,例如为你的家创造酷炫的家具。

GAN在行业中的应用 🏢

我们已经看到了GAN在多个创意领域的应用,现在来看看它在实际产业中的价值。

在医学中也有多种应用。你可以使用GAN来生成人工医疗数据,甚至在X光片中检测异常。你将会在后续课程中看到更多这方面的内容。

多家知名公司也开始使用生成对抗网络(GAN)用于各种应用。

以下是部分公司的应用案例:

  • Adobe:正在考虑为Photoshop的下一代加入GAN功能,让新手艺术家达到专家水平,例如处理这些涂鸦。
  • Google:使用GAN进行文本生成,同时也用于图像生成。
  • IBM:使用GAN进行数据增强,生成合成示例以增强下游分类器的数据集。例如,当你没有足够的特定类别或特定类型的图像数据时。
  • Snapchat和TikTok:将它们用于新的创意滤镜,你可能已经见过并使用过。
  • 迪士尼:使用GAN进行超分辨率处理。

在专业化的末期,你将能够使用GAN进行你喜欢的任何应用。

总结 📝

本节课中我们一起学习了GAN在现实世界中的广泛应用。

总之,你看到了GAN在过去几年中取得的快速进展。在我向你展示了几个非常酷的应用之后,我提到了一些大公司如何使用生成对抗网络。实际上,GAN还有很多其他的用途等待探索。

P30:【2025版】30. Z空间中的向量代数 🔢

在本节课中,我们将学习生成对抗网络中“可控生成”背后的核心思想。我们将从回顾图像插值开始,逐步理解如何通过操纵输入生成器的噪声向量,来控制生成图像的特征。


回顾:图像插值

在之前的课程中,我们了解到可控生成是通过操纵输入生成器的噪声向量 z 来实现的。为了理解这个过程,我们先回顾一个相关概念:图像插值

图像插值是指,在两个由GAN生成的图像之间,生成一系列平滑过渡的中间图像。在实践中,你可以看到一张图片如何逐渐变成另一张图片。

以下是进行插值的基本步骤:

  1. 首先,我们有两个噪声向量,v1v2,它们位于一个被称为 Z空间 的向量空间中。Z空间是所有可能的噪声向量所在的空间。
  2. v1 输入生成器 G,得到图像 Image1;将 v2 输入生成器 G,得到图像 Image2
  3. 为了得到这两张图像之间的中间图像,我们在Z空间中对两个输入向量 v1v2 进行线性插值。这意味着我们计算一系列中间向量,公式为:
    v_interp = α * v1 + (1 - α) * v2
    其中,α 是一个从0到1变化的参数。
  4. 最后,将这些中间向量 v_interp 依次输入生成器 G,就能得到一系列在 Image1Image2 之间平滑过渡的图像。

因此,插值展示了在Z空间中移动向量,会如何系统性地改变生成器的输出。


从插值到可控生成

上一节我们介绍了图像插值,本节中我们来看看可控生成。你会发现,可控生成和插值在思路上是相似的,但目标不同。

可控生成同样利用Z空间的变化,并观察修改噪声向量如何反映在生成器的输出上。关键在于,我们需要找到Z空间中与特定特征变化相关的方向

举个例子:

  • 用一个噪声向量 v_red,生成一张红头发女士的图片。
  • 用另一个噪声向量 v_blue,生成一张蓝头发(其他特征相同)的女士图片。
  • 这两个向量之间的差异 d = v_blue - v_red,就代表了Z空间中一个特定的“方向”。沿着这个方向移动,就能修改生成图像中的头发颜色

在可控生成中,我们的目标就是为各种关心的特征(如笑容、年龄、发型等)找到这些隐藏的“方向向量” d


可控生成的实现方法

有了代表某个特征变化的方向 d,我们就可以控制GAN的输出了。这非常令人兴奋,因为它意味着我们可以有目的地编辑生成的内容。

以下是实现可控生成的基本操作:

  1. 首先生成一张初始图像。例如,使用噪声向量 v1 输入生成器 G,得到一张红发男士的图像。
  2. 为了修改他的头发颜色,我们只需将找到的“头发颜色方向” d 加到原始噪声向量上,创建一个新的噪声向量:
    v_new = v1 + β * d
    其中,β 是一个控制变化强度的系数。
  3. 将这个新向量 v_new 输入到同一个生成器 G 中,就能得到一张该男士头发变为蓝色的图像。

通过调整系数 β,我们可以控制特征变化的程度(例如,从深红变为浅蓝)。


挑战与总结

本节课中,我们一起学习了Z空间向量代数的核心概念。

总结如下:

  1. Z空间是生成器输入噪声向量所在的高维空间。
  2. 图像插值通过在两个向量间进行线性插值(v_interp = α * v1 + (1 - α) * v2),实现了图像间的平滑过渡。
  3. 可控生成的本质是在Z空间中寻找与特定特征(如头发颜色)对应的方向向量 d
  4. 通过在原噪声向量上加上该方向向量(v_new = v + β * d),即可实现对生成图像特征的定向编辑。

然而,可控生成也面临一些挑战,例如:

  • 如何准确且高效地找到对应不同语义特征的可靠方向 d
  • 当同时修改多个特征时,方向之间可能会发生干扰。
  • 确保沿着方向移动时,图像的其他无关属性保持不变。

理解Z空间中的这些向量操作,是掌握高级GAN应用的重要基础。在接下来的课程中,我们将深入探讨如何实际寻找这些控制方向。

P31:可控生成的挑战 🎯

在本节课中,我们将要学习可控生成技术所面临的两个主要挑战:输出空间的特征相关性Z空间的纠缠。理解这些挑战是掌握如何有效控制生成对抗网络(GAN)输出的关键。


概述 📋

可控生成技术允许我们决定生成图像的特征,例如人物的发色或发长。然而,在实际应用中,实现精确控制会遇到一些困难。本节课程将详细探讨这些挑战及其成因。


挑战一:输出空间的特征相关性 🔗

上一节我们介绍了可控生成的基本概念,本节中我们来看看第一个挑战——输出空间的特征相关性。当训练数据集中不同特征之间存在高度关联时,控制单一特征会变得困难。

例如,你希望控制生成图像中人物的胡须量。如果数据集中“胡须的存在”与“面部的男性化程度”这两个特征高度相关,那么当你尝试给一张女性图片添加胡须时,模型可能不仅会添加胡须,还会同时改变面部结构,使其更男性化。

以下是特征相关性导致的问题:

  • 你希望控制单一特征(如胡须)。
  • 但由于特征相关性,改变一个特征会连带改变其他相关特征。
  • 这导致你无法实现精确、独立的特征编辑。


挑战二:Z空间的纠缠 🌀

在了解了特征相关性的挑战后,我们再来看看另一个常见问题——Z空间的纠缠。Z空间是生成器的输入噪声空间。当Z空间发生纠缠时,意味着噪声向量不同方向上的变化会同时影响输出中的多个特征。

即使这些特征在原始数据集中并无关联,仅仅因为噪声空间的学习方式不够解耦,就会导致这个问题。

以下是Z空间纠缠的具体表现:

  • 当你试图改变人物的年龄时,可能同时改变了她的眼睛和头发颜色。
  • 当你试图给人物添加眼镜时,可能意外地改变了她的发型或胡须。
  • 噪声向量 z 中某个分量的变化,会同时改变输出图像的多个特征,公式上可以理解为:Δ输出 = f(Δz_i),其中 Δz_i 是噪声向量的一个变化,而 f 是一个复杂的映射,导致多个特征同时改变。

这种情况在Z空间的维度不足以清晰分离所有待控制特征时尤为常见,因为噪声向量无法与输出特征形成一一对应的关系。


总结 🏁

本节课中我们一起学习了可控生成面临的两大核心挑战。

  1. 输出空间的特征相关性:由于训练数据中特征本身存在关联,试图控制一个特征会不可避免地影响其他相关特征。
  2. Z空间的纠缠:由于生成器输入噪声空间的结构问题,调整噪声向量会同时改变输出中多个不相关的特征,使得独立控制变得困难。

理解这些挑战是后续学习如何解决它们(例如通过解耦表示学习)的第一步。只有克服了这些障碍,我们才能实现真正精准、可靠的可控图像生成。

P32:分类器梯度法控制GAN生成 👓

在本节课中,我们将学习一种利用预训练分类器的梯度来控制生成对抗网络输出特征的方法。这种方法无需修改已训练好的生成器权重,即可在潜在空间中找到调整特定特征(如添加墨镜)的方向。

概述

可控生成的核心思想是在生成器的潜在空间(z空间)中,沿着特定方向移动噪声向量,从而改变生成图像的特征。例如,我们可以通过移动z向量来“延长头发”或“缩短头发”。

上一节我们介绍了可控生成的基本概念,本节中我们来看看如何利用一个训练好的分类器来高效地找到这些控制方向。

方法原理

为了在z空间中找到修改特定特征(例如“是否戴墨镜”)的方向,我们可以使用一个已经训练好的分类器。这个分类器能够识别图像中的人是否佩戴了墨镜。

以下是实现这一目标的具体步骤:

  1. 准备一批噪声向量 z,并将其输入到已冻结权重的生成器 G 中,得到一批生成图像 G(z)
  2. 将生成的图像 G(z) 输入到预训练的墨镜分类器 C 中。
  3. 分类器会输出每张图像“戴墨镜”的概率。我们的目标是修改原始的 z 向量,使得 C(G(z)) 的输出概率(即戴墨镜的概率)增大。
  4. 为实现目标,我们计算分类器输出相对于输入噪声 z 的梯度。公式可以表示为:
    direction = ∇_z [ C(G(z)) ]
    这个梯度方向指示了如何微调 z 才能让分类器更确信图像中的人戴了墨镜。
  5. 我们沿着梯度方向更新 z 向量(例如 z_new = z + η * direction),同时保持生成器 G 的权重完全不变。
  6. 重复这个过程,直到生成的图像被分类器以高置信度判定为“戴墨镜”。

这种方法简单高效,因为它直接利用了分类器提供的“知识”来指导生成过程。

方法的优势与要求

这种方法的主要优势在于其简洁性和对现有模型的利用。你无需重新训练GAN,只需一个能准确识别目标特征的分类器即可。

然而,这种方法也有其前提条件:

  • 你需要一个针对目标特征(如墨镜、胡子、笑容等)预训练好的、性能可靠的分类器。
  • 如果现有公开模型中没有你需要的分类器,你可能需要自己收集数据并训练一个。

在决定采用此方法前,建议先调研是否有现成的预训练分类器可用,这通常是最快捷的途径。

总结

本节课中我们一起学习了如何利用分类器梯度来控制GAN的生成。核心要点是:

  • 预训练的分类器可以用来在GAN的潜在空间(z空间)中找到与特定输出特征相关的方向。
  • 通过计算分类器输出相对于噪声向量 z 的梯度,可以确定调整特征的方向。
  • 整个控制过程通过迭代更新噪声向量 z 来实现,生成器 G 的权重始终保持冻结、不被修改。

记住这个简单而强大的技巧,它让你能够快速为训练好的GAN模型添加可控生成的能力。

P33:【2025版】33. 解耦 🧩 - 小土堆Pytorch教程

在本节课中,我们将要学习生成对抗网络中一个重要的概念——解耦。我们将探讨什么是解耦的潜在空间,为什么它对可控生成至关重要,以及如何鼓励模型学习这样的空间。


回顾:纠缠与非纠缠的潜在空间

上一节我们介绍了潜在空间中“纠缠”的含义及其在可控生成中带来的问题。本节中,我们来看看其对立面——“解耦”或“非纠缠”的潜在空间。

一个解耦的潜在空间意味着,输入噪声向量 z 中的每一个维度(或一组维度)都独立地、明确地对应着生成输出(如图像)中的某一个特定特征。

例如,假设我们有以下两个噪声向量 v1v2,它们来自一个解耦的潜在空间:

# 示例:解耦的噪声向量
v1 = [z_hair_color, z_hair_length, z_other1, z_other2, ...]
v2 = [z'_hair_color, z'_hair_length, z'_other1, z'_other2, ...]

在这个例子中:

  • 噪声向量的第一个维度 z[0] 可能对应生成人像的发色
  • 噪声向量的第二个维度 z[1] 可能对应生成人像的发长

因此,如果你想改变生成图像中人物的发色,你只需要改变噪声向量中第一个维度的值。同样,要改变头发长度,只需改变第二个维度的值。其他维度的值可能不直接对应某个具体特征,但它们为模型提供了额外的灵活性,有助于学习更丰富的表达。

这些由噪声向量控制、决定输出外观但不直接显示在输出中的因素,通常被称为潜在因素变异因素


解耦与纠缠的关键区别

理解解耦空间的核心在于把握其与纠缠空间的关键区别。

解耦的潜在空间中,当你改变某个维度以控制一个输出特征(例如,是否戴眼镜)时,其他特征(如胡须、发型)会保持不变

反之,在纠缠的潜在空间中,改变一个维度可能会同时影响多个不相关的特征。例如,试图给一个女性形象添加胡须时,可能会意外地改变其面部轮廓或发型。

解耦空间的目标是实现精准、独立的控制,公式化地表达这一理想状态就是:
改变 z[i] → 仅改变 特征_i, 而 特征_j (j ≠ i) 保持不变。


如何鼓励模型实现解耦

鼓励模型学习解耦潜在空间主要有两大类方法。

方法一:使用带标签的数据(监督方法)

这种方法类似于条件生成,但信息嵌入的方式不同。

  • 核心思路:对训练数据进行标注(例如,为每张人脸图片标记发色、是否戴眼镜等),然后在训练过程中,引导模型将特定的标签信息与噪声向量中特定的维度关联起来。
  • 优点:如果标签准确,能较直接地引导模型学习解耦表示。
  • 挑战:需要大量人工标注数据。对于连续值特征(如头发长度),定义离散的类别(“桶”)可能不够精确且工作量大。

方法二:添加正则化项(无监督/半监督方法)

这种方法不需要对数据进行详细标注,而是通过修改损失函数来鼓励解耦。

  • 核心思路:在标准的GAN损失函数(如BCE损失或Wasserstein损失)基础上,增加一个正则化项。这个正则化项的设计目标是鼓励噪声向量的每个维度与输出图像的某个独立特征相关联。
  • 常见技术:许多先进方法利用分类器的梯度作为正则化信号的来源。例如,训练一个辅助分类器来识别图像中的某个属性(如微笑),然后通过分析生成器对此属性最敏感的噪声维度,来建立关联。
  • 优点:避免了繁重的数据标注工作。
  • 公式示意
    总损失 = 原始GAN损失 + λ * 正则化项
    其中,正则化项用于惩罚不同特征维度之间的相关性。

以下是两种方法的简要对比:

方法 是否需要详细标签 核心思想 优点 缺点
监督方法 将标签信息编码进噪声向量的特定维度 目标明确,引导直接 标注成本高,对连续特征处理不便
无监督方法 在损失函数中添加鼓励解耦的正则化项 无需标注,灵活性高 实现复杂,解耦效果可能不如监督方法明确


总结

本节课中,我们一起学习了生成对抗网络中解耦潜在空间的概念。

我们首先明确了解耦空间的含义:它是一个噪声向量 z 的每个维度独立控制生成输出单一特征的空间。这与纠缠空间形成对比,在纠缠空间中,改变一个维度会影响多个特征。

接着,我们探讨了鼓励模型实现解耦的两种主要途径:

  1. 使用带标签数据的监督方法,通过将类别信息嵌入噪声向量来引导模型。
  2. 通过添加正则化项的无监督方法,修改损失函数以鼓励噪声维度与输出特征间的独立性。

掌握解耦技术对于实现精准、可控的图像生成至关重要,是迈向高级生成模型应用的关键一步。

P34:课程1总结 🎉 - 小土堆PyTorch教程

在本节课中,我们将对课程一的学习内容进行总结,并展望课程二的核心主题与学习目标。

恭喜你完成课程一的学习。你已经掌握了构建最先进生成对抗网络所需的基础知识。

上一节我们回顾了课程一的成果,本节中我们来看看课程二将要探索的精彩内容。在课程二中,你将深入学习生成对抗网络在逼真图像生成中的具体应用。这一应用是图像生成领域的一个重大转折点,其意义堪比从90年代的模糊手机图像质量飞跃到现代的高清电影画质。

那么,如何量化这些GAN模型的改进程度呢?在课程二中,你将找到答案。你将学习生成对抗网络如何推动逼真图像生成的发展,这标志着图像生成技术的重大进步,其跨越幅度正如从早期的低分辨率图像时代进入高清视觉时代。

因为你们在课程二中将要构建的模型非常激动人心且技术先进,这些模型正被集成到各种产品中,并影响着人们的生活。因此,确保与这些技术相关的人员能够负责任地使用和处理它至关重要。负责任的一个关键方面是理解模型可能存在的偏见。

以下是课程二你将深入探索的议题:

  • 你将探究当这些强大的模型被投入使用时,它们可能并未以一种完全公平的方式运作。

所以,请做好准备。课程二的目标是让你不仅掌握必要的技术知识,同时建立起构建模型的责任感。正是这类模型让GANs声名远扬。请记住:能力越大,责任越大。

本节课中我们一起回顾了课程一的完成情况,并介绍了课程二的核心方向——聚焦于GAN在图像生成中的突破性应用、其评估标准,以及随之而来的技术责任感。我们下一课程再见。

课程2:生成对抗网络进阶 🚀

在本课程中,我们将深入学习生成对抗网络的进阶概念与应用。我们将从风格生成等前沿算法开始,探讨GAN的替代方案,学习模型评估方法,并深入讨论GAN技术的社会影响与伦理问题。

概述 📋

欢迎来到生成对抗网络的第二门课程。在第一课中,你学会了构建一个基本的GAN,并接触了DCGAN、条件GAN等改进模型。在本课程中,我们将把这些想法进一步深化。

核心内容详解

1. 风格生成与前沿算法 🎨

上一节我们回顾了基础,本节中我们来看看更前沿的生成技术。风格生成是当前生成人脸及其他物体的尖端算法。它能生成极其逼真的图像,以至于人们难以分辨其真实性。例如,网站 thispersondoesnotexist.com 展示了此类技术的成果。

该技术的核心在于其高度的可控性。你可以精细地控制生成器的输出,例如调整发型的细节。其目标是生成多样化且逼真的图像,避免陷入“模式崩溃”,即模型只反复生成少数几种样本。

2. GAN的替代方案与模型评估 ⚖️

除了GAN,本课程还将介绍其他生成模型,例如变分自编码器模型。同时,我们将学习如何评估生成模型,这涉及对生成样本的多样性技术指标进行量化分析。

以下是模型评估中需要考虑的几个关键方面:

  • 多样性:确保模型能生成广泛类型的数据,而非单一模式。
  • 真实性:评估生成样本与真实数据的接近程度。
  • 稳定性:监控训练过程,防止模式崩溃等问题。

3. GAN的社会影响与伦理责任 🌍

技术能力伴随着社会责任。本课程将深入探讨GAN的社会影响,包括其正面和负面应用。

我们必须正视GAN技术可能带来的问题,例如:

  • 偏见问题:曾有案例显示,GAN将低分辨率的奥巴马图像转换成了白人形象,这揭示了算法中可能存在的偏见。
  • 深度伪造:生成逼真假内容可能被滥用,造成信息混乱和信任危机。

因此,作为技术的构建者和使用者,我们必须思考如何负责任地开发与应用GAN。积极的影响,例如利用GAN合成图像来帮助公众理解气候变化等重大问题,其潜力远大于负面用例。

一个特别的项目是使用GAN合成图像,以帮助人们更直观地理解气候变化的影响。

总结 ✨

本节课中我们一起学习了生成对抗网络的进阶知识。我们探讨了风格生成等前沿算法,了解了GAN的替代方案与评估方法,并重点讨论了技术的社会影响与伦理责任。希望你在掌握这些强大技术的同时,能始终以负责任和积极的态度运用它们,为解决重要问题贡献创意与力量。我们非常期待看到你将创造的东西。

🎵 P36:【2025版】36. 无监督学习与GAN评估入门

在本节课中,我们将要学习生成对抗网络(GANs)的基本概念,并重点探讨如何评估一个GAN模型的性能。我们将通过类比来理解无监督学习与监督学习的区别,并介绍评估生成模型的核心思路。


🎹 监督学习与无监督学习的类比

上一节我们介绍了课程背景,本节中我们来看看GAN所属的无监督学习与常见的监督学习有何不同。

你可能更熟悉监督学习。可以将其模式想象成一名钢琴学生,他的任务是学习弹奏《闪烁的小星星》。我们可以根据他击中的正确音符数量错误音符数量来明确评估其学习成果。这个过程有清晰的对错标准。

但是,使用生成对抗网络(GANs)的生成模型则属于无监督学习。实际上,你是在试图让你的“学生”成为一名作曲家,而不是演奏者。这里没有确切的、固定的“正确音符”让他去击中。


🎼 GAN的评估思路

既然没有标准答案,那么我们该如何评估一个“作曲家”的水平呢?关键在于观察其作品的高层次特征

你可以分析它生成的旋律所具有的一般模式,并将这些模式与伟大音乐作品的特征进行比较。换句话说,评估转向了对整体结构和特征的考量。

以下是将此思路应用于图像生成领域的例子:

  • 在生成面部图像的任务中,评估者会观察诸如眼睛是否对称,或者鼻子下方是否有嘴唇等特征。
  • 接着,将这些生成图像的特征与真实图像的特征进行比较。

📊 评估的关键:统计性而非单一性

当然,你不能仅凭一个样本来评判GAN的好坏。

因为你的GAN有可能只是“灵光一现”,生成了一张极其逼真的图像,但除此之外再也无法产生高质量的输出。这就像一个作曲家只写出了一小节美妙的旋律,却无法完成整首乐曲。

因此,对于GAN的评估,你必须查看它在一段时间内生成的许多样本,从统计意义上判断其整体生成质量。评估必须是基于大量输出的、综合性的分析。


🚀 本周学习与实践

在本周的课程中,你将探索上述方法以及其他多种评估GAN性能的技术。你也将在你的家庭作业中亲自实践这一评估过程。


本节课中我们一起学习了无监督学习下的GAN与监督学习的根本区别,理解了评估生成模型需要关注其输出的高层次特征并与真实数据分布进行比较,同时明确了评估必须基于大量样本进行统计分析的核心理念。

P37:【2025版】37. 评估GAN 🧐 - 小土堆Pytorch教程

在本节课中,我们将要学习如何评估生成对抗网络(GAN)。评估GAN是衡量其性能的关键步骤,我们将了解评估的挑战性以及需要关注的核心属性。


评估GAN的挑战

上一节我们介绍了评估GAN的重要性,本节中我们来看看为什么评估GAN具有挑战性。

评估GAN与评估其他模型有相似之处。通常,您会取一个模型的检查点权重,并在某一点冻结它们。然后比较其输出与一些指标。这些指标可以在模型之间使用,不仅仅是为自己的独立评估。

然而,评估生成对抗网络(GANs)是一项特别具有挑战性的任务,这是一个活跃的研究领域,最近取得了很大进展。为了说明这一点,我们可以与监督学习进行对比。

在监督学习中使用分类器,有一些测试你可以通过。这些图像上有标签,告诉你它们应该如何分类。根据这些标签,你可以评估你的模型是否正确或错误。通常这里有一个保留的测试集,你可以评估你的模型是正确的还是错误的。这个测试集可以用来评估你的模型或其他人的模型。

然而,对于生成对抗网络,你将一些随机噪声输入进去,然后你得到这个假图像。但是没有一个明确的方法来判断这些生成的图像有多真实。你不知道它应该生成的确切像素。你不能说,这里的像素稍微不对或对。因为那里没有明确的目标告诉你应该生成什么像素,给定这个噪声向量。

所以这个模型更像是一个高级艺术家学习如何绘制杰作,而不是学习已知画作中的精确笔触。这就是分类器的正确性,因为对错分明。

此外,这个判别器区分真实与虚假,永远不会达到完美,常常过度拟合于区分真实与虚假的图像。所以你可能会想,因为它在真实与虚假的图像之间分类,也许它对此有用。但是不,这是对生成器过度拟合,所以它很可能会认为你特定生成器中的很多图像,尽管它们看起来逼真,实际上是假的,因为它们可以捕捉到某些特性,而这些特定的特性可能很小,有时甚至是生成器产生的可感知的东西。

因此,没有完美的或通用的判别器可以同时看两个生成器,并且明确指出这个比另一个更好。


评估GAN的核心属性

既然我们了解了评估的挑战,那么,你是如何评估生成式对抗网络的呢?你可以首先定义你想要的属性。

以下是评估GAN时需要考虑的两个主要属性:

  1. 真实性:一个主要目标是生成图像的质量,以及它们看起来多么真实。你可以将整体质量和确定性整体视为其真实度因素。但也包括图像的清晰度,例如,一个模糊的脸可能看起来仍然很真实,但这并不是真正的高保真度。
  2. 多样性:仅仅生成一个单一的图像不是你想要的。一个好的生成器也能产生良好的图像多样性。范围是什么?这个生成器能够产生的图像多样性是什么?它是否能够产生训练数据集中的固有多样性,或者你正在建模的所需类别。

总之,我们有两个属性,真实性多样性,它们位于两个轴上,有时你可以将它们视为在二者之间进行权衡。


深入理解真实性

上一节我们介绍了两个核心属性,本节中我们首先深入探讨真实性

对于真实性,你可以考虑你的图像看起来有多真实。这样想,对于每个假样本,它与最近的真实样本有多不同?你也可以更广泛地思考,即一百个假样本与一百个真实样本有多远,以获得更好的代表性。你不想再出现一锤子买卖,你不想错过好的和坏的高、低真实性样本。因为这些可能会区分这个扫描与其他GAN,你想要一个能够持续提供好结果的GAN。

你可以用几种方法来进行这种比较。你将在后续课程中学习一些方法。


深入理解多样性

了解了真实性后,我们来看看另一个关键属性:多样性

关于多样性,你想要生成的图像覆盖整个真实分布的多样性。这意味着,如果GAN只生成相同的单一图像,即使它非常真实,那不是一个表现良好的模型。你可能记得这与模式崩溃类似。

所以你需要一个能够生成不同图像的GAN。例如这些用不同风格写的数字“8”。你也可以测量并感知到,例如100个样本的分布,与100个真实样本的分布。

在评估GAN时,真实性和多样性都是你关心的标准。通过捕捉真实性和多样性,你可以得到一个很好的关于你生成器生成假图像质量的概念,这可能只是看你的假图像与你的真实图像有多接近。


总结

本节课中我们一起学习了如何评估生成对抗网络(GAN)。

总之,评估GAN是具有挑战性的,因为没有全局判别器,提供可以作为基准来公平比较不同GAN的ground truth。为了评估GAN,你需要考虑真实性,即图像的质量,以及多样性,即那些图像的多样性。有了这些属性和标准,你才能全面、客观地衡量一个GAN模型的性能。

P38:图像比较方法 📊

在本节课中,我们将学习如何比较图像,特别是在评估生成对抗网络(GAN)时,如何衡量生成图像与真实图像在真实性和多样性上的差异。我们将介绍两种核心方法:像素距离和特征距离。

概述

评估生成对抗网络时,在真实性和多样性上比较图像可能具有挑战性。关键在于确定比较的标准。本节将探讨两种方法:简单但不够可靠的像素距离,以及更可靠的特征距离。

像素距离法

比较图像最简单的方法是查看它们像素之间的差异,这种方法称为像素距离。

对于一个真实图像和一个假图像,您可以计算它们对应像素值的绝对差值。

具体步骤如下:

  1. 将一张图像的像素值(范围从0到255)与另一张图像的对应像素值相减。
  2. 取差值的绝对值。
  3. 汇总所有像素的绝对差值,得到总差异。

公式表示如下:
像素距离 = Σ |真实图像像素值 - 生成图像像素值|

当两张图片完全相同时,总差异为零,表示它们没有距离。然而,像素距离实际上并不可靠。

像素距离的局限性

上一节我们介绍了像素距离的计算方法,本节中我们来看看它的主要问题。

像素距离对微小的、人眼难以察觉的位移非常敏感。例如,想象一张图片整体向左移动了一个像素。

尽管图像内容几乎完全相同,但基于像素距离的计算会产生巨大的绝对差异值。对于一张高分辨率、拥有数百万像素的图像,即使只移动一个像素,所有错位的像素都会产生非零的差值,导致最终计算出一个巨大的像素距离总和,这并不能准确反映图像内容的相似度。

特征距离法

由于像素距离的局限性,我们需要一种更稳健的比较方法。另一种选择是关注图像的高级语义特征,而不是原始的像素值。

这种方法的核心思想是:通过神经网络等工具提取图像的高级特征(例如,物体是否有两只眼睛、鼻子的位置、毛发纹理等),然后在特征空间中进行比较。这种高级语义信息对像素级的微小移动或变化敏感性较低。

以下是特征距离法的基本思路:

  1. 使用预训练模型(如分类网络)提取图像的特征向量。
  2. 比较真实图像和生成图像的特征向量之间的距离(例如,计算欧氏距离或余弦距离)。

代码描述其核心过程如下:

# 伪代码示例
real_features = feature_extractor(real_image) # 提取真实图像特征
fake_features = feature_extractor(fake_image) # 提取生成图像特征
feature_distance = calculate_distance(real_features, fake_features) # 计算特征距离

通过比较特征,我们可以更有效地评估图像在高级语义层面的相似性。例如,即使两张狗的图片背景不同,只要它们都包含“两只眼睛”、“一个鼻子”、“下垂的耳朵”等关键特征,它们在特征空间中的距离就会很近。而一张生成质量很差的图像(例如,有五条腿或两个鼻子),其特征向量会与真实图像的特征向量相距甚远。

总结

本节课中我们一起学习了两种比较图像的方法。

  • 像素距离:计算简单,但过于敏感且不可靠,容易受到像素级微小扰动的影响。
  • 特征距离:这是一种更优的替代方法。它通过提取图像的高级语义特征,并在特征空间中计算距离,从而实现对图像内容相似性更稳健、更可靠的评估。这种方法在GAN评估及其他计算机视觉任务中都非常常见。

在后续课程中,我们将深入探讨如何具体提取这些特征以及计算特征距离的细节。

P39:特征提取 🧠 - 小土堆PyTorch教程

在本节课中,我们将学习如何从图像中提取特征。这些特征对于计算图像之间的相似度或差异至关重要,例如在评估生成对抗网络(GAN)生成图像的质量时。

概述:什么是特征提取?

特征提取是从原始数据(如图像)中获取有意义的、可度量的信息的过程。在图像处理中,我们通常不直接比较像素值,而是比较从图像中提取出的、能代表其核心内容的“特征”。

为了计算真实图像与生成图像之间的特征距离,我们需要一种提取特征的方法。一个高效的方法是使用在大规模图像数据集上预训练好的分类器模型。

为何使用预训练分类器? 🤔

你可能会问,是否需要为每次评估都训练一个新的分类器?答案是否定的。

有些神经网络已经在数百万张图片上进行了预训练,并且能够识别成百上千个类别。这些模型已经学习了如何从图像中提取有用的特征。因此,我们可以直接使用这些公开可用的预训练模型作为特征提取器,并将其应用于各种GAN模型的评估中。

这些预训练分类器通常在大型数据集(如ImageNet)上训练,使其能够建模广泛的自然图像特征。

如何从分类器中提取特征? ⚙️

要使用预训练分类器进行特征提取,我们并不关心其最终的分类结果。我们看重的是网络在完成分类任务过程中所学到的、有助于决策的中间特征。

因此,我们可以“截断”网络,移除最后的分类层(通常是全连接层),然后获取其前一层的输出。这一层包含了关于输入图像的高度浓缩和有用的信息。

以下是一个典型的卷积神经网络(CNN)结构示意:

输入图像 -> [卷积层 -> 激活函数 -> 池化层] x N -> 全连接层 -> 输出预测

我们可以移除最后的全连接层,使用最后一个池化层的输出作为特征。因为这个池化层包含了最丰富的信息,足以传递给后续的分类层。

假设网络最后一个池化层输出了100个值,这100个值就代表了模型从输入图像中提取出的特征向量。这个过程将高维的像素数据压缩成了一个低维的特征表示。

选择哪一层作为特征层? 🔍

使用最后一层(分类层之前)是常见做法,因为它包含的信息最综合、最具判别性。然而,它也可能过度拟合于原始训练任务(如ImageNet的1000类分类)。

使用更早的层也是可行的。随着向网络前端回溯,提取的特征会变得更基础、更通用。例如,最早的卷积层可能只学习到检测“垂直边缘”这样的基础模式。

选择哪一层作为特征层是可以实验的。对于初学者,建议从最后一个池化层开始尝试,因为它基于广泛的数据集训练,通常能提供良好的通用特征。

关键数据集:ImageNet 🗂️

ImageNet是一个包含1400多万张图像、覆盖2万多个类别的大型数据集。在ImageNet上预训练的模型(如VGG, ResNet)学习到了大量关于自然物体、动物、场景的特征。

从这些模型中提取的特征,有时被称为 ImageNet嵌入。嵌入(Embedding)指的是将数据(如图像)映射到一个低维向量空间的过程。在这个特征空间嵌入空间中,相似的图像对应的向量距离也更近。

总结 📝

本节课我们一起学习了特征提取的核心概念:

  1. 目的:为了高效比较图像,我们需要提取其核心特征。
  2. 方法:利用在大规模数据集(如ImageNet)上预训练的分类器模型。
  3. 操作:通过移除模型的最后一层(分类层),获取其前一层的输出作为特征向量。这个过程可以形式化地表示为:
    # 伪代码示意
    features = pretrained_model.cut_last_layer(input_image)
    
  4. 选择:通常使用最后一个池化层的输出作为特征,但也可以尝试更早的层以获得更基础的特征。
  5. 概念:提取出的特征向量也称为嵌入,它们存在于一个特征空间中,用于度量图像间的相似性。

在接下来的课程中,我们将具体学习如何使用一个流行的、在ImageNet上预训练的分类器模型来实际进行特征提取。

P4:【2025版】4.GAN背后的直觉 🧠 - 小土堆Pytorch教程

在本节课中,我们将要学习生成对抗网络(GAN)背后的核心思想。我们将了解GAN的两个关键组成部分——生成器与判别器——是如何通过相互对抗与学习,最终生成以假乱真的数据的。


概述

生成对抗网络(GAN)是一种强大的生成模型,它能够学习生成逼真的数据,使其难以与真实数据区分开来。这种能力是通过让两个神经网络——生成器与判别器——相互竞争来实现的。

上一节我们介绍了GAN的基本概念,本节中我们来看看这两个组件是如何具体工作的。


GAN的两个核心组件

GAN包含两个不同的神经网络:生成器判别器

  • 生成器 的目标是学习生成看起来足够真实的“假”数据,以“愚弄”判别器。
  • 判别器 的目标是学习区分输入的数据是来自真实数据集还是由生成器创造的“假”数据。

你可以将这个过程想象成一场“猫鼠游戏”:

  • 生成器 如同一个伪造名画的画家。
  • 判别器 如同一个艺术鉴定专家。

生成器不断尝试画出更逼真的赝品来骗过鉴定专家;而鉴定专家则在一次次鉴别中,练就了更敏锐的眼力来识破伪造。两者在对抗中共同进步。


训练过程的直观理解

为了开始这场“游戏”,我们首先需要一个真实的数据集,例如一批著名的画作。

初始状态

在训练开始时,两个组件都非常“幼稚”。

  • 生成器 不知道真实画作应该是什么样子。它最初只能生成一些随机的、像涂鸦一样的图像。我们可以用公式表示生成器的目标:生成器试图最大化判别器对其生成样本的误判率
  • 判别器 同样不具备鉴别能力。它会被给予混合了真实画作和生成器早期“涂鸦”的一批图像,但它最初无法正确区分它们。

对抗训练的开始

以下是训练循环的关键步骤:

  1. 固定生成器,训练判别器
    我们将一批真实图像和一批由当前生成器产生的假图像混合,输入给判别器。我们会告诉判别器每个图像的“真实”标签(1代表真实,0代表假)。通过这个过程,判别器开始学习区分好坏。例如,它可能学会识别出那些明显的“涂鸦”是假的。

  1. 固定判别器,训练生成器
    接着,我们使用训练后的判别器来评估生成器新产生的一批假图像。判别器会为每个假图像输出一个“真实性”分数(例如,60%像真的)。生成器的目标就是改进自己,使得下一批假图像能获得更高的分数。这个过程可以用代码逻辑表示:
    # 伪代码示意:生成器的损失函数通常旨在最大化判别器对假样本的输出
    generator_loss = -log(D(G(z)))  # 希望D(G(z))接近1(即判别器认为生成的是真的)
    
    通过判别器提供的反馈(分数),生成器知道了改进的方向,从而画出稍微更像真实作品的图像。

  1. 循环迭代
    上述两个步骤交替进行。生成器的作品越来越逼真(例如,从涂鸦进步到能画出模糊的人脸),而判别器为了不被骗,也必须不断提升自己的鉴别能力,去发现更细微的伪造痕迹。

训练的终点

经过多轮这样的对抗训练,生成器产生的图像会越来越难以与真实图像区分。最终,当生成器产生的图像质量达到我们的要求,以至于判别器难以有效分辨时(例如,判别器对假图像的判断置信度接近50%,即随机猜测),训练就可以结束。此时,我们就得到了一个能够生成高质量逼真图像的生成器。


核心要点总结

本节课中我们一起学习了GAN背后的直觉:

  1. GAN由生成器判别器两个神经网络组成,它们通过对抗过程进行学习。
  2. 生成器的目标是生成足以欺骗判别器的假数据。
  3. 判别器的目标是准确区分真实数据与生成器产生的假数据。
  4. 两者在交替训练中相互促进:判别器为生成器提供改进方向的反馈,而生成器不断升级的“造假”技术又迫使判别器变得更加强大。
  5. 最终目标是获得一个能生成高质量样本的生成器。

在下一个视频中,我们将深入探讨GAN的数学模型和损失函数。

P40:Inception v3与嵌入提取教程 🧠

在本节课中,我们将学习Inception V3网络,并了解如何将其用作特征提取器来获取图像的“嵌入”表示。这种技术对于比较图像(例如评估生成对抗网络GAN)非常有用。


概述 📋

在上一个视频中,我们学习了如何使用在大型数据集上训练过的分类器作为特征提取器。本节我们将聚焦于一个具体且常用的网络:Inception V3。我们将了解其结构,并学习如何从中提取一个称为“嵌入”的紧凑特征向量,用于后续的图像比较任务。


Inception V3网络架构 🏗️

Inception V3是一个复杂的卷积神经网络分类器,通常在ImageNet数据集上进行训练。它虽然层数较深,但在计算成本和效率方面取得了良好的平衡,并且在分类任务中表现出色。更重要的是,它作为一个特征提取器特别有效。

既然我们要用它来提取特征以比较真实图像与生成图像,下面我们来看看它的具体结构。

从分类器到特征提取器 ✂️

要将Inception V3用作特征提取器,我们需要进行一些修改。以下是关键步骤:

  1. 移除全连接层:我们切除网络末端的全连接层(原本用于输出ImageNet的1000个类别)。
  2. 获取中间层输出:我们使用最后一个池化层(平均池化层)之前的卷积层输出。该输出的维度通常是 8 x 8 x 2048
  3. 生成嵌入向量:将这个 8 x 8 x 2048 的特征图通过一个全局平均池化层(使用1个滤波器),最终得到一个 2048维的向量。这个向量就是图像的“嵌入”。

这个2048维的嵌入向量,本质上是网络将输入图像的关键信息压缩后的表示。与原始图像(例如1024x1024x3,超过300万个像素值)相比,嵌入向量的维度缩小了超过1000倍。这种压缩使得后续的图像比较操作更加高效。


理解“嵌入” 🧩

从数学角度看,特征提取模型应用了一个映射函数。对于Inception V3,这个函数可以表示为:

embedding = f(x)

其中:

  • x 是输入图像(可以是真实图像或生成图像)。
  • f 代表修改后的Inception V3网络(移除了全连接层)。
  • embedding 是输出的2048维特征向量。

这些提取出的特征被称为图像的嵌入,因为它们将图像映射到了一个更低维度的语义空间。在这个空间中,语义相似的图像,其嵌入向量的值也会彼此接近。

例如,两只不同的金毛犬图片,尽管在像素层面上可能有差异(如位置、姿态),但它们的嵌入向量在2048维空间中的距离会很近。而一张椅子的图片,其嵌入向量则会与狗的嵌入向量相距甚远。


嵌入向量的比较与应用 ⚖️

上一节我们介绍了如何获取嵌入向量,本节中我们来看看如何利用它们进行比较。

为了评估GAN,我们通常需要比较一批真实图像和一批生成图像的特征。以下是进行特征比较的基本思路:

  • 直接向量运算:可以计算所有真实图像嵌入的均值向量,以及所有生成图像嵌入的均值向量,然后计算这两个均值向量之间的距离(如欧几里得距离)。
  • 分布距离:更高级的方法是,将真实图像和生成图像的嵌入分别视为两个概率分布,然后计算这两个分布之间的距离(例如,弗雷歇距离)。

与直接比较像素相比,比较嵌入特征的优势非常明显。像素距离对微小的偏移(如物体位置移动几个像素)非常敏感,可能导致两个语义相同的图像被认为差异很大。而特征距离关注的是高级语义(如“这是一只浅色毛、粉红鼻子的狗”),因此对这类变化更加鲁棒。


总结 🎯

本节课中我们一起学习了:

  1. Inception V3网络:一个高效且强大的卷积神经网络,可作为优秀的特征提取器。
  2. 嵌入提取:通过移除网络末端的全连接层,并利用最后一个池化层前的输出,我们可以为任何输入图像生成一个紧凑的2048维特征向量(嵌入)。
  3. 嵌入的意义:嵌入将图像压缩到低维语义空间,相似图像的嵌入在空间中彼此接近。
  4. 比较方法:通过计算真实图像嵌入和生成图像嵌入的均值距离或分布距离,可以有效地评估生成图像的质量,这比直接比较像素更合理、更高效。

在接下来的课程中,我们将具体学习如何计算这种特征距离。

课程P41:Fréchet Inception距离 (FID) 🧮

在本节课中,我们将要学习Fréchet Inception距离(FID),这是目前衡量生成图像与真实图像之间差异最流行的指标。我们将从基础的Fréchet距离概念讲起,逐步理解如何将其应用于图像特征,并最终掌握FID的计算原理、应用及其局限性。

1. 什么是Fréchet距离? 🐕

上一节我们介绍了FID是一个衡量图像生成质量的指标,本节中我们来看看其核心的数学基础——Fréchet距离。

Fréchet距离以数学家Maurice Fréchet命名,是一种用于测量两条曲线之间距离的度量方法。这个概念也可以扩展到比较两个概率分布。

一个经典的比喻是“遛狗人”问题:狗在一条曲线(蓝色)上行走,主人在另一条曲线(橙色)上行走。两者都可以按自己的速度前进,但不能后退。Fréchet距离就是计算从起点到终点,所需的最短狗绳长度。这个长度保证了在整个行走过程中,狗绳始终足够长,无需中途加长。

核心思想:它衡量的是两条曲线在“对齐”行走时的最大瞬时距离。

2. 从曲线到分布:Fréchet距离的推广 📊

理解了曲线间的Fréchet距离后,我们可以将其思想推广到概率分布的比较上。对于许多常见的分布,Fréchet距离存在解析解。

例如,对于两个一维正态分布,它们之间的Fréchet距离有简单的计算公式。设两个分布分别为X和Y,其均值分别为μ_x和μ_y,标准差分别为σ_x和σ_y。

它们之间的Fréchet距离公式为:
d² = (μ_x - μ_y)² + (σ_x - σ_y)²

这个公式直观地结合了分布中心(均值)的差异和分布形状(标准差)的差异。

3. 多元正态分布与协方差矩阵 🧩

真实世界的数据(如图像特征)往往非常复杂,无法用简单的一维分布描述。因此,我们需要使用多元正态分布来建模。

多元正态分布将正态分布推广到高维空间。可视化一个简单的二元正态分布,如果两个维度互不影响(独立),其概率密度图会像一个对称的圆形山丘。

然而,维度之间常常相互影响。这种影响通过协方差矩阵来描述。协方差矩阵概括了方差的概念:

  • 对角线上的元素是每个维度自身的方差。
  • 非对角线上的元素衡量两个不同维度之间的协方差(即它们如何共同变化)。

以下是协方差矩阵的示例:

Σ = [ σ₁²   cov(x₁,x₂) ]
    [ cov(x₂,x₁)   σ₂² ]

其中,cov(x₁, x₂)表示维度1和维度2的协方差。正值表示正相关,负值表示负相关,零表示独立。

4. 多元Fréchet距离公式 🔢

现在,我们可以将一维的Fréchet距离公式推广到多元情况,用于比较两个多元正态分布。

设我们有两个多元正态分布:

  • 真实分布:均值向量为 μ_x,协方差矩阵为 Σ_x
  • 生成分布:均值向量为 μ_y,协方差矩阵为 Σ_y

它们之间的Fréchet距离公式为:
d² = ||μ_x - μ_y||² + Tr(Σ_x + Σ_y - 2 * sqrt(Σ_x * Σ_y))

让我们分解这个公式:

  1. ||μ_x - μ_y||²:计算两个均值向量之间的欧几里得距离的平方。这衡量了分布中心的差异。
  2. Tr(...):表示矩阵的迹,即矩阵对角线元素之和。这部分衡量了两个分布形状(由协方差矩阵描述)的差异。
  3. sqrt(Σ_x * Σ_y):表示矩阵的平方根运算。

这个公式正是一维公式在多元空间中的自然推广。

5. 应用于图像:Fréchet Inception距离 (FID) 🖼️

了解了多元Fréchet距离后,我们来看它如何应用于评估生成对抗网络(GAN)。这就是Fréchet Inception距离(FID)。

以下是FID的计算步骤:

  1. 提取特征:使用在ImageNet上预训练好的Inception V3网络(通常是最后一层池化层之前的激活值),分别提取大量真实图像和生成图像的特征向量。这些特征向量就是图像的“嵌入”。
  2. 拟合分布:假设这些特征向量服从多元正态分布。分别用真实图像的特征和生成图像的特征,拟合出两个多元正态分布。即计算它们的均值向量和协方差矩阵。
  3. 计算距离:使用上一节的多元Fréchet距离公式,计算这两个拟合分布之间的距离。这个距离值就是FID分数。

核心要点:FID分数越低越好。分数越低,说明生成图像的特征分布与真实图像的特征分布越接近,即生成图像的质量越高、多样性越好。

6. FID的优缺点与局限性 ⚖️

尽管FID被广泛使用,但它也存在一些局限性,在使用时需要注意。

以下是FID的主要优点:

  • 计算高效:相比需要人工评估的指标,FID可以自动、快速计算。
  • 感知相关:由于使用了深度网络特征,它与人类对图像质量的感知有一定相关性。
  • 综合评估:同时考虑了生成图像的质量(均值)和多样性(协方差)。

以下是FID的主要缺点和注意事项:

  • 对特征提取器敏感:FID依赖于Inception V3网络提取的特征。如果生成的任务领域(如医学图像、卫星图像)与ImageNet的自然图像差异很大,这些特征可能不具代表性。
  • 需要大样本量:为了稳定地估计分布的均值和协方差,需要成千上万的图像样本。样本量不足会导致分数有偏差。
  • 样本量偏差:即使使用同一个生成模型,用更多样本计算出的FID分数通常会更低(显得更好),这并非理想属性。
  • 基于正态分布假设:FID假设图像特征嵌入服从多元正态分布,但这往往只是一个近似。它只捕捉了分布的一阶矩(均值)和二阶矩(协方差),忽略了更高阶的统计特性(如偏度、峰度)。
  • 分数无标度:FID分数没有固定的范围(如0到1),其绝对值大小不易直接解释,通常用于模型间的相对比较。

因此,在实践中,FID应作为重要的定量参考指标,但绝不能替代开发者的定性检查(肉眼观察生成样本)。最佳的模型选择需要综合定量分数和定性分析。

总结 📝

本节课中我们一起学习了Fréchet Inception距离(FID)。

我们首先从Fréchet距离的直观概念入手,理解了它如何衡量曲线或分布间的差异。接着,我们学习了多元正态分布和协方差矩阵,这是理解高维数据分布的基础。然后,我们推导了多元Fréchet距离的公式,并最终将其应用于图像生成领域,解释了FID的计算流程:通过Inception网络提取特征,拟合多元正态分布,再计算分布间的距离。

最后,我们探讨了FID的优缺点。记住,FID是一个强大且流行的工具,但它也有其假设和局限。在评估和优化生成模型时,请务必结合FID分数与对生成样本的视觉检查。

P42课程:Inception分数详解 🧠

在本节课中,我们将学习一种用于评估生成对抗网络(GAN)性能的经典指标——Inception分数。我们将了解其核心思想、计算方法、优缺点,以及它与FID等现代指标的区别。


概述 📋

Inception分数是一种衡量生成图像“真实性”和“多样性”的指标。它使用在ImageNet数据集上预训练的Inception V3分类器,通过分析生成图像的分类概率分布来计算得分。虽然该指标已被FID等更先进的指标广泛取代,但理解其原理对于阅读早期论文和全面掌握GAN评估方法仍然非常重要。


Inception分数的核心思想 💡

上一节我们介绍了Inception分数的基本概念。本节中,我们来看看其背后的核心思想。

Inception分数主要评估生成图像的两个方面:

  1. 清晰度/保真度:单张生成图像是否清晰、明确地属于某个类别。
  2. 多样性:所有生成图像是否覆盖了广泛的类别。

如何评估清晰度?

将一张生成图像输入Inception V3分类器,会得到一个类别概率分布 p(y|x)。例如,一张图片可能被分类为:狗(0.6)、猫(0.3)、鸟(0.1)。

  • 高清晰度:概率分布集中在少数类别(甚至一个类别)上,即熵值低
    • 公式:H(p(y|x)) 较低。
  • 低清晰度:概率分布均匀分散在许多类别上,即熵值高

如何评估多样性?

收集大量生成图像,计算所有图像类别标签的边缘分布 p(y)。这个分布反映了生成器产出了哪些类别的图像。

  • 高多样性p(y) 在所有类别上分布均匀,即熵值高
    • 公式:H(p(y)) 较高。
  • 低多样性/模式崩溃p(y) 集中在少数几个类别上,即熵值低

一个理想的生成器应同时具备低熵的 p(y|x)(图像清晰)和高熵的 p(y)(类别多样)。这两个分布差异越大越好。


Inception分数的计算 🧮

理解了清晰度和多样性的概念后,我们来看看如何将它们结合成一个单一的分数。

Inception分数使用KL散度来衡量条件分布 p(y|x) 与边缘分布 p(y) 之间的差异。KL散度越大,说明两个分布差异越大,即生成器的性能越好(既清晰又多样)。

以下是Inception分数的计算公式:

IS(G) = exp( E_{x~p_g} [ KL( p(y|x) || p(y) ) ] )

其中:

  • G 代表生成器。
  • p_g 是生成图像的数据分布。
  • KL( p(y|x) || p(y) ) 是条件分布 p(y|x) 相对于边缘分布 p(y) 的KL散度。
  • E 表示对所有生成图像 x 求期望(平均值)。
  • exp 是指数函数,用于将分数放大到一个更易读的范围(例如,1到1000之间,对应ImageNet的1000个类别)。

分数解读

  • 分数越高越好
  • 最低理论值为1(当 p(y|x)p(y) 完全相同时,KL散度为0)。
  • 在ImageNet上,最高理论值接近类别数1000。

Inception分数的优缺点 ⚖️

任何指标都有其适用范围和局限性。以下是Inception分数的主要优缺点。

优点

  • 单一指标:将保真度和多样性结合为一个易于比较的数字。
  • 无需真实数据:计算时只需要生成的图像,不需要与真实图像库进行比较。
  • 历史地位:曾是GAN领域最流行的评估指标之一,大量经典论文引用。

缺点与局限性

然而,Inception分数存在一些显著缺陷,这也是它被FID取代的主要原因。

以下是其主要缺点:

  1. 容易被“欺骗”:生成器可以针对指标进行优化。例如,为ImageNet的1000个类别各生成一张完美的图片,就能获得接近满分,但这显然不是真正的多样性(无法生成同一类别的不同变体)。
  2. 不与真实数据比较:这是最根本的问题。它只评估生成图像“内部”的分布,不关心生成分布是否与真实数据分布匹配。一个生成器可能得到高分,但其生成的图像风格可能与真实世界相去甚远。
  3. 依赖特定分类器:分数高度依赖于Inception V3分类器的能力和偏见。如果生成图像的特征不在分类器的训练集(ImageNet)范围内,评估就会不准确。
  4. 对空间关系不敏感:分类器关注物体是否存在,而非其位置和结构关系是否合理。一张五官错位但特征清晰的人脸可能获得高保真度分数。
  5. 领域不匹配:当生成任务的目标域(如人脸、医学图像)与ImageNet差异很大时,该分数基本失效。


与FID的对比及总结 🎯

我们已经详细探讨了Inception分数的原理和局限。现在,让我们将其与当前主流指标FID进行简单对比,并总结全文。

与FID的核心区别

  • Inception分数:使用分类器的输出层概率,评估生成图像的内部统计特性(清晰度、多样性)。
  • FID分数:使用分类器的中间层特征,计算生成图像与真实图像在特征空间分布的相似度(使用Frechet距离)。

总结
本节课中,我们一起学习了:

  1. Inception分数的目标:量化生成图像的清晰度(低熵的 p(y|x))和多样性(高熵的 p(y))。
  2. 计算方法:利用KL散度衡量两个分布的差异,并通过指数运算得到最终分数 IS(G) = exp(E[KL(p(y|x)||p(y))])
  3. 优缺点:其优点是提供单一、便捷的评估值;但缺点明显,包括易被欺骗、不与真实数据比较、依赖分类器等。
  4. 历史地位:作为GAN发展史上的一个重要里程碑,Inception分数帮助推动了早期研究,但目前已被更鲁棒、更可靠的FID分数所取代。

对于现代研究,建议优先使用FID作为评估指标。但理解Inception分数对于阅读文献和深入理解生成模型评估的演进仍然至关重要。

P43:【2025版】43. 采样和截断 🎲✂️

在本节课中,我们将要学习生成对抗网络(GAN)评估中的两个重要技巧:采样截断。你将了解如何通过不同的采样策略来影响生成图像的质量与多样性,并掌握一个在模型训练完成后用于调整生成效果的实用技巧。


概述

你已经了解了GAN的主要评估方法。本节将深入探讨评估过程中的具体技巧,特别是如何通过控制噪声向量的采样来影响生成结果。我们将从采样策略的重要性开始,然后介绍一个广泛使用的“截断技巧”,最后讨论人类评估在GAN发展中的关键作用。


采样策略的重要性

上一节我们介绍了GAN的评估框架,本节中我们来看看评估时一个基础但关键的环节:如何采样生成图像

在评估时,真实数据与伪造数据的统计数据都很重要。你会发现它们之间存在差异。一个在训练后可以进行的技巧是调整采样策略,以偏向更高的真实性或多样性。

以下是关于采样策略的核心要点:

  • 真实数据采样:对于真实数据,通常可以随机均匀地采样。
  • 伪造数据采样:对于伪造数据,通常的做法是根据训练时使用的噪声向量 z 的先验分布进行采样。
  • 常用先验分布:在训练GAN时,通常使用正态分布作为噪声向量 z 的分布,其公式为 z ~ N(0, 1)。这意味着接近零的向量值在训练中出现频率更高。
  • 采样位置的影响:使用接近零的 z 值进行采样,生成的图像质量(保真度)通常较高,但会导致多样性降低。使用远离零的 z 值采样,可能会生成更奇怪、多样性更高但质量较差的图像。

因此,你的采样技术实际上成为评估和后续应用的一个重要方面。因为像FID或Inception Score这样的评价指标是基于模型生成的样本运行的,而非模型参数本身,这意味着评估结果在很大程度上依赖于你所采样的图像。


截断技巧:权衡保真度与多样性

遵循对保真度与多样性之间权衡的观察,有一种叫做截断技巧的采样方法被广泛使用。

截断技巧是一个在模型训练完成后进行的后处理步骤,它通过在保真度和多样性之间进行权衡来调整生成效果。

该技巧的核心是截断训练时使用的正态分布(例如 N(0,1))的尾部。通过设定一个超参数(截断阈值),决定保留分布中心的多少部分,而舍弃两端的极端值。

以下是截断技巧的工作原理:

  • 追求高保真度:如果你希望生成图像的质量和真实感更高,你应在零附近采样,并截断更大比例的尾部(即使用较高的截断阈值)。但这会减少生成图像的多样性,因为一些“古怪”但可能新颖的样本被排除在外。
  • 追求高多样性:如果你希望生成图像的多样性更大,你应在分布的尾部更多地采样,并使用较低的截断阈值。然而,这些图像的保真度可能会降低,因为生成器在训练时很少接收到关于这些极端噪声向量应生成何种“真实”图像的反馈。

你当然也可以使用不同的先验噪声分布(如均匀分布)来训练模型。但正态分布之所以流行,正是因为人们可以方便地在其上应用截断技巧来调整权衡。

研究表明,当人们尝试不同的先验噪声分布时,并未发现显著区别。正如预期的那样,一个模型的FID分数在缺乏多样性或保真度时会变差。因此,使用截断技巧生成的样本在自动化指标上可能表现不佳,但在特定的下游应用中,若你需要更高保真度的图像且不希望出现“垃圾”输出,这个技巧可能非常符合你的需求。


人类感知评估:最终的标尺

说到使用那些截断后“在人眼中看起来更好”的样本,我们必须承认,使用人类进行评估仍然是GAN评价的重要组成部分,通常是开发过程中的关键环节。

自动化评价指标仍然不能完全捕捉我们想要的生成质量,因此人类感知评估仍然设定着基准和标准。

最近开发的一种基于原则的众包感知任务系统,为GAN评估提供了一种系统化方法。它被称为 HYPE(Human eYe Perceptual Evaluation,人眼感知评估)。

HYPE的工作方式是向众包评估者(如亚马逊 Mechanical Turk 工作者)连续展示一系列图像,并要求他们判断每张图片是真实的还是伪造的。

HYPE的一个变体版本会以不同的毫秒时长闪现图片,以测试评估者在多短的时间内能判断图片真伪。你的生成模型越好,人类就需要更长的时间来判断图片是否是伪造的。而HYPE Infinity版本则移除了时间阈值,只是简单地浏览图片。

当然,最终的评估将取决于你想要的下游任务。例如,如果你的GAN生成的是带有肺炎的X光图像,你希望确保专业医生认可其真实性,而不是让非专业人士或预训练在ImageNet上的分类器来做决定。


总结

本节课中我们一起学习了GAN评估中的采样与截断技巧。

现在你知道了如何通过在训练期间使用的 z 的先验分布来采样伪造图像。在测试或推理阶段,你还掌握了一个新技巧——截断技巧。它可以让你通过截断采样分布的尾部(或多或少),来调整你是对更高的保真度还是更高的多样性感兴趣。

虽然自动化的评价指标是一个良好的近似,但它们仍无法完全替代人类感知。人类评估在设定质量基准方面仍然至关重要,而HYPE等方法为快速评估图片质量提供了系统化的途径。

感谢你花时间学习。请继续关注关于其他新评估方法的更多内容。

P44:【2025版】44. 精确率与召回率 🎯

在本节课中,我们将学习生成对抗网络(GAN)及其他生成模型的两个重要评价指标:精确率召回率。我们将理解它们如何分别衡量生成样本的真实性多样性,并探讨它们之间的关系。


概述

在生成模型的评价中,除了传统的指标,近年来出现了一些新的评价方法。其中,将分类任务中的精确率召回率概念扩展到生成模型领域,是一种特别值得注意且有趣的做法。它帮助我们更直观地理解生成器的性能。


核心概念:真实分布与生成分布

首先,我们引入两个核心分布:

  • 真实分布 (Pr):代表真实数据(例如,真实的人脸图片)在数据空间中的概率分布。
  • 生成分布 (Pg):代表生成器模型(如GAN的生成器)能够生成的所有样本的分布。

理想情况下,生成器的最佳目标是让生成分布 Pg 与真实分布 Pr 完全重叠。这意味着生成器不仅能生成逼真的样本,还能覆盖真实数据的所有变化。


精确率 (Precision)

上一节我们介绍了两个核心分布,本节中我们来看看精确率

精确率关注的是生成样本的质量。它衡量在所有生成的样本中,有多少是“好”的(即看起来真实的)。

以下是精确率的直观解释:

  • 分子(交集):生成的、且与真实分布重叠的样本(即看起来逼真的假样本)。
  • 分母(整个生成区域):生成器能够生成的所有样本,包括逼真的和“垃圾”的。

因此,精确率的公式可以理解为:
精确率 = (看起来真实的生成样本数量) / (所有生成样本的数量)

高精确率意味着生成器产生的样本大部分质量都很高,看起来很真实。但它不要求生成器能生成所有类型的真实样本。即使生成器只擅长生成某一小类逼真的图像(例如,只生成正面人脸),它的精确率也可能很高。

核心要点:精确率与生成样本的真实性保真度直接相关。


召回率 (Recall)

理解了衡量质量的精确率后,我们再来看看衡量覆盖范围的召回率

召回率关注的是生成样本的多样性。它衡量生成器能够覆盖多少真实数据分布。

以下是召回率的直观解释:

  • 分子(交集):同样是生成的、且与真实分布重叠的样本。
  • 分母(整个真实区域):所有可能的真实样本。

因此,召回率的公式可以理解为:
召回率 = (看起来真实的生成样本数量) / (所有真实样本的数量)

高召回率意味着生成器能够建模出真实数据中几乎所有的变化和模式。它衡量的是生成器的“创造力”或覆盖能力。

核心要点:召回率与生成样本的多样性直接相关。


精确率与召回率的权衡

在实际的生成模型中,尤其是参数量巨大的现代模型(如大型GAN),往往存在一种权衡。

模型通常更容易获得较高的召回率,因为它有足够的能力去记忆和覆盖训练集中的所有模式,甚至生成更多变化。然而,这也可能导致它产生许多不属于真实分布的、奇怪的“垃圾”样本,从而拉低精确率

这就引出了截断技巧的应用。通过限制生成器的输入噪声范围,可以牺牲一部分多样性(召回率),来过滤掉那些低质量的生成样本,从而显著提升生成样本的整体质量(精确率)。这对于许多下游应用(如图像编辑、合成)非常有用。


总结

本节课中,我们一起学习了生成模型评价中的两个关键指标:

  1. 精确率:衡量生成样本的质量。高精确率意味着“生成的样本大多很逼真”。
  2. 召回率:衡量生成样本的多样性。高召回率意味着“生成器能创造出真实数据中的各种类型”。

你现在可以将精确率与真实性关联,将召回率与多样性关联。理解这种权衡有助于你评估模型,并在实际应用中使用像截断技巧这样的方法来优化模型输出,以获得最佳性能。

你已经完成了本周课程的所有理论材料,准备好进入实践环节吧。找出你的最佳模型检查点,享受编码的乐趣!

课程P45:【2025版】45. 欢迎来到第2周 👋

在本节课中,我们将要学习生成式对抗网络(GAN)的局限性、其替代方案,以及机器学习模型中普遍存在的偏见问题。我们将探讨这些概念,为后续负责任地使用先进生成模型打下基础。


概述

到目前为止,在这一专业中,你主要关注了生成式对抗网络的优点。

但同样重要的是要理解,并意识到使用这些模型可能存在的缺点和负面影响。

但对于这些缺点中的一些,你将了解其他生成模型的知识。

这些模型是生成式对抗网络的替代品,可以解决这些问题。

别担心,尽管它们有弱点,但它们在现实生成方面仍然是最好的。

你还将接触到所有机器学习,包括所有生成模型和生成式对抗网络中固有的缺陷。

以及所有生成模型和生成式对抗网络中固有的缺陷,并且这就是偏见的主题。

偏见以许多不同的方式被引入,包括数据集。

但是,你也需要考虑你的损失函数和你的评价方法在其他方面的影响。

你将在一个使用当前技术的模型中看到一个偏见的例子。

那将模糊的像素图像转化为高分辨率图像,一种被称为上采样的过程。

除了这次,它被上采样成了一个像素化模糊的奥巴马图像,谁是混血,有着高分辨率的白人。

所以本周的兴奋点是探索这种偏见。

为了赋予你知识,负责任地处理最先进的GAN状态,因为权力越大,责任越大。


生成模型的优缺点

上一节我们介绍了本周的学习目标,本节中我们来看看生成式对抗网络的具体优缺点。

生成式对抗网络(GAN)由两个神经网络组成:生成器(G)判别器(D),它们通过对抗过程进行训练。其核心目标函数(损失函数)可以简化为:

min_G max_D V(D, G) = E_{x~p_data(x)}[log D(x)] + E_{z~p_z(z)}[log(1 - D(G(z)))]

尽管GAN在生成逼真数据方面表现出色,但它们也存在一些固有缺陷。

以下是GAN的一些主要缺点:

  • 训练不稳定:生成器和判别器的平衡难以维持,容易导致模式崩溃。
  • 评估困难:缺乏一个简单、客观的指标来衡量生成样本的质量和多样性。
  • 计算资源需求高:训练复杂的GAN模型通常需要大量的时间和算力。

替代生成模型

了解了GAN的弱点后,我们自然会问:是否有其他选择?本节中我们来看看可以解决这些问题的替代生成模型。

这些模型旨在克服GAN的某些局限性,例如提高训练稳定性或提供更明确的概率分布。

以下是几种重要的替代方案:

  • 变分自编码器(VAE):通过学习数据的潜变量分布来生成新样本,其训练目标是最小化重建误差和潜空间分布与先验分布(如标准正态分布)之间的KL散度。
    损失函数 = 重建损失 + β * KL散度
  • 自回归模型(如PixelCNN):通过显式地对数据点的条件概率分布进行建模来生成数据,顺序地生成每一个像素。
  • 标准化流(Normalizing Flows):通过一系列可逆变换将简单分布转换为复杂的数据分布,允许精确的概率密度计算。

机器学习中的偏见问题

上一节我们介绍了不同的生成模型,但所有模型都面临一个共同挑战:偏见。本节中我们深入探讨偏见是如何产生及其影响的。

偏见可能以多种方式被引入机器学习系统,其影响深远,尤其是在生成模型中。

偏见的主要引入途径包括:

  • 数据集偏见:训练数据未能公平、全面地代表现实世界。例如,人脸数据集如果过度包含某一特定肤色的人群,模型对其他肤色人群的生成效果就会变差。
  • 算法设计偏见:损失函数和评价指标的设计可能无意中强化或引入偏见。如果优化目标只关注某类样本的“逼真度”,模型就会倾向于生成该类样本。
  • 评估方法偏见:用于评估模型性能的基准或测试集本身可能存在偏见,导致评估结果失真。

偏见实例分析:图像超分辨率

理论需要结合实际。现在,我们来看一个具体的偏见例子,它发生在图像上采样(超分辨率)任务中。

描述的例子揭示了一个关键问题:一个旨在将模糊低分辨率图像转化为高清图像的技术,当输入一张前总统奥巴马(作为混血人士)的模糊照片时,却生成了一张具有高分辨率白人特征的面孔。

这个过程可以简述为:
低分辨率模糊图像 -> [上采样模型] -> 高分辨率清晰图像
然而,由于训练数据中某种特征的过度代表,输出图像的种族特征发生了不应有的改变。

这个案例清晰地表明,即使是最先进的技术,如果其训练数据或目标函数存在偏见,也会产生具有社会危害性的输出。因此,探索和理解这种偏见,对于负责任地开发和应用最先进的GAN及其他生成模型至关重要。因为能力越大,责任越大。


总结

本节课中我们一起学习了生成式对抗网络的局限性、几种重要的替代生成模型(如VAE、自回归模型),并重点探讨了机器学习中普遍存在的偏见问题。我们了解到,偏见可能通过数据集、算法设计和评估方法被引入系统,并通过一个图像超分辨率的实例看到了偏见的具体表现。掌握这些知识,将帮助我们未来更负责任、更谨慎地使用强大的生成式AI技术。

P46:GAN的缺点 🧐

在本节课中,我们将学习生成对抗网络(GAN)的一些主要缺点。了解这些局限性对于全面掌握GAN技术至关重要。

之前我们学习了如何让GAN工作,并主要关注了其优点,例如它能够生成惊人的逼真效果。现在,我们将看到GAN的一些缺点,这对于学习任何新技术都同样重要。

优点回顾

在深入探讨缺点之前,我们先简要回顾一下GAN的显著优势。

  • 生成高质量图像:GAN可以生成对肉眼来说非常逼真的图像,以至于可能被误认为是真实存在的。
  • 快速生成:一旦拥有训练好的模型,加载模型权重并输入噪声,即可快速生成对象。

GAN的主要缺点

然而,GAN也存在其固有的缺点。以下是几个关键方面。

1. 缺乏明确的评估指标 🎯

GAN缺乏明确、理论上的内在评价指标。你无法仅通过查看模型权重或输出就轻易判断哪个模型更好。为了评估GAN,通常需要比较许多生成样本的特征,并与真实图像进行对比。但即使这种方法也不完全可靠,它只是理想评价方法的一种近似估计。

2. 训练不稳定与耗时 ⏳

在训练过程中,模型可能会不稳定,并且需要很长时间才能收敛。这有时感觉更像是一门艺术而非科学,因为梯度下降并不总能得到你想要的生成器。例如,模式崩塌(Mode Collapse)就是一个典型问题,即生成器卡在生成有限几种样本(如所有输出都是数字“7”)的模式上。你不能简单地继续训练并期望GAN自动收敛,需要经常检查并在合适时机停止训练,这通常需要定性检查生成的样本。不过,这个问题在一定程度上已被 Wasserstein LossLipschitz连续性 等技术所缓解。

3. 缺乏显式的概率密度估计 📊

GAN模型通常不提供对建模特征的显式概率密度估计。这意味着你无法直接计算某个特定图像(或其特征)出现的可能性(即概率 P(x))。这种密度估计能力对于异常检测等任务很有用,例如,通过判断一张“狗”的图片是否具有低概率特征来发现异常。虽然可以通过大量样本来近似得到某种密度估计,但GAN本身并不直接提供这一功能。

4. 生成器通常不可逆 🔄

标准的GAN生成器没有被训练成可逆的。这意味着常规任务是输入一个噪声向量 z 并输出一张图片 G(z)。而相反的任务——输入一张图片 x 来找出其对应的潜在噪声向量 z(即 G^{-1}(x))——则非常困难。虽然已有一些新方法(如使用另一个模型或设计双向GAN)来解决可逆性问题,但这并非标准GAN的固有特性。

可逆性对于图像编辑特别有用。它意味着你可以将任何图像(包括真实图像)映射回其潜在空间中的噪声向量,然后利用可控生成技术(例如调整年龄、发色等属性)来修改这个噪声向量,从而实现对原图的编辑。

总结与展望

本节课我们一起学习了GAN的主要缺点。

总结来说,GAN虽然能产生难以置信的高质量结果并支持相对快速的样本生成,但也存在以下局限性:缺乏内在的评估指标训练过程可能不稳定(尽管已得到部分解决)、模型不提供显式的概率密度估计,以及将图像转换回其潜在表示具有挑战性

尽管如此,强调GAN在生成高保真结果方面的能力依然非常重要。GAN可以说是最早也是最好的能实现如此逼真且一致输出的AI模型之一。因此,GAN的技术经常被用于增强其他模型的输出真实性,并在许多不同领域得到应用。

在下一个视频中,我们将继续探索GAN的更多相关内容。

P47:GAN的替代方案 🧠

在本节课中,我们将学习生成对抗网络(GAN)之外的其他生成模型。我们将重点介绍变分自编码器(VAE),并简要了解自回归模型、流模型以及混合架构。通过学习这些替代方案,你将理解它们如何解决GAN的某些缺点,以及它们各自的特点和权衡。

概述

在上节课中,我们了解了生成对抗网络(GANs)的缺点。本节课中,我们将探讨其他生成模型如何解决这些缺点,但它们也有各自不同的权衡。具体来说,我们将讨论另一种流行的模型——变分自编码器(VAE),以及其他一些不那么流行但非常酷的替代方案。

生成模型可以是任何试图建模 p(x|y) 的机器学习模型,或者如果它只是建模那一类,这可能是数据中 x 的概率。通常它会引入某种噪音或随机性,这样每次生成的结果都不同,这意味着输出结果的多样性。然后输出代表该类的特征或对象。生成器模型包括更多内容,远不止GAN。

深入探讨变分自编码器(VAE) 🏗️

上一节我们介绍了生成模型的基本概念,本节中我们来看看变分自编码器(VAE)这一重要的生成模型家族。

变分自编码器(VAE)是另一种大型生成模型家族。提醒一下,上周我们学过,VAE使用两种不同的模型工作:一个编码器和一个解码器

以下是VAE的基本工作原理:

  • 通过将真实图像输入编码器来学习,找到一种良好的方式来表示这张图像在潜在空间中。
  • 然后取这个表示(或接近它的表示),并用解码器重构编码器之前看到的真实图像。

我刚才描述的大致就是自编码器,它是VAE的一部分。而“变分”部分稍微复杂一些,但它使得模型能够以一种方式进行训练,以最大化生成真实数据或图像的概率,就像实际数据输入到编码器中一样。

所以从宏观角度来看,VAE试图最小化生成分布和真实分布之间的差异。这通常被认为是一个稍微容易的优化问题,能导致更稳定的训练,但也常被认为会导致结果模糊或低保真。

在训练完VAE之后,实际上会去掉编码器(就像你不需要GAN的判别器一样),然后你用解码器类似于生成器:你从潜在空间中采样点,就能够生成一个输出图像。

VAE与GAN的对比 ⚖️

了解了VAE的基本原理后,我们来对比一下它与GAN的优缺点。

如果你记得GAN的优缺点,VAE在大多数方面是相反的。

  • 通常认为VAE生成的结果质量低于GAN,或者至少不是第一个产生逼真结果的。他们确实落后于GAN,并且需要更多的工程和调整。
  • 但他们可以进行密度估计,并且可以很容易地进行反向处理,因为他们有一个编码器来尝试找到那个潜在空间表示。这可能不是一个完美的逆向(意味着它不是正好一对一),但它能让你得到一个不错的噪声因素,并且训练也更加稳定和可靠,尽管可以说它相当慢。

但是GANs的阵营会说,所有这些都很好,但是如果你不能生成好的样本,那就没用。因此,为了改善VAE的结果,已经投入了大量的工作。

这里是一个很近的VAE的例子,叫做VQ-VAE2。左边是VQ-VAE2,右边是GAN。你可以看到GAN的质量稍微高一些,但是VAE也开始有更好的结果,特别是在多样性这里,就像你看到的生成的鱼一样。还有这个VAE式的模型,VQ-VAE2借鉴了很多VAE的概念,但是它实际上不被认为是一个纯粹的VAE解决方案,事实上它也依赖于自回归网络组件。

其他生成模型简介 🌈

除了VAE,还有其他类型的生成模型。接下来,我们简要了解一下自回归模型和流模型。

那么自回归模型是什么?它是一种模型,通过看之前的像素来确定下一个像素。也许它看到了这里的几个像素,然后它能够确定那个图像的其余像素。这也是另一种生成模型,它根据之前的像素逐个像素生成。所以你可以认为这是它在之前的像素上的条件,来确定下一个像素。它看不到未来的像素,只能看到过去的像素。如果你熟悉RNNs或语言和语音模型,这个概念也很相似:你不能看到未来。

正如你所能猜到的,这个模型并不是完全无监督的,因为它依赖于那些之前的像素。所以它是一种有监督的技术,这意味着它需要锚定像素来开始生成,不能直接从噪声中生成。

另一种生成模型是流模型。这些训练起来很难也很耗时,但是它是一个很酷的新想法,基于似然来找到一个可逆映射,从噪声到生成的图像。这是一个基于似然的新想法,因此很明显,它将是可逆的。

在高层次上,它正在做的是从一个初始的简单分布开始,它找到一系列可逆变换来创建更复杂的分布。假设它从非常简单的东西开始,它有这些可逆映射(这些映射由箭头表示),最终得到更复杂的分布,最终它能够建模人脸。这是一个名为Glow的流模型示例。

混合架构 🧬

最后,你也可以将这些模型或想法结合起来,形成混合架构,试图从两个或多个世界中获益。这就是你之前看到的VAE自回归模型,称为VQ-VAE-2。还有许多GAN-VAE模型将两者的概念结合起来。你也将在课程三中看到一些先进的模型。

总结

本节课中我们一起学习了GAN的几种重要替代方案。

总之,VAEs在很大程度上与GANs的优缺点列表相反。值得注意的是,结果通常更模糊(尽管这是有争议的),但它可以估计密度,易于逆向,训练稳定。然而,GANs在许多方面已经改进了这些缺点,因为训练已经大大稳定下来,并且近似反演(这是你需要编辑图像的)已经减少到一个工程问题,即通过另一个模型找到你的z向量。这些在结果上也取得了长足的进步。

总的来说,当我们谈到应用时,我认为GANs在生成真实图像是主要目标时仍然更有用。正如你在这个视频中所看到的,其他替代性的生成模型包括自回归模型、流模型,以及其他所有这些模型的混合模型。

现在,你已经学习了其他生成模型。你将探索机器学习中普遍存在的问题,GANs,以及这些其他模型当然不会对这些问题免疫。

P48:【2025版】48. 机器偏见入门 🔍 - 小土堆Pytorch教程

在本节课中,我们将要学习机器学习中的一个重要社会议题:机器偏见。我们将通过分析一个真实案例,了解偏见如何被嵌入算法,以及它可能带来的严重后果。

概述:什么是机器偏见? 🤖

机器偏见是指人工智能和机器学习模型在决策过程中,系统性地对特定群体产生不公平或歧视性结果的现象。这种现象并非源于技术本身,而是反映了训练数据或算法设计中所包含的人类社会偏见。

上一节我们介绍了机器偏见的定义,本节中我们来看看一个具体的案例研究。

案例背景:COMPAS风险评估算法 ⚖️

《机器偏见》系列文章揭示,美国司法系统越来越多地依赖名为“COMPAS”的商业风险评估算法来预测被告未来犯罪的可能性。该算法的目的是减少量刑中的主观偏见。

以下是关于COMPAS算法的几个关键事实:

  • 算法目的:旨在通过计算风险评分,为法官提供客观参考,以减少预审和量刑阶段的偏见。
  • 专有性:算法的具体计算方法是公司的商业秘密,未向公众公开。
  • 数据输入:评分基于被告填写的问卷及其犯罪记录。问卷中不直接询问种族,但包含诸如“你的父母是否有人进过监狱?”或“饥饿的人偷窃是否错误?”等问题。
  • 影响:法官可参考此风险评分来增加或减少刑期。

算法表现与偏见证据 📊

尽管设计初衷是减少偏见,但研究发现COMPAS算法本身存在显著的种族偏见。

上一节我们了解了算法的基本构成,本节中我们来看看它的实际表现数据。

研究发现,该算法在预测暴力犯罪再犯率时,整体准确率仅为 20%。然而,更严重的问题在于其错误在不同种族群体间的分布并不公平。

以下是算法预测错误的具体分析:

  • 假阳性错误(错误地将低风险者标记为高风险):非裔美国人被告被错误标记为高风险的比例约为 45%,而白人被告的这一比例约为 23%
  • 假阴性错误(错误地将高风险者标记为低风险):白人被告被错误标记为低风险的比例约为 48%,而非裔美国人被告的这一比例约为 28%

这些数据表明,该算法更倾向于将黑人被告错误地评估为高风险,而更倾向于将白人被告错误地评估为低风险。

具体案例对比 👥

为了更直观地理解偏见的影响,我们可以对比两个具体案例。

以下是两个被告的对比情况:

  • 格雷戈里·卢戈(白人男性):有三次酒驾前科及一次袭击记录。他的COMPAS风险评分为 1分(低风险)
  • 玛洛里·威廉姆斯(黑人女性):仅有两次轻罪记录,首次面临严重指控。她的COMPAS风险评分为 6分(高风险)

尽管威廉姆斯的犯罪历史明显更轻,但她却获得了高得多的风险评分,这直观地体现了算法结果的不公平性。

偏见带来的现实后果 ⛓️

高风险评分会对个人的生活产生直接的、严重的负面影响。

以下是两个受评分影响的真实案例:

  • 保罗·齐利:因复吸并盗窃被判刑。在法官看到其高风险评分后,刑期从1年增至2年。上诉后虽减至18个月,但上诉法官指出,若无此评分,他本可能只被判6个月至1年。
  • 萨奇·琼斯:18岁,无前科,因骑未上锁的自行车被捕。尽管被评估为“中等风险”,其保释金仍从0美元被提高到1000美元。犯罪记录导致她至今难以找到工作。

这些案例说明,一个有偏见的模型预测,足以改变一个人的判决结果和未来人生轨迹。

总结与思考 💡

本节课中我们一起学习了机器偏见在司法系统中的具体体现。

为了在刑事司法中预测再犯风险而创建的模型,本意是减少偏见,但实际上往往只是反映并放大了社会中已有的偏见。这给历史上被边缘化的群体带来了更困难的处境。

此外,由营利性公司开发的专有软件带来了额外问题:

  1. 不透明性:计算方法不公开,使得独立审计和改善系统变得异常困难。
  2. 评估冲突:软件准确性的调查常由开发者自身进行,缺乏独立监督。
  3. 视角局限:这类模型无法全面评估一个人,例如他们真诚改过的努力,或刑期对其家庭造成的深远影响。

理解机器偏见的存在与危害,是开发更公平、更负责任的人工智能系统的第一步。

P49:定义公平 🔍

在本节课中,我们将探讨机器学习模型中的“公平性”概念。我们将了解公平性为何难以精确定义,并学习几种常见的公平性定义方式。


上一节我们讨论了模型偏见,本节中我们来看看如何具体衡量一个模型是否公平。指南针模型的偏见似乎显而易见,但公平性本身是一个复杂的理想概念。事实上,不同的研究论文依赖于公平性的不同定义。

以下是公平性的几种常见定义方式:

  • 人口统计学平行 / 结果独立:模型预测结果的分布应独立于“敏感属性”(如种族、性别)。这意味着,对于敏感属性的不同取值,模型预测的期望值应该完全相等。
    • 核心概念P(预测 | 敏感属性=A) = P(预测 | 敏感属性=B)
  • 代表性结果:模型在测试集上产生的结果,其人口统计比例应与现实世界的人口分布相匹配。
    • 举例:在美国,生成亚洲人面孔的图像生成模型,其输出中亚洲人面孔的比例应接近美国亚裔人口的实际比例(约6%)。
  • 平等机会:模型在不同群体中应具有相同的假阳性率或假阴性率。这在风险评估等模型中尤为重要。
    • 核心概念P(错误预测 | 敏感属性=A) = P(错误预测 | 敏感属性=B)

如你所见,公平性有三种不同的定义。显然,并不存在一个单一的、普适的公平性定义,以上只是三种非常基本的定义方式,当然还存在其他定义。

尽管没有单一的公平性定义,但我们仍然可以观察到,在所有这些定义下,几乎所有模型都可能存在公平性缺失的问题。


总之,公平性难以精确定义,也没有一个放之四海而皆准的定义。这就是为什么在将机器学习系统部署到生产环境之前,充分了解和探索这些不同的公平性定义至关重要。公平性的定义有很多种,尽管没有单一标准,但审视模型在多种定义下的表现,有助于我们更全面地识别和缓解潜在的公平性问题。

P5:【2025版】5.判别器 - 小土堆Pytorch教程 - BV1YeknYbENz 🧠

在本节课中,我们将要学习生成对抗网络(GAN)中的一个核心组件——判别器。我们将从基础的分类器概念开始,逐步理解判别器如何工作,以及它在GAN框架中扮演的角色。

判别器概述 📖

生成对抗网络由两个模型组成:判别器和生成器。本节我们将重点介绍判别器的工作原理。

判别器本质上是一种分类器。因此,我们将从复习分类器开始,了解它如何在概率层面进行建模学习。最后,我们会看到这些概念如何转化为GAN中判别器的具体任务。

分类器快速回顾 🔄

上一节我们介绍了判别器的定位,本节中我们来看看它的基础——分类器。

分类器的目标是区分不同的类别。例如,给定一张猫的图片,分类器应能判断出这是猫而不是狗。实际上,它可以学习区分猫与多个其他类别,最简单的情况可能是区分“猫”和“非猫”。

分类器的输入不限于图像。以下是分类器可以处理的几种数据类型:

  • 一段文本(例如:“它喵喵叫并玩线团”)
  • 一段猫发出各种声音的录像

神经网络分类器模型 🧠

一种常见的分类器模型是使用神经网络。

这个神经网络接收一系列输入特征,例如 x0, x1, x2, ..., xn,共n个不同的特征。

随后,网络会计算一系列非线性变换(具体细节后续会深入介绍)。

最终,网络会输出对各个类别的预测概率。例如:

  • 认为输入图片是猫的概率:45%
  • 认为输入图片是狗的概率:45%
  • 认为输入图片是鸟的概率:10%

在训练初期,模型的预测可能不正确(例如猫和狗的概率相同)。模型会随着时间学习,试图根据数据中的真实标签来改进预测。训练时会告诉模型正确答案,例如:“这是100%的猫,0%的狗,0%的鸟”。

分类器的学习过程 📈

以下是分类器学习过程的总结:

  1. 输入与标签:你有一些输入特征 X(例如:“发出咕噜声”、“喜欢玩线团”)和一套对应的标签 Y(例如:猫、狗、鸟)。
  2. 模型与参数:使用神经网络,它接收特征 X 并学习一组参数 θ(即神经网络中各节点的权重)。这些权重随着模型学习“猫”、“狗”、“鸟”的特征而不断更新。
  3. 预测与目标:模型的目标是将特征 X 映射到预测标签 ŶŶ 是模型对真实标签 Y 的估计。
  4. 损失函数:通过计算 Y(真实值)与 Ŷ(预测值)之间的差异来定义损失函数。损失函数的目标是告诉模型,其分类结果距离正确答案有多远。
  5. 参数更新:根据损失函数的梯度来更新神经网络中的参数 θ。梯度指示了参数应该朝哪个方向调整,才能使预测 ŷ 更接近真实 y
  6. 迭代:重复上述过程,直到分类器达到良好的性能。

判别模型的数学视角 ➗

让我们从数学角度稍作停留。判别模型的目标是为每个类别的概率建模。

例如,不仅仅是判断是否为猫,而是判断属于猫、乌龟、鸟、狗、鱼等类别的概率,这基于一组输入特征 X(例如一张猫的图片)。

换句话说,判别模型是对给定输入特征 X 条件下,类别 y 的条件概率 P(y|X) 进行建模。

特征 X 可以是从图像中提取的信息(例如“会喵喵叫”、“喜欢玩线团”),也可以是图像像素值本身。这是一个条件概率分布,因为模型是在看到输入特征之后才做出类别预测的。

GAN中的判别器 🎨

现在回到GAN的上下文。在GAN中,判别器是一个二分类器。

它的任务是检查输入的样本(例如图像),并判断它们属于“真实”样本还是“生成(假)”样本。

例如,对于一张生成的假《蒙娜丽莎》画像,判别器不是判断图中是猫、狗还是鸟,而是判断这张图片有多“假”。

从概率角度看,判别器建模的是:给定输入特征 X(例如假《蒙娜丽莎》的像素),该样本是“假”的概率 P(假|X)

判别器可能会判定这张假《蒙娜丽莎》有85%的概率不是真的(即 P(假|X) = 0.85)。作为简化,它会被分类为“假”。

你也可以从另一面理解,即样本为“真”的概率 P(真|X) = 1 - P(假|X) = 0.15

判别器输出的这个概率值(例如0.85),不仅仅是给样本打上“假”的标签,更重要的是,这个信息会反馈给生成器,帮助生成器改进其生成能力。

总结 🎯

本节课中我们一起学习了判别器的核心概念。

判别器是一种分类器,它学习建模在给定输入特征(如图像的RGB像素值)的条件下,样本属于“真实”或“生成(假)”类别的概率 P(类别|X)

判别器的输出是一个概率值,这个值在GAN的训练中至关重要,它驱动着生成器不断进化,以产生更逼真的样本。

🧠 P50:【2025版】50. 偏见的引入方式

在本节课中,我们将学习偏见是如何被引入机器学习模型的。我们将探讨偏见可能出现的各个阶段,并通过具体案例(如PULSE系统)来加深理解。了解这些引入途径,是构建公平、负责任AI系统的第一步。

上一节我们了解了机器学习中偏见的基本概念,本节中我们来看看偏见具体是如何进入模型的。

📊 偏见进入模型的阶段

偏见可以在模型开发和部署的多个阶段被引入。首先,你将了解偏见如何进入你的模型在任何阶段。然后,我们将更具体地看看它在PULSE系统中的表现。

1. 训练阶段引入的偏见

偏见进入模型的一种方式是在训练阶段。所以首先你应该注意你的训练数据集。

以下是训练数据可能引入偏见的几个方面:

  • 数据缺乏多样性:这可能意味着数据中没有足够的变化。例如,数据集中有色人种的图像比例过少。有时如果你只是从互联网上抓取图像(例如抓取名人的图像),这可能很难被发现。
  • 数据收集过程:你需要考虑数据是如何收集的。数据是否全部从一个地点收集?是否来自一次网络抓取?它是否由一个人或一个特定的人口群体收集?记住,无论什么被认为是所谓的“多样化”数据集,也真的非常依赖于你对公平的定义。
  • 数据标注偏见:正如你在之前的视频中所看到的,如果你使用的是标记数据,那么标签的多样性也会影响你的数据。这是因为不同的群体可能会以不同的方式标记事物。这可能会导致你的数据中产生固有的偏见。例如,如果你的标签者大多是男性,他们标记求职者的简历是否适合软件工程职位的面试。

这些只是你应该考虑的几个方面,当你在为你模型的训练数据做准备时。在更广泛的社会中存在的偏见也可能影响你模型的所有部分。

2. 评估阶段引入的偏见

另一个可以引入偏见的领域是在你评估模型期间。

以下是评估阶段可能引入偏见的例子:

  • 评估方法的制定者:是谁创造了评估方法?你可能在使用的评价方法对图像有偏见。通常被认为是所谓的“好”或“正确”的标准,在一种文化中成立,但在另一个地方可能不成立。
  • 文化差异示例:一个简单的例子是汽车是靠左行驶还是靠右行驶。如果评估数据通常来自车辆在某一侧行驶的地区,那么评估可能会反映出这一点,并对车轮在“错误”一侧的车辆进行不良评估或打分。这将完全取决于当地的驾驶法规。
  • 数据集代表性不足:另一个更具体的例子与ImageNet有关(用于训练Inception V3模型的数据集)。ImageNet中超过一半的图像来自美国和大不列颠。与世界人口密度相比,这并不真正代表大多数人的来源。这种不平衡导致系统不准确地将图像分类到类别中(例如,稻帽会被分类为头发吗?还是披肩会被分类为围巾?)。

评估计算的方式,可以强化模型中的内部偏见。这可能让你认为模型在某项任务上表现很好,但实际上它无法公平地执行该任务。

例如,研究人员从收入水平不同的家庭中提取了物品,然后评估了顶尖对象识别模型在这些物品上的准确性。结果表明,来自高收入家庭的图像在这些模型上具有更高的准确性。所以这不太好。那些开发这些模型的人可能会得出结论,他们的模型在视觉感知方面达到了人类水平,并且说“视觉感知已经解决”。但实际上,这只是对特定社会经济地位的物体的高准确性,这并不是我对伟大模型的愿景。

3. 架构与算法设计引入的偏见

所以现在偏见也可以通过模型架构和算法设计引入。

以下是相关考虑因素:

  • 开发者的多样性:优化代码的程序员的多样性如何?他们对“什么是所谓的正确或错误,以及什么是好看或不好看”的看法会影响设计。毕竟,特别是在生成模型中,评估指标本身可能就不够完善。
  • 问题与解决方案的选择:人们会更加关注如何选择各种问题在这个领域。一旦你选择了重要的问题,人们会优化那些被定义为“正确、错误、好或坏”的解决方案。这将影响研究方向的选择。
  • 损失函数的影响:例如,用于生成GAN面孔的损失函数可以影响模型认为“正确”的内容,这可能是皮肤颜色更浅或更深的区别。

这只是一些例子。偏见可以出现在任何人可能设计、工程或接触的系统中,因为每个人都有偏见,无论是否有意识。

🔍 案例分析:PULSE系统中的偏见

这里有一个偏见的例子,在一个叫做PULSE的系统中。该系统使用了一种称为StyleGAN的先进GAN,来从模糊的像素化图像中创建高分辨率图像,这是一种称为上采样的过程。

从这些像素化图像作为输入,到生成上采样图像作为输出,它做得相当好。这就是研究社区在2020年看到的最好的成果之一。你看到一个男孩被很好地上采样,然后你可以看到一个视频游戏角色被带入生活的酷应用。

然而,问题出现了:

  • 一个像素化的奥巴马(他是双种族)照片,被上采样成一个明显是白人的人。
  • 政治家亚历山德里亚·奥卡西奥-科尔特斯和演员露西·刘,也被变成他们不可辨认的自己,这些在种族上可能更被描述为所谓的“白人”。

这是因为生成的面部特征更接近StyleGAN生成器在其训练数据上学习到的“平均”面部特征。系统在一个白人视频游戏角色上表现更好,而不是这些人种,这是一个相当强的迹象,表明模型中存在偏见问题。

但很难确切地说,系统失败的地方在哪里:是StyleGAN网络本身,还是建立在StyleGAN之上的PULSE系统,或者是StyleGAN所训练的数据集。

🛠️ 应对与缓解

已经进行了研究来减轻GAN中的偏见,例如,使用对抗性损失来惩罚模型表现出偏见。

# 概念性代码:在损失函数中加入对抗性惩罚项
total_loss = task_loss + lambda * adversarial_loss

这很复杂,并且是重要的工作领域,所以我鼓励你去深入研究一下。到目前为止,这类问题开始在机器学习社区中受到更多关注。《脉冲》论文的作者已经发布了一份警告声明,关于应用他们的模型。

📝 总结

本节课中我们一起学习了偏见被引入机器学习模型的各种途径。

总之,偏见可以从多个不同的路径被引入到模型中,这是一个非常真实的问题,就像PULSE系统所展现的那样。同样,这也与之前课程中提到的COMPAS系统有关。我希望这将提醒你尝试保持警惕,警惕自己的模型中可能存在偏见,甚至找到在日常学习、应用和推进机器学习(特别是GAN)的过程中克服这种偏见的方法。

机器学习和GAN的世界,需要研究人员和实践者在他们的工作中思考这个问题。所以现在你拥有了这个重要的知识,我希望你现在能够负责任地与最先进的GAN一起工作。拥有巨大力量的,伴随着巨大的责任。所以,请善用你的力量。

P51:【2025版】51. 欢迎来到第3周 🎯

在本节课中,我们将学习当前最先进的生成对抗网络——StyleGAN。我们将分解其核心组成部分,理解它为何能在图像的真实性与多样性方面,超越其他GAN模型。

概述

你最近几周已经看到了几项关于GANs的改进。本周是关于当前最先进的GAN风格GAN。我们将分解其组成部分,理解是什么使它在定量和定性评估指标上击败了其他GANs。无论是在真实性还是多样性方面,它都做得很好。

核心特点

StyleGAN涉及过去几周熟悉的主题。包括在高分辨率下稳定的训练,生成更高质量的图像,并更好地控制图像生成,以获得更大的多样性。

一个显著的特点是,StyleGAN实际上可以改变图像的更精细的绿色方面。比如将一缕头发别在耳后,或者让角色跌倒,添加一些噪音。

核心概念解析

以下是StyleGAN实现更精细控制的关键机制之一,通常通过潜在空间(latent space)的映射和注入自适应实例归一化(AdaIN)来实现。

代码示例:AdaIN操作的核心思想

# 简化版AdaIN公式概念
def adain(content_feature, style_feature):
    # 计算内容特征的均值和方差
    content_mean, content_std = compute_mean_std(content_feature)
    # 计算风格特征的均值和方差
    style_mean, style_std = compute_mean_std(style_feature)
    # 将内容特征归一化后,按风格特征的统计量进行缩放和平移
    normalized_feature = (content_feature - content_mean) / content_std
    styled_feature = normalized_feature * style_std + style_mean
    return styled_feature

上一节我们介绍了StyleGAN的核心控制机制,本节中我们来看看其组成部分的具体优势。

主要优势列表

以下是StyleGAN相较于传统GAN的主要改进点:

  • 高分辨率训练稳定:通过渐进式增长等策略,有效生成高清图像。
  • 生成质量更高:在定量指标(如FID)和定性视觉评估上表现优异。
  • 控制能力更强:能够分离并精细控制图像的高级属性(如姿态、发型)和随机细节(如雀斑、发丝)。
  • 多样性更丰富:通过对风格向量的精细插值,可以生成连续、多样的图像变体。

本周内容预告

本周的作业将深入探讨这些不同的部分。你将有机会动手实践,观察StyleGAN如何通过调整不同的“风格”代码来改变生成图像的特定属性。

总结

本节课中我们一起学习了StyleGAN的概述与核心特点。我们了解到StyleGAN在图像生成质量、稳定性和可控性上取得了显著进步,能够精细地操控图像的各个方面。在接下来的课程中,我们将逐步拆解其架构,深入理解这些优势背后的技术原理。

🧠 P52:GAN的改进方法

在本节课中,我们将学习生成对抗网络(GAN)自诞生以来的主要改进方向。我们将了解研究人员如何通过一系列技术提升GAN的训练稳定性、模型容量和生成多样性,从而使其能够生成越来越逼真的高质量图像。

📈 GAN的演进历程

你可能在课程开始时见过这张来自GAN之父Ian Goodfellow的推文图片。它直观展示了GAN在数年间的飞速进步。

GAN生成的图像从最初几乎无法辨认的黑白人脸,发展到2018年已能输出足以令人信服的高质量真实人脸图像。这一进步始于对GAN训练稳定性的首次重大改进。

🔧 提升训练稳定性

上一节我们回顾了GAN的发展,本节中我们来看看如何提升其训练稳定性。不稳定的GAN通常意味着延长训练时间并无帮助,生成器可能陷入局部最优,导致模式崩溃(Mode Collapse),例如只重复生成数字“4”,而无法覆盖全部数据分布。

小批次统计法

一种缓解模式崩溃的思路是将批次多样性信息传递给判别器。以下是其核心思想:

  • 计算小批次标准差:通过计算一个批次内所有生成样本的标准差,可以量化该批次的变化程度。公式表示为:
    σ_batch = sqrt(mean((x_i - μ_batch)^2))
    其中,x_i 是批次中的样本,μ_batch 是批次样本的均值。
  • 低标准差预警:如果标准差很低,表明批次内样本非常相似,生成器可能正接近模式崩溃。
  • 信息传递给判别器:判别器在接收单个样本的同时,也能感知整个批次的统计特征(如标准差)。这使它能够识别模式崩溃的迹象,并据此惩罚生成器,鼓励其生成更多样化的输出。

强制Lipschitz连续性

另一种稳定训练的重要方法是强制判别器满足 1-Lipschitz连续性。这在Wasserstein GAN(WGAN)及其变体中尤为关键。

  • Wasserstein损失(W损失):其核心思想是衡量真实数据分布与生成数据分布之间的距离,能提供更有意义的梯度信号。
  • 梯度惩罚(Gradient Penalty, GP):WGAN-GP通过添加一个梯度惩罚项来强制Lipschitz约束。其损失函数包含如下项:
    L_GP = λ * E[(||∇_x̂ D(x̂)||_2 - 1)^2]
    其中,是真实样本和生成样本连线上的随机点,λ是惩罚系数。这项惩罚旨在将判别器梯度范数约束在1附近。
  • 效果:这能防止判别器学习得过快、过强,从而保持生成器梯度的有效性,稳定对抗训练过程。

谱归一化(Spectral Normalization)

谱归一化是另一种强制执行Lipschitz连续性的权重归一化技术。

  • 实现方式:它通常以“谱归一化层”的形式实现,对神经网络每一层的权重矩阵进行操作,将其谱范数(最大奇异值)归一化。
  • 类比:在某种意义上,它类似于批量归一化(BatchNorm),但归一化对象是权重而非激活值。
  • 作用:通过约束每层变换的“放大”能力,谱归一化能有效稳定GAN的训练,且通常有现成的开源实现可供使用。

模型平均与渐进增长

研究人员还通过两种高级技术来稳定训练并生成高分辨率图像,这在StyleGAN中得到了集中体现。

  • 模型权重平均(Exponential Moving Average, EMA):不是直接使用训练过程中某一时刻的生成器权重(θ_i),而是计算多个检查点权重的指数移动平均值。
    θ̄ = α * θ̄ + (1 - α) * θ_i
    其中,θ̄是平均后的权重,α是衰减率。这能平滑训练过程中的权重波动,避免使用陷入局部最优的检查点,从而得到更稳定、更高质量的生成器。

  • 渐进式增长(Progressive Growing):该方法从低分辨率(如4x4)开始训练生成器和判别器,稳定后,逐步添加新的网络层来提高分辨率(如8x8, 16x16…直至1024x1024)。这种方式让模型先学习图像的整体结构,再逐渐细化细节,极大地稳定了高分辨率图像的生成过程。

🏗️ 增大模型容量

随着训练稳定性的提升,GAN的模型容量(即网络的宽度和深度)也得到了显著扩大。

  • 深度卷积结构:例如DCGAN(深度卷积生成对抗网络),确立了卷积网络在GAN中的核心地位。
  • 硬件与数据推动:更强大的GPU硬件和高质量、高分辨率的数据集(如FFHQ,一个包含7万张1024x1024高清人脸的Flickr数据集)为训练更大、更深的模型提供了可能。
  • 架构适应:新的网络架构(如StyleGAN)专门为利用这些高分辨率数据集而设计,从而生成前所未有的逼真图像。

🌈 增强生成多样性

GAN的最终目标是模拟真实世界的丰富变化,因此生成输出的多样性至关重要。

  • 数据集的贡献:使用覆盖范围更广、更多样化的大型数据集进行训练,能直接提升生成图像的多样性。
  • 架构改进的辅助:前述的稳定技术(如小批次统计法)在防止模式崩溃的同时,也直接促进了多样性的生成。
  • 评估指标:多样性已成为评估GAN性能的一个关键标准。优秀的GAN不仅能生成高质量的图像,还应能覆盖数据分布中的各种模式。

📝 课程总结

本节课中,我们一起学习了GAN的三个主要改进方向:

  1. 训练稳定性:通过小批次统计法、强制Lipschitz连续性(如梯度惩罚、谱归一化)、模型权重平均渐进式增长等技术,有效缓解了模式崩溃,使得长时间训练大型模型成为可能。
  2. 模型容量:得益于硬件进步和高质量数据集,生成器与判别器变得更深、更宽,能够处理并生成高分辨率图像。
  3. 生成多样性:通过更丰富的数据集和稳定的训练机制,GAN生成的图像变化越来越丰富,更能反映真实数据的复杂分布。

这些改进共同推动了GAN从生成模糊图像发展到能合成以假乱真的高质量图像。在接下来的课程中,我们将在介绍StyleGAN时,再次看到这些技术的具体应用。

P53:StyleGAN概述 🎨

在本节课中,我们将要学习一种强大的生成对抗网络(GAN)变体——StyleGAN。我们将了解它的核心目标、关键概念“风格”的含义,以及其独特的架构组成部分。通过本教程,你将理解StyleGAN为何能在生成高分辨率、高保真度图像方面取得突破性进展。


概述

在前一个视频中,我们了解了GANs这些年的发展历程。本视频将介绍一种相对较新的架构——StyleGAN。它被认为是当前生成模型领域的前沿,特别是在生成极其逼真人脸方面的一个转折点。

我们将从StyleGAN的主要目标开始,解释它如何体现GAN的改进。然后,我们会探讨“风格”在StyleGAN中的含义。最后,我们将介绍其架构的各个组成部分。


StyleGAN的主要目标 🎯

StyleGAN的首要目标是生成高质量、高分辨率的图像,这些图像足以“愚弄”一个随意的观察者。

第二个目标是增加输出图像的多样性。回想早期视频中可爱小狗的例子,理想的输出应该能从金毛寻回犬变化到金毛混血犬,再到法国斗牛犬,而不是只生成一系列背景相同、略有不同的金毛寻回犬。

StyleGAN的另一个亮点是增强了对图像特征的控制能力。这包括添加特征(如帽子或太阳镜),或者混合两种不同生成图像的风格。例如,你可以看到布拉德·皮特和安吉丽娜·朱莉的风格混合后会产生什么效果。

在高分辨率下达到欺骗未经训练眼睛的精确度,是一项巨大的成就,直到最近才变得更容易实现。


图像质量的演进

这主要归功于模型容量的提升、更高分辨率数据集的可用性,以及GAN架构本身解决了生成高分辨率图像的挑战。

以下是早期GAN(2014年)生成的面孔,它们大多看起来像糟糕的素描,模糊且不真实。

现在,请看这张由更近期的StyleGAN生成的高分辨率人脸图像。如果没有上下文,你可能不会猜到这不是一个真实的人。

显然,StyleGAN实现了更高的真实感。一个有趣的方面是,StyleGAN尝试了Wasserstein损失(W Loss)和梯度惩罚(GP Loss)——这些是你在第三周学到的——以及第一周学到的原始GAN损失。研究发现它们在不同的高分辨率人脸数据集上各有优势。实际上,两者都可能有效,关键在于尝试。


对图像特征的控制

最后,StyleGAN还旨在增强你对图像特征的控制力。

这种控制可以是将一张图像的风格混合到另一张图像中。如下图所示,中间的脸是由下方和右侧的脸混合而成。你可以看到发色和风格来自右侧图片,而各种面部特征来自下方的脸。

同样,在右下角,那个女人是上方女人和左侧男孩风格的混合。

控制也意味着可以添加配饰,如眼镜。这是通过解纠缠的潜空间来实现的,你将在不久的将来了解更多细节。如下图所示,所有这些生成的人物都戴上了太阳镜。


“风格”在StyleGAN中的含义

在图像生成的上下文中,“风格”几乎意味着图像的任何变化。你可以将这些变化看作是代表图像不同层次的外观和感觉。

这些不同层次可能包括:

  • 更大、更粗略的风格:如面部形状或面部结构。
  • 更精细、更详细的风格:如颜色、头发纹理或某些头发的位置。

StyleGAN有趣的一点是,它由多个“块”组成。早期的块大致对应更粗略的特征(如面部结构或姿势),而接近输出的层则控制更精细、更详细的风格(如发色或眉毛形状)。

你可以想象,一个生成的女人图像,可以基于上方女人的粗略风格、中间女人的中等风格和下方女人的精细颗粒风格以某种方式组合或改变。


StyleGAN与传统GAN的架构差异

现在你对“风格”的概念更熟悉了,让我们看看StyleGAN生成器与你可能更熟悉的传统GAN生成器之间的差异。

传统GAN生成器中,你将一个噪声向量 z 直接输入生成器,生成器然后输出一张图像。

# 传统GAN生成流程示意
z = random_noise_vector()
generated_image = Generator(z)

StyleGAN中,噪声向量的处理方式有所不同。

  1. 噪声向量 z 不直接输入生成器,而是先通过一个映射网络(Mapping Network),得到一个中间的噪声向量 w
  2. 这个 w 向量随后被多次注入到StyleGAN生成器中,用于生成图像。
  3. 此外,还有额外的随机噪声被传递到生成器的各层,以添加图像上的随机微小变异(例如,移动一缕头发的方式)。

# StyleGAN生成流程示意
z = random_noise_vector()
w = MappingNetwork(z)  # 映射网络
generated_image = StyleGAN_Generator(w, random_noises)  # 注入w和随机噪声

这种随机噪声没有可学习参数,主要是无关的高斯噪声,用于轻微扰动卷积层各处的值。

然而,映射网络非常重要,它包含可学习的参数。反向传播会从判别器回来,通过生成器,再通过这个映射网络进行学习。

值得注意的是,w 并不是简单地输入到网络中。相反,StyleGAN生成器从 w 中提取“样式”,然后将这个中间噪声值添加到生成器中的多个点。在生成器的早期阶段,w 告知更粗略的样式(如一般的面部形状);在后面的层中注入的 w 则控制更精细的样式(如发色)。

将这种中间噪声注入所有样式层,是通过一种称为AdaIN(自适应实例归一化)的操作来实现的。这是一种类似于批归一化的归一化操作,但在归一化后,它会基于传入的 w 来应用特定的样式(即调整图像的统计特征,如均值和方差)。


渐进式增长

StyleGAN第三个也是最后一个重要组成部分是渐进式增长

这是指在整个训练过程中,逐步提高生成器所生成图像的分辨率。渐进式增长的概念起源于Progressive GANs,并非StyleGAN独有,但它是StyleGAN的前身。作者们注意到它有助于训练高分辨率图像。

在训练过程中,生成器和判别器从生成低分辨率的小图像开始(例如,一个模糊但大致有面部轮廓的图像)。当模型在这个分辨率上稳定后,它们可以扩展到两倍的高度(例如,从4x4到8x8)。现在任务变得稍难一些,需要生成不那么模糊、更像脸部的图像。这个过程会一直持续,直到达到所需的图像分辨率(如1024x1024)。

这种“加倍”会在训练过程中的预定时间发生,但不能太突然,必须是渐进的,以便让生成器更容易适应生成更大的图像。

如果你现在感到困惑,完全不用担心,稍后会在课程中详细解释。主要的要点是:如果你想要增长(分辨率),你必须慢慢来。


总结

本节课中,我们一起学习了StyleGAN及其一些惊人的成就,包括:

  • 生成高分辨率图像时更高的保真度。
  • 增加了生成结果的多样性。
  • 对图像特征(如发色和配饰)有了更多的控制。

你了解了在图像生成中“风格”的含义,即图像的一般纹理或外观和感觉,它取决于在生成器中的位置,从大的核心样式(如面部形状)到更精细的样式(如发色)。

最后,你认识了StyleGAN的架构,并看到了它的主要组成部分:

  1. 噪声映射网络:将初始噪声 z 映射到中间潜码 w
  2. 自适应实例归一化:将 w 代表的风格注入到生成器的各层。
  3. 渐进式增长:逐步提高生成图像的分辨率以实现稳定训练。

这些组件让StyleGAN与更传统的GAN区分开来。这只是一个高层次的介绍,在后续课程中,你将深入探讨这些组件的细节。

P54:渐进增长 🚀

在本节课中,我们将要学习渐进增长,这是StyleGAN中的一个核心组成部分。我们将解释其背后的直觉与动机,并深入探讨其实现方式。


概述

渐进增长旨在使生成器更容易生成高分辨率图像。其核心思想是从低分辨率图像开始训练,逐步过渡到高分辨率图像。这种方法让模型从更简单的任务入手,逐步学习复杂的细节。


渐进增长的动机与直觉

上一节我们介绍了渐进增长的目标,本节中我们来看看其具体动机。

首先,在StyleGAN中,渐进增长让生成器从生成非常模糊的低分辨率图像开始。例如,初始阶段可能只生成4x4像素的图像。这是一个相对简单的任务。

为了使判别器的任务也相匹配,真实的训练图像也会被下采样到相同的低分辨率(如4x4)。这样,判别器在初始阶段也只需评估低分辨率图像的真伪。


渐进增长的过程

理解了动机后,我们来看看渐进增长是如何一步步实现的。

以下是渐进增长的基本步骤:

  1. 初始阶段:生成器生成4x4图像,判别器评估下采样至4x4的真实图像。
  2. 尺寸翻倍:经过预定的训练间隔后,生成器和判别器的目标分辨率翻倍,例如从4x4变为8x8。
  3. 添加新层:生成器会添加新的上采样和卷积层来生成更高分辨率的图像。判别器也会添加新的卷积层来处理更高分辨率的输入。
  4. 重复过程:上述过程不断重复,分辨率持续翻倍(如16x16, 32x32...),直到达到目标的高分辨率(如1024x1024)。

在这个过程中,生成器逐步学习生成更清晰、细节更丰富的图像,而判别器也同步提升其鉴别能力。


平滑过渡:Alpha混合

然而,渐进增长并非简单地直接切换分辨率。为了实现从旧分辨率到新分辨率的平滑过渡,StyleGAN引入了一个关键的alpha参数。

当需要将分辨率从4x4提升到8x8时,并非立即让新添加的网络层完全生成图像。而是分两步走:

  1. 首先,将旧的4x4输出通过一个固定的上采样方法(如最近邻插值)直接放大到8x8。这称为上采样图像
  2. 同时,将旧的4x4输出输入到新添加的可学习网络层中,让其尝试生成8x8图像。这称为生成图像

最终的8x8输出是这两部分的加权和,由alpha参数控制:

# 伪代码表示最终的输出混合
最终输出 = (1 - alpha) * 上采样图像 + alpha * 生成图像

以下是alpha参数的变化过程:

  • 初始 (alpha = 0):完全使用上采样图像,新网络层不发挥作用。
  • 过渡期 (0 < alpha < 1):随着训练进行,alpha从0逐渐线性增加到1。模型越来越依赖新网络层学习到的特征,而非简单的像素放大。
  • 最终 (alpha = 1):完全使用新网络层生成的图像,上采样部分被弃用。此时新层已完全融入网络,可以独立生成该分辨率的图像。

这种平滑过渡避免了分辨率突变带来的训练不稳定,让网络能够平稳地学习新尺度下的特征。


判别器的对应处理

生成器的变化理解了,判别器也需要进行对应的调整以处理逐渐变大的图像。

判别器进行的是相反方向的操作。当输入图像分辨率从4x4增加到8x8时:

  1. 一方面,将高分辨率(8x8)输入直接下采样到低分辨率(4x4),然后送入原有的判别器网络。
  2. 另一方面,将高分辨率输入送入新添加的判别器层进行处理,再下采样并与原有网络流合并。

判别器同样使用与生成器同步的alpha参数来混合这两个处理路径的结果,实现平滑过渡。


在StyleGAN中的结构

在StyleGAN中,渐进增长是通过一系列结构相似的增长块来实现的。

每个增长块通常包含:

  • 对于生成器:上采样层 + 一个或多个卷积层。
  • 对于判别器:一个或多个卷积层 + 下采样层。

这些块像搭积木一样堆叠,每个块负责将图像分辨率提高一倍,并通过alpha混合机制平滑地激活。


总结

本节课中我们一起学习了StyleGAN中的渐进增长技术。

我们了解到:

  1. 核心目的是稳定高分辨率图像生成的训练过程。
  2. 实现方式是让模型从低分辨率开始,在预定的时间间隔将分辨率翻倍。
  3. 关键技巧是使用alpha参数进行平滑过渡,混合“旧方法放大”和“新网络生成”的结果,避免训练突变。
  4. 该技术同时应用于生成器判别器,确保两者能力同步增长。

总之,渐进增长通过分阶段、平滑过渡的策略,显著提升了GAN模型学习生成复杂高分辨率图像的能力和稳定性。

P55:噪声映射网络 🧠

在本节课中,我们将要学习StyleGAN中一个独特的组成部分——噪声映射网络。我们将了解它的结构、作用原理以及它在整个生成器架构中的位置。

概述

噪声映射网络是StyleGAN的关键组件之一,它负责将输入的噪声向量 z 映射为一个中间噪声向量 w。这一设计旨在实现对生成图像风格更精细、更解耦的控制。

网络结构

上一节我们介绍了噪声映射网络的基本概念,本节中我们来看看它的具体结构。

噪声映射网络实际上是一个由八个全连接层组成的多层感知机(MLP)。它在各层之间使用了激活函数。

以下是其核心结构描述:

  • 它接收一个从正态分布中采样得到的、维度为512的噪声向量 z
  • 经过网络映射后,输出一个维度同样为512的中间噪声向量 w
  • 网络的作用是改变 z 的值,将其映射到另一个空间(w 空间)。

其过程可以用伪代码表示:

# 输入:噪声向量 z, shape: (batch_size, 512)
# 输出:中间向量 w, shape: (batch_size, 512)
w = MLP(z)  # MLP 包含8个全连接层

设计动机

了解了网络结构后,我们自然会问:为什么需要这个额外的映射步骤?本节我们来探讨其设计动机。

在原始的GAN中,直接从 z 空间采样噪声向量存在“纠缠”问题。这意味着改变 z 向量的某个值,可能会同时影响生成图像中的多个特征(例如,改变眼睛的同时也改变了胡子),这不利于进行精细的、特征级别的控制。

z 空间通常服从简单的正态分布,而真实图像数据中各种特征(如是否有眼镜、胡须的颜色等)的联合概率分布非常复杂。让 z 空间直接建模这种复杂分布是困难的,网络可能会学习到一种复杂的、难以理解的纠缠映射来勉强完成任务。

引入噪声映射网络后,w 空间为网络提供了一个中间空间。这个空间可以更好地匹配真实数据的特征密度分布,从而学习到更线性、更易于控制的变异因素。这有助于减少不同风格特征之间的紧密相关性,最终实现更解耦的特征控制。

需要明确的是,w 空间并非完全解耦,但它比原始的 z 空间纠缠程度更低。

在生成器中的位置

我们已经知道了噪声映射网络是什么以及为什么需要它,现在来看看它在整个StyleGAN生成器架构中扮演什么角色。

在采用渐进式增长的StyleGAN生成器中,生成器的输入并非直接是噪声向量 z 或映射后的 w。相反,网络以一个固定的常量张量开始,这个张量对于所有生成的图像都是相同的(例如,一个形状为 [4, 4, 512] 的常量)。

那么,w 向量用在哪里呢?它被注入到生成器的每一个上采样块中。具体来说,在生成器的多个中间层(即各个上采样块),w 向量会被多次引入,以影响该层级所控制的特征(如粗糙特征、中等特征、精细特征等)。这与传统GAN一开始就输入噪声的做法完全不同。

这种设计使得不同层级的特征可以受到同一组风格代码 w 的不同部分或不同方式的影响,从而实现了对生成图像风格的多尺度、精细化控制。

总结

本节课中我们一起学习了噪声映射网络。

  • 它是一个多层感知机(MLP),将噪声向量 z 映射为中间向量 w
  • 其核心目的是为了获得一个更解耦的表示空间(w 空间),以实现对生成图像特征的精细控制。
  • 在StyleGAN生成器中,常量张量作为起始输入,而映射得到的 w 向量则被多次注入到网络的各个中间层,以控制不同尺度的风格特征。

在下一节课中,我们将具体学习 w 向量是如何被精确地加入到这些生成器块中的。

P56:自适应实例归一化 (AdaIN) 🎨

在本节课中,我们将详细学习自适应实例归一化(AdaIN)。这是一种将中间噪声向量(风格信息)整合到生成网络中的关键技术。我们将从实例归一化的概念讲起,并与批量归一化进行对比,最后深入理解“自适应”部分的原理及其在生成对抗网络(GAN)中的应用。


实例归一化与批量归一化

上一节我们介绍了AdaIN的整体作用,本节中我们来看看它的核心组成部分——实例归一化。

首先,实例归一化是AdaIN的第一步。它从卷积层中提取输出特征图 x,并将其归一化为零均值和单位标准差。这个过程通过计算这些值的均值和标准差来实现,使数据围绕零中心分布,标准差为一。

这与你可能更熟悉的批量归一化有所不同。以下是两者的关键区别:

  • 批量归一化 (Batch Normalization):计算均值和标准差时,会考虑一个批次(batch)中所有样本的同一通道数据。公式可表示为对批次维度 N 和空间维度 H, W 进行统计。
    # 伪代码示意:沿批次(N)和空间(H, W)维度计算均值和方差
    mean = mean(x, dim=[0, 2, 3])  # 对N, H, W维度求平均
    var = var(x, dim=[0, 2, 3])    # 对N, H, W维度求方差
    
  • 实例归一化 (Instance Normalization):只针对单个样本(实例)的单个通道计算均值和标准差。它不依赖批次内其他样本的信息。公式可表示为仅对空间维度 H, W 进行统计。
    # 伪代码示意:仅沿空间(H, W)维度计算每个样本每个通道的均值和方差
    mean = mean(x, dim=[2, 3])  # 对H, W维度求平均
    var = var(x, dim=[2, 3])    # 对H, W维度求方差
    

在风格迁移或图像生成的上下文中,实例归一化比批量归一化更合理,因为它处理的是每个独立的生成样本,而非整个批次的统计特性。


“自适应”部分:注入风格信息

了解了实例归一化如何工作后,我们来看看AdaIN中“自适应”的含义。这部分负责将风格信息从中间噪声向量 w 注入网络。

首先,原始的噪声向量 z 通过一个映射网络(一个多层感知机MLP)被转换为中间噪声向量 w。这个 w 向量承载了控制生成图像风格的潜在信息。

w 向量并不会直接输入到AdaIN层。相反,它通过两个独立的全连接层(Affine Transformation),学习生成两个参数:

  • y_s:代表缩放(scale)参数。
  • y_b:代表偏置(bias)或偏移参数。

这些参数 y_sy_b 会被送入每一个AdaIN层。


AdaIN的完整流程

现在,我们将实例归一化和自适应部分结合起来,看看AdaIN的完整工作流程。

  1. 实例归一化:对卷积层的输出特征图 x 进行实例归一化,消除其原有的风格信息,得到归一化后的特征 x_norm。公式为:
    x_norm = (x - μ(x)) / σ(x)
    其中 μ(x)σ(x)x 沿空间维度计算的均值和标准差。

  1. 自适应仿射变换:利用从 w 向量学习得到的缩放参数 y_s 和偏置参数 y_b,对归一化后的特征进行重新缩放和偏移。这是应用新风格的关键步骤。公式为:
    AdaIN(x, w) = y_s(w) * x_norm + y_b(w)

这个过程可以理解为:先通过实例归一化“剥离”内容中的原有风格,然后根据 w 向量提供的风格信息,通过 y_sy_b 将特征“重塑”到新的分布(即目标风格)中。这就像保持一幅画的内容(如一张脸),但将其笔触和色彩风格从“毕加索式”调整为“莫奈式”。


AdaIN在生成器中的位置与作用

理解了AdaIN的原理后,我们来看看它在StyleGAN这类网络中的具体应用。

生成器由多个块(Block)组成。早期的块负责学习图像的粗粒度特征(如轮廓、姿态),而后期的块负责学习细粒度细节(如发丝、纹理)。

AdaIN被用于生成器的每一个卷积层之后。这意味着风格信息 w 被持续地注入到生成过程的各个阶段:

  • 注入到早期块的AdaIN会影响图像的粗粒度风格(如整体构图、画风)。
  • 注入到后期块的AdaIN会影响图像的细粒度风格(如纹理细节、局部色彩)。

由于每个块后都进行AdaIN操作,当前块输出的特征会被归一化并施加风格,然后作为输入进入下一个块。下一个块的AdaIN又会对其重新进行归一化和风格化。这种设计允许对图像生成进行分层级的、精细的风格控制。你甚至可以在不同块中注入不同的 w 向量,以实现风格混合,这将在后续课程中探讨。


总结

本节课中我们一起学习了自适应实例归一化(AdaIN)。

  • 核心作用:AdaIN是将中间噪声向量 w 中的风格信息传递到生成图像的核心机制。
  • 两个步骤
    1. 实例归一化:对每个样本的每个通道独立进行归一化(x_norm = (x - μ) / σ),剥离原有风格,提取内容信息。
    2. 自适应变换:利用由 w 学习得到的参数(y_s, y_b)对归一化后的特征进行仿射变换(y_s * x_norm + y_b),施加新的目标风格。
  • 网络中的应用:在StyleGAN等网络中,AdaIN被插入到生成器的每个卷积层后,使得风格信息能够分层级地、精细地控制从粗到细的整个图像生成过程。

通过AdaIN,生成器能够将内容(由网络结构决定)与风格(由噪声向量 w 决定)有效地分离开并进行灵活组合,从而生成高质量且风格多样的图像。

P57:风格与随机变化 🎨🎲

在本节课中,我们将学习两种为StyleGAN生成图像增加多样性和控制力的关键技术:风格混合随机噪声注入。前者通过混合不同的中间噪声向量来控制图像的粗略与精细风格;后者则通过向网络中添加额外的噪声来为图像引入微小的随机变化。


风格混合:融合不同风格 🧬

上一节我们介绍了StyleGAN的基本概念,本节中我们来看看如何通过混合不同的风格来创造新的图像。

风格混合的核心思想是,在生成过程中,不必在整个网络中始终使用同一个中间噪声向量 w。我们可以将网络的不同部分与来自不同初始噪声 zw 向量关联起来。

例如,你可以采样一个噪声 z1,通过映射网络得到 w1,并将其注入到网络的前半部分。接着,采样另一个噪声 z2,得到 w2,并将其注入到网络的后半部分。在 w1w2 之间切换的时机可以任意设定,不一定是网络的正中间。

公式描述

  • 前半部分风格:w1 = MappingNetwork(z1)
  • 后半部分风格:w2 = MappingNetwork(z2)
  • 最终图像:Image = Generator(w1, w2)

切换点越靠后,w2 所控制的特性就越精细(如发丝细节、瞳孔颜色)。反之,w1 则控制更粗略的特性(如脸型、性别)。这种机制不仅增加了输出图像的多样性,也让我们能更精细地控制生成结果。

以下是一个风格混合的示例:

  • 第一列图像由不同的 w1 生成,决定了粗略风格(如脸型)。
  • 第一行图像由不同的 w2 生成,决定了精细风格(如细节纹理)。
  • 中间区域的图像则是 w1w2 的混合结果。例如,某张图像可能继承了左侧图像的粗略风格和上方图像的精细风格,从而产生兼具两者特点的新面孔。

随机噪声:增加细节变化 🌪️

除了混合不同的风格向量,我们还可以通过直接向生成器网络中添加随机噪声来引入变化。这种方法不依赖于混合两个不同的 w 向量,而是对单一生成过程进行“微调”。

具体操作是在每个卷积层的输出特征图进入“自适应实例归一化”(AdaIN)模块之前,为其添加一个从标准正态分布中采样的随机噪声张量。

代码描述

# 假设 x 是卷积层的输出特征图
batch_size, channels, height, width = x.shape
# 采样与特征图形状相同的随机噪声
random_noise = torch.randn(batch_size, 1, height, width).to(x.device)
# 将噪声与特征图相加(通常还会乘以一个可学习的缩放因子 lambda)
x = x + lambda * random_noise
# 然后将 x 送入后续的 AdaIN 和激活函数

这个可学习的缩放因子 lambda 控制了噪声对最终图像的影响程度。lambda 值大,则噪声影响大;值小,则影响微弱。

注入噪声的时机决定了变化的“粒度”:

  • 网络早期(低分辨率层)注入噪声,会产生粗略的变化,例如改变发型的大体卷曲度或眉毛的浓淡。
  • 网络后期(高分辨率层)注入噪声,会产生精细的变化,例如调整发丝的走向、皮肤毛孔的细节或睫毛的疏密。

以下是一个随机噪声效果的示例:

可以看到,仅通过添加微小的随机噪声,就能使生成人物的头发产生自然的变化,一缕一缕的发丝细节得以显现。


总结 📝

本节课中我们一起学习了两种提升StyleGAN生成能力的技术:

  1. 风格混合:通过在网络的不同阶段注入来自不同噪声源 z 的中间向量 w,可以融合不同图像的粗略与精细风格,从而创造出兼具两者特征的新图像,并极大地增加了输出的多样性。
  2. 随机噪声注入:通过向生成器网络的卷积层输出中添加可缩放的随机噪声,可以直接为图像引入随机性变化。噪声添加的时机决定了变化的性质——早期添加影响整体结构(粗略变化),后期添加影响细节纹理(精细变化)。

这两种技术都遵循神经网络的一个普遍规律:网络前部学习抽象、全局的特征,后部学习具体、局部的特征。灵活运用风格混合与噪声注入,能够让我们更精准地控制生成对抗网络所创造的内容。

P58:【2025版】58. 把各部分结合起来 🧩 - 小土堆Pytorch教程

在本节课中,我们将把之前学到的所有关于StyleGAN的核心组件整合在一起,形成一个完整的理解。我们将回顾每个部分的作用,并了解它们是如何协同工作以生成高质量图像的。


概述

StyleGAN是一个强大的生成对抗网络,它通过一系列创新组件来提升生成图像的质量和多样性。本节课我们将系统性地回顾这些组件,并理解它们在整个架构中的位置与功能。


回顾核心组件

上一节我们介绍了StyleGAN的各个独立概念,本节中我们来看看如何将它们组装成一个完整的生成器。

1. 渐进式增长 (Progressive Growing)

首先,你学习了渐进式增长。它本质上是让模型随时间逐步生成输出,从低分辨率的小图像开始,逐步增加到高分辨率的大图像。这种方法有助于稳定训练过程,并让生成器逐步构建更复杂的特征。

2. 映射网络 (Mapping Network)

然后,我们学习了映射网络。它的作用是将从正态分布中采样的潜在编码 z,通过一个多层感知机进行处理。这个网络通常包含八个全连接层,层间使用激活函数(如Leaky ReLU),最终输出一个中间的风格向量 w

公式表示w = MappingNetwork(z)

3. 风格注入 (Style Injection)

接着,你将这个中间风格向量 w 输入到生成器的每个主要块中(除了最开始的输入层)。这种设计允许在网络的不同深度控制不同层级的风格特征。

4. 自适应实例归一化 (AdaIN)

你学习了自适应实例归一化。AdaIN利用风格向量 w 的统计信息(均值和标准差),在网络中的各个点对特征图进行归一化和风格化。在网络早期的块中,它影响更宏观、整体的样式;在网络后期的块中,它则控制更精细的细节。

代码描述

# 假设 feat 是特征图,style 是来自 w 的缩放和偏置参数
def AdaIN(feat, style_scale, style_bias):
    mean = feat.mean(dim=(2, 3), keepdim=True)
    std = feat.std(dim=(2, 3), keepdim=True) + 1e-8
    normalized = (feat - mean) / std
    return normalized * style_scale + style_bias

5. 风格混合 (Style Mixing)

你还学习了风格混合。这项技术通过为不同的网络区块采样不同的风格向量 w 来实现。例如,可以在网络的前半部分使用 w1,在后半部分使用 w2。这样,最终的生成图像将是两种不同风格特征的混合体。

6. 随机噪声 (Stochastic Noise)

最后,是随机噪声的注入。这些噪声会影响图像中微小、随机的细节变化,例如一缕头发的精确位置、卷曲程度或皮肤纹理。噪声被添加到网络的多个点,并且每个注入点都有一个可学习的缩放参数,用于控制噪声对该层级特征的影响强度。

核心作用:增加生成图像的细节多样性和真实感。


组件整合与总结

恭喜你学习到这里!以上就是构成StyleGAN的主要组成部分。

以下是这些组件的一个简要总结列表:

  • 渐进式增长:稳定训练,逐步提升分辨率。
  • 映射网络:将潜在编码 z 转换为解耦的风格向量 w
  • 风格注入:将 w 向量送入生成器的各个层级。
  • 自适应实例归一化 (AdaIN):利用 w 的统计信息对特征图进行风格化。
  • 风格混合:混合不同风格向量以创造新的特征组合。
  • 随机噪声:为图像添加细微的随机细节。

本节课中,我们一起学习了如何将StyleGAN的各个核心组件——渐进式增长、映射网络、AdaIN、风格混合和随机噪声——整合到一个统一的框架中。理解每个部分如何贡献于最终图像的质量和多样性,是掌握StyleGAN设计精髓的关键。

P59课程:课程2总结与展望 🎯

在本节课中,我们将对已完成的课程二进行总结,并展望课程三即将学习的内容。课程二的核心是构建一个最先进的生成对抗网络及其组成部分。接下来,我们将深入了解生成对抗网络的实际应用场景。


课程三内容预览 🚀

上一节我们总结了课程二关于构建生成对抗网络的知识。本节中,我们来看看在课程三中,你将如何应用这些知识。

课程三将涵盖生成对抗网络的三个主要应用方向。

以下是具体的应用方向介绍:

  • 数据增强:你将学习如何使用生成对抗网络生成的数据来增强数据集,以辅助下游模型的训练。例如,下游模型可以是用于分类不同人脸的分类器,而你的生成对抗网络可以生成大量的人脸数据供其使用。
  • 隐私保护:你将了解如何利用生成对抗网络生成的数据来帮助保护隐私,同时保持任务所需的准确性。例如,如果你拥有敏感的医疗记录(如人们的生日或诊断信息),你可能不希望保险公司直接获取这些信息。你可以生成合成数据,这些数据更便于分享或用于模型训练,从而避免他人通过逆向工程模型来利用原始敏感记录。
  • 风格迁移:你将有机会深入学习生成对抗网络如何用于图像风格迁移。这建立在你有条件生成的知识基础上,但条件不再是一个简单的类别向量,而是一整张图像的内容。例如,根据一张马的图像生成斑马,根据橙子生成苹果,或者根据卫星图像生成地图。


总结 📝

本节课中,我们一起回顾了课程二关于构建生成对抗网络的成果,并预览了课程三将深入探索的三大应用领域:数据增强、隐私保护和风格迁移。所有这些应用都令人兴奋,让我们直接开始课程三的学习吧。

P6:【2025版】6.生成器 - 小土堆Pytorch教程 - BV1YeknYbENz

🧠 概述

在本节课中,我们将要学习生成对抗网络(GAN)中的核心组件——生成器。我们将了解它的基本概念、工作原理、训练目标以及它在概率建模中的作用。


🎯 生成器的核心角色

生成器就像一个心脏,在一个模型中扮演着核心角色。它是一个用于生成示例的模型。

你应该专注于帮助它达到高性能。

在训练过程的最后,在这个视频中,我将重新审视生成器的作用。你将看到它如何提高自己的性能,然后我会向你展示它在概率建模方面的工作。


🐱 生成器的目标与输入

生成器的最终目标是能够生成一类示例。如果你训练它是从猫这一类,那么生成器会进行一些计算并输出一个看起来真实的猫的表示。

理想情况下,生成器每次运行时不会输出一样的猫。为了确保它能够每次输出不同的示例,你将输入不同的一系列随机值,也称为噪声向量。所以这里这个噪声向量实际上是一组值,这些不同阴影的单元格只是不同值。

你可以认为这是一、二、五、一,点五、五、五、二。然后这些噪声向量作为输入被送入,有时与猫这一类y一起输入到生成器的神经网络中。这意味着这些特征x0,x1,x2,一直到xn,包括类别以及噪声向量中的数字。

然后,在这个神经网络中生成器,会从这些输入计算一系列非线性结果。

并返回一个看起来像一只可爱的棕色和白色猫的表示。所以这里,而不是不同的类别,它的输出实际上是一张图片。你可以想象这张图片有三百万个像素,你可以想象这些是三百万个最后的节点,它们并不表示类别,而是每个像素值。

在另一个运行中它可以生成这一只无毛猫。在最后一次运行中,这一只savannah猫。这些都是用不同的噪声向量。让我们首先考虑概念上生成器如何随着时间的推移而改进。


🔄 生成器的训练与改进

你有一个噪声向量或那些随机输入值,我将其表示为希腊字母si,并将它输入到一个生成器,表示为一个神经网络,以生成一个猫的图像特征集或一个试图生成猫的图像。例如,生成器可能会生成这个图像。

x hat被送到鉴别器,这决定了它根据对其的检查认为它是多么真实和多么虚假,以及之后判别器对它的看法。这是这里表示是判别器预测的y hat,代表它是判别器的预测。你可以计算一个成本函数。

基本上看生成器产生的例子被判别器认为是真实的程度。因为生成器希望这看起来尽可能真实,所以基本上生成器希望y hat尽可能接近1,即真实,而判别器试图让这为零,即虚假。

它使用这两个之间的差异来更新生成器的参数,然后让它随着时间的推移改善并知道移动其参数的方向,以生成看起来更真实并能愚弄判别器的东西。所以当你得到一个看起来不错的生成器时,你可以保存生成器的参数theta。

这通常意味着冻结那些theta值并保存到某个地方,然后你可以加载它回来,然后从保存的生成器中采样。采样基本上意味着你有这些随机噪声向量,当你将这些输入到保存的生成器中时,它可以生成各种各样的例子。

所以这个保存的生成器没有训练过猫,我希望没有,因为正在生成狗。请注意你可以继续生成新的噪声向量,将其通过此保存的生成器,然后采样更多狗图像,在这种情况下。所以在概率的世界里。


📊 生成器的概率建模

生成器模型一个例子的概率,例如猫,在前一个例子中,实际上是一只狗,当然你也可以做一个乌龟,鸟或鱼,请随意。更一般地,生成器试图模型,给定猫这种类别y的猫的特征x的概率。

例如舔它的爪子或可爱的胡须或各种毛皮。所以这是条件概率x给定类别y。然而,因为我们目前只有一个类别,例如只生成猫,那么y总是相同的,所以你实际上不需要这里。所以你有p x你正在模型。当然,如果你希望你的生成器学习所有不同类型的类别并且你关心类别,那么你确实需要放那个类别。当然,如果你希望你的生成器学习所有不同类型的类别并且你关心类别,那么你确实需要放那个类别,并在课程一中稍后看到更多。

所以现在你有p x遍及世界上所有的猫类型,生成器将建模特征x的概率,没有其他附加条件。这是因为类别y总是为猫。

所以对所有概率x都是隐含的。在这种情况下,它将尝试近似真实分布的猫。最常见的猫品种实际上会有更多的生成机会,因为它们在数据集中出现得更频繁。而某些特征,如尖耳朵,会更常见,因为大多数猫都有。

然后更稀有的品种将更有可能较少被采样。

所以这些线条只是代表一个三维的概率分布,猫的分布。所以,猫携带的最常见的类型的特征,将显示并在这里采样。如果你认为这是三维表示,它将向你伸出,然后稀有品种或稀有外观的猫将在边缘。

这意味着最常见的猫品种将有更多的生成机会,而较少常见的品种,如斯芬克斯,则会很少生成。你将在未来的视频中看到,如何控制采样过程并得到你想要的。但现在,生成器的工作是仅仅模仿自然界中的猫。


✅ 总结

本节课中我们一起学习了生成器。

总结一下,生成器产生看起来真实的假数据。它学习模仿你数据的类别的特征x的分布。为了每次产生不同的输出,它以随机特征作为输入。

这周的作业中,你将构建一个生成器对抗网络来生成数字的图像。它具有相同的设置。你只需给它随机噪音,它可以产生所有这些不同的手写数字。这很酷,因为手写不总是完美,它每次看起来都不同。它将能够建模并生成这个数据集中的各种5和8,以及所有不同的手写数字。

课程3:图像到图像转换与数据增强 🎨

在本节课中,我们将学习图像到图像转换框架及其在数据增强和人工数据合成中的应用。我们将探讨Pix2Pix等算法,并了解如何将这些技术用于解决小数据问题,例如超分辨率、图像修复和概念设计。


概述

在前两节课程中,我们学习了如何构建复杂的生成对抗网络,包括风格GAN这类高度可控的模型。本节课程是最后一节,我们将进一步探索更复杂的图像生成能力。

同时,我们将学习如何将这些方法应用于数据增强和人工数据合成,特别是在小数据问题上。例如,我们将学习Pix2Pix算法,并更广泛地了解图像到图像转换框架。这个框架能实现超分辨率等功能。

输入一张低分辨率图像,该框架能将其转换为视觉效果良好的高分辨率图像。此外,该框架还能实现其他功能,例如,处理一张被树木部分遮挡视野的图像,擦除树木,并让生成对抗网络填充缺失的视野部分。

因此,你可以实现类似Photoshop的效果,例如移除遮挡视野的树木。图像到图像转换也允许你处理手绘图片。例如,你可以画一张简单的卡通猫,然后使用GAN将其转换为一张逼真的猫的图像。

更实际的应用是,如果你想设计一双新鞋,你可以手动绘制鞋子的草图,然后使用GAN将其转换为一个看起来真实的设计。如今,许多这类想法已被应用,并且越来越多地用于解决小数据问题的数据增强。

正如你所听到的,图像到图像转换框架可以应用于许多领域。实际上,你还可以将其扩展到其他领域,这正是它成为一个重要框架的原因。

例如,你可以将其扩展到图像到视频的生成。你可以输入一张《蒙娜丽莎》的图像,然后结合你自己的面部动作数据,构建一个模型来生成你通过蒙娜丽莎形象说话的视频,就像《哈利·波特》中会说话的肖像画。

数据增强也是一个非常有用的结构,是GAN的一个实际应用。许多你已经训练过的分类器、检测器和分割模型,在训练中使用GAN生成的数据都取得了显著进展。

如果你想看起来更像某个人,你可以生成一张自己穿着特定风格衣服的图像。这展示了GAN在个性化内容生成上的潜力。


核心概念与算法

以下是图像到图像转换中的一些核心概念。

Pix2Pix算法

Pix2Pix是一个基于条件生成对抗网络的框架,用于学习从输入图像到输出图像的映射。其核心目标函数结合了GAN的对抗损失和输出与真实图像之间的L1损失,以鼓励生成清晰的图像。

对抗损失 鼓励生成器产生难以被判别器区分的图像,其公式可简化为:
L_GAN = E[log(D(x, y))] + E[log(1 - D(x, G(x)))]

L1重建损失 则确保生成图像在像素层面与目标图像接近:
L_L1 = E[||y - G(x)||_1]

总损失是两者的加权和:
L_total = L_GAN + λ * L_L1

数据增强流程

在深度学习中,数据增强用于人工扩展训练数据集。使用GAN进行数据增强的一般流程如下:

  1. 训练GAN:在现有数据集上训练一个GAN模型,使其能够生成与真实数据分布相似的新样本。
  2. 生成合成数据:使用训练好的生成器创建新的图像。
  3. 混合数据:将生成的合成数据与原始真实数据混合,形成扩增后的训练集。
  4. 训练目标模型:使用这个混合数据集来训练最终的任务模型(如分类器、检测器)。

应用场景列表

图像到图像转换框架具有广泛的应用前景,以下是一些主要方向。

  • 图像修复:移除图像中不需要的物体或遮挡物,并智能填充背景。
  • 超分辨率:将低分辨率图像转换为高分辨率、细节更丰富的图像。
  • 语义图像合成:根据草图或标签图生成逼真的图像,如将鞋类草图转为设计图。
  • 风格转换与特效:实现类似艺术滤镜或“会说话的肖像画”等创意应用。
  • 数据增强:为小样本学习任务生成额外的训练数据,提升下游模型的泛化能力。

总结

在本节课中,我们一起学习了图像到图像转换的核心框架及其重要应用。我们了解了Pix2Pix等算法如何通过结合对抗损失和重建损失来实现高质量的图像生成。同时,我们探讨了如何利用GAN进行数据增强,以解决小数据集的训练难题,并列举了该技术在图像修复、超分辨率、概念设计等多个领域的实际应用。

希望你能运用这些知识,创造出有趣且有用的项目。祝你学习顺利,期待看到你的成果!

P61:【2025版】61. 欢迎来到第1周 🎬 - 小土堆Pytorch教程

在本节课中,我们将要学习生成对抗网络(GAN)的一个重要应用:数据增强。我们将探讨如何利用GAN生成的数据来提升下游机器学习模型(如分类器或检测器)的性能,特别是在数据稀缺或涉及隐私的场景下。


概述

你已经看到GAN本身可以生成有趣的数据。然而,这些生成的数据远不止有趣,它们还能为其他模型提供帮助。这个过程被称为数据增强。简单来说,数据增强就是通过人工方式增加训练数据的数量和多样性,以提高模型的泛化能力。


GAN数据增强的核心应用

上一节我们介绍了数据增强的基本概念,本节中我们来看看GAN生成的数据如何具体应用于实际场景。

场景一:解决数据稀缺问题

假设你正在构建一辆自动驾驶汽车。如果它在检测“高尔夫球车”时遇到困难,很可能是因为你的原始数据集中缺少这类样本。

以下是解决此问题的步骤:

  1. 使用你的GAN模型,生成大量包含“高尔夫球车”在道路上的合成图像。
  2. 将这些生成的图像与你的真实数据集混合。
  3. 使用这个混合后的、更丰富的数据集重新训练你的检测器模型。

通过这种方式,你的自动驾驶汽车模型就能学会识别之前未曾见过的“高尔夫球车”,从而提升其整体性能。

场景二:保护数据隐私

在某些情况下,法律或伦理要求可能限制你使用真实的人像数据(例如来自监控摄像头)来训练模型。

以下是应对隐私挑战的方法:

  1. 使用GAN生成不包含任何真实个人身份的“假人”图像。
  2. 用这些生成的隐私安全数据来训练你的模型(如人脸识别或行为分析模型)。

虽然生成的假人数据 G(z) 并非完美(z 为随机噪声向量),但一个好的GAN模型能够生成既接近真实数据分布 P_data(x),又具有一定新颖性的样本。这使得模型在保护隐私的同时,仍能获得一定的识别准确性。


本周任务预告

在理解了GAN数据增强的原理和应用后,本周的实践任务将帮助你巩固这一知识。

以下是你在本周分配中将要完成的内容:

  • 你将在一个流行的公开数据集上进行实践。
  • 你将亲身体验如何使用GAN生成的数据来辅助一个下游分类任务。
  • 通过对比实验,观察添加生成数据后模型性能的变化。


总结

本节课中我们一起学习了GAN在数据增强方面的强大用途。我们探讨了如何利用生成数据解决数据稀缺隐私保护两大挑战。核心在于,GAN能够学习真实数据的分布 P_data(x) 并生成新的样本 G(z),从而扩充训练集,提升下游模型的鲁棒性和适用性。在接下来的实践中,你将有机会亲自验证这一技术的效果。

P63:数据增强方法及其用途 🧠

在本节课中,我们将要学习数据增强的概念、方法及其用途,并探讨生成对抗网络(GAN)在数据增强中扮演的角色。

什么是数据增强?🤔

数据增强通常用于补充数据。当真实数据获取成本过高或过于稀少,导致数据量不足时,数据增强技术可以发挥作用。假设你只有少数几个绿色的真实数据样本,你可以通过生成一些橙色的额外数据点来补充数据集。

GAN在数据增强中的作用 🎨

生成对抗网络(GAN)非常适合数据增强任务。因为它可以生成逼真的假数据来补充真实数据,从而用于下游任务。

这些下游任务可以是分类器、检测器、分割模型或任何类型的判别模型。

传统数据增强方法 🔄

实际上,进行数据增强的一种常见方法并不一定需要使用GAN。传统方法是直接对输入图像进行各种变换。

例如,假设你的任务是检测图像中是否有狗。如果你的分类器数据不足,你可以对一张原始图片进行多种增强处理,然后将所有增强后的图片都作为训练数据输入分类器。

以下是几种常见的传统数据增强操作:

  • 水平翻转transforms.RandomHorizontalFlip()
  • 旋转transforms.RandomRotation(degrees)
  • 缩放和裁剪transforms.RandomResizedCrop(size)
  • 应用滤镜:调整色彩、对比度等。

GAN增强 vs. 传统增强 🌈

GAN在数据增强中的优势在于它能生成大量具有高度多样性的新图片。它生成的狗图片在品种、光照、背景甚至姿态上的多样性,可能远超简单的传统变换。

因此,这些方法可以相互叠加使用。你可以同时使用传统数据增强技术和GAN生成的数据来增强你的数据集。

一个有趣的研究方向是探索如何最佳地组合来自不同增强技术的图像。这个领域试图找到一种策略,以确定何时向分类器提供何种增强图像。如果你对此感兴趣,建议从了解 RandAugment 开始。

数据增强的应用场景 🚀

接下来,我们看看GAN生成的数据在数据增强中的具体应用场景。

应用一:社会科学中的注视点检测 👁️

在社会科学中,研究人员常使用注视点检测来确定人在研究中关注的方向。收集额外的眼睛注视样本通常很困难。

以往,研究人员会生成合成示例,但这些示例通常由计算机图形程序生成,不够真实,对下游分类器的帮助有限。而GAN生成的数据提供了更好的真实性,能显著提高分类器判断眼睛注视方向的性能。这对于难以大规模召集参与者收集数据的研究非常有用。

应用二:语音情感识别 🗣️

语音情感识别旨在检测说话者语音中表达的情感。这个任务对于智能助手(如Alexa或Google Home)很重要,它们需要检测用户情感以提供更好的服务。

代表语音的频谱图(频率谱的视觉表示)具有与情感相关的特征。尽管收集更多真实的愤怒或快乐语音样本可能很困难,但可以使用GAN生成一些假的频谱图来增强数据集。

应用三:医疗影像分析 🏥

在某些领域,获取数据极其困难。例如,由于患者隐私问题,脑部扫描或肿瘤乳腺X光片数据难以获得。

你可以使用GAN生成合成的病变图像(例如由DCGAN生成的肝脏病变)。在其他情况下,获取更多数据样本可能是不道德的(例如,你不可能为了获取癌症样本而故意让人患癌),或者数据无法从其他机构合法获取。在这些情况下,生成假数据成为一个可行的选项。

总结 📝

本节课中我们一起学习了数据增强的核心概念与方法。

  • 数据增强的目的:在真实数据难以获得或成本过高时,通过生成或变换数据来补充数据集。
  • 主要方法
    1. 传统增强:对现有图像进行翻转、旋转、裁剪等变换。
    2. GAN增强:利用生成对抗网络生成高度多样且逼真的新数据。
  • 核心优势:GAN能提供远超传统方法的多样性,并且可以与传统方法结合使用。
  • 应用场景:广泛应用于数据稀缺的领域,如社会科学研究、语音情感识别以及医疗影像分析等。

总之,当真实数据难以获得时,GAN生成的数据为数据增强提供了强大且有效的解决方案,并在多个重要领域展现出巨大的应用潜力。

P64:数据增强的利与弊 📊

在本节课中,我们将探讨使用生成对抗网络进行数据增强的优缺点。我们将分析其在不同场景下的应用效果,并理解其背后的核心原理。


概述

数据增强是提升模型性能的重要手段。传统方法依赖于手工制作的合成示例,而生成对抗网络提供了一种新的途径。本节课程将对比这两种方式,并详细阐述GAN数据增强的优势与局限。


GAN数据增强的优点 👍

上一节我们介绍了数据增强的基本概念,本节中我们来看看GAN数据增强的具体优势。

1. 生成质量优于手工合成示例

使用生成的GAN数据来模仿真实示例,已经显示出比手工制作的合成示例更有帮助。例如,手工制作一个合成眼睛图像可能效果有限,而GAN能生成更逼真的样本。

2. 生成大量标记数据

当你的训练数据集不平衡,或者某个类别的示例数量不足时,你可以使用条件GAN为那些稀缺类别生成大量标记示例。这能有效缓解数据不均衡问题。

核心概念示例(条件GAN)

# 伪代码示意:使用条件c控制生成特定类别的数据
generated_image = generator(z, c)

其中 z 是随机噪声,c 是类别条件。

3. 提升下游模型的泛化能力

GAN数据增强可以提高下游任务模型的泛化能力。例如,在医学图像分割任务中,专家标注的数据有限且获取成本高。你可以用GAN生成更多模仿专家标注风格的数据,从而让下游分割模型学习得更好。这种方法比传统手工合成更接近真实的专家标注分布。


GAN数据增强的缺点 👎

了解了优点后,我们再来看看其面临的挑战和局限性。

1. 生成多样性受限于训练数据

GAN无法创造出训练数据中不存在的多样性。如果你的训练数据集本身就很有限,那么GAN生成的数据多样性也会严重受限。其输出多样性 D_output 严重依赖于输入训练数据的多样性 D_train,可以表示为:
D_output ≈ f(D_train)

2. 可能过度拟合真实数据

如果GAN开始过度模仿或“记住”真实训练数据,以至于生成的假数据与真实数据几乎无法区分,这就构成了另一种形式的过拟合。此时,将这些生成数据加入训练集,就如同对原始数据简单地重复训练,无法为下游任务带来新的、有益的多样性,因而帮助有限。


总结

本节课中我们一起学习了使用生成对抗网络进行数据增强的利与弊。

优点总结

  • 生成的数据质量通常优于手工制作的合成示例。
  • 能够为稀缺类别生成大量标记数据,解决数据不平衡问题。
  • 已被证明能有效提升下游模型(如图像分割、分类、检测任务)的泛化能力。

缺点总结

  • 生成数据的多样性受原始训练数据集范围的限制。
  • 存在过度拟合真实数据、无法提供有效新信息的风险。

理解这些优缺点,能帮助我们在实际项目中更明智地选择和应用数据增强策略。

P66:用于匿名的GAN 🎭

在本节课中,我们将要学习生成对抗网络(GAN)在匿名化领域的应用。我们将探讨GAN如何通过生成不同的面孔来帮助人们隐藏身份,同时也会分析这项技术可能带来的风险,例如身份盗用和深度伪造。


上一节我们介绍了GAN在匿名化中的基本概念,本节中我们来看看GAN如何具体实现身份隐藏。

GAN的核心思想是让两个神经网络——生成器(Generator)和判别器(Discriminator)——相互对抗学习。生成器的目标是生成足以“欺骗”判别器的假数据(如图像),而判别器的目标是准确区分真实数据和生成数据。这个过程可以用以下公式化的目标函数来描述:

min_G max_D V(D, G) = E_{x~p_data(x)}[log D(x)] + E_{z~p_z(z)}[log(1 - D(G(z)))]

其中,G 是生成器,D 是判别器,x 是真实数据,z 是随机噪声。

通过这种对抗训练,生成器最终能学会生成非常逼真的人脸图像。当应用于匿名化时,系统可以接收一个人的真实面部图像,然后生成器会输出一张看起来是另一个人、但保留了原始表情和姿态的新面孔。这样,个人的真实身份得以隐藏,而其想要表达的情感和信息却能够通过一个“替身”面孔传递出去。

以下是GAN用于匿名化的一个典型流程:

  1. 输入一张需要被保护的个人面部图像。
  2. 生成器网络将图像编码到一个潜在空间,并从中解码出一张全新的、不属于任何真实个体的面部图像。
  3. 输出图像保留了原图的姿态、表情和场景上下文,但身份信息已被替换。


了解了基本原理后,我们来看看GAN匿名化技术的一些具体应用场景。这对于需要保护隐私的群体尤为重要。

以下是GAN匿名化技术的主要应用领域:

  • 保护污名化群体:例如,性侵犯受害者或某些案件的证人,他们可能需要在公众面前发声但又必须隐藏真实样貌以避免遭受二次伤害或威胁。
  • 保护社会活动家:在一些敏感地区或议题下,活动家可能需要隐藏身份以保证自身安全,同时仍希望通过视频等方式进行倡导和表达。
  • 纪录片与新闻采访:媒体可以让不愿露面的受访者通过一个生成的面孔来讲述自己的故事,这既保护了受访者,又让故事得以传播。


尽管GAN在匿名化方面有积极作用,但我们必须认识到,同样的技术也可能被滥用。上一节我们看到了其善意的应用,本节中我们来审视其潜在风险。

最突出的风险是身份盗用深度伪造。恶意使用者可以利用GAN技术,将一个人的面部特征替换到另一个人的身体上,制造出该人说出或做出其从未有过言行的虚假视频。例如,可以生成一段“爱因斯坦”发表不当言论的视频。这种深度伪造技术可能被用于散布虚假信息、诽谤他人或进行欺诈,对社会和个人构成严重威胁。


本节课中我们一起学习了生成对抗网络在匿名化领域的双重作用。

总结如下:

  • 积极方面:GAN能够为需要保护隐私的群体(如受害者、证人、活动家)提供一个安全的表达渠道。通过生成逼真的替代面孔,他们可以在隐藏真实身份的同时,有效地传递信息和情感。
  • 消极方面:同样的技术可能被恶意用于身份盗用和制造深度伪造内容,这对个人名誉和社会信任构成重大风险。

因此,GAN技术本身是一把双刃剑,其价值取决于使用者的意图。在发展和应用此类技术时,必须同时考虑其强大的创造力和潜在的破坏力,并建立相应的伦理规范与法律约束。

P67课程:图像风格转换与条件GAN入门 🎨

在本节课中,我们将学习生成对抗网络(GANs)在图像风格转换领域的应用。我们将了解如何利用条件GAN将一种图像的风格转移到另一种图像上,并探索其在实际场景中的多种用途。

概述

上一节我们介绍了GAN的基本概念。本节中,我们将具体探讨一种特殊的GAN应用——图像风格转换。这是一种将源图像的风格(如艺术风格、类型特征)迁移到目标图像内容上的技术。

GAN在图像转换中的应用

应用生成对抗网络(GANs)不仅仅是使用GAN生成数据。你上周学习的数据增强技术,也可以与神经网络结合用于图像转换任务。

图像转换任务是指将一种风格从一个图像转移到另一个图像。这项技术基于其广泛的应用场景。

例如,以下是图像风格转换的几个典型应用方向:

  • 地图与卫星图像互转:你可以构建一个模型,将卫星图像的风格转换为地图路线。
  • 草图生成真实图像:你可以绘制草图,然后让程序基于这些草图生成逼真的图像。
  • 时尚风格转换:对于AI驱动的零售应用,这可能涉及转换不同的时尚风格。你可以通过将整个图像输入到你的条件生成器中来完成这一切。

条件GAN的核心机制

为了实现上述转换,我们需要使用条件生成对抗网络。其核心思想是为生成器和判别器提供额外的条件信息。

传统的GAN输入可能只是一个随机噪声向量 z。而在条件GAN中,生成器的输入除了 z,还有一个条件变量 c。判别器不仅需要判断图像是否真实,还需要判断图像是否符合给定的条件 c

以下是条件GAN与普通GAN在输入上的关键区别:

  • 条件GAN的输入:是一个完整的图像,而不是一个简单的噪声向量。
  • 条件信息的作用:例如,一个独热编码的类别向量可以告诉你的GAN:“生成看起来像卫星图像的东西,但要具备地图的风格”。

这种能够处理图像到图像转换的GAN架构,例如 Pix2Pix,拥有强大的生成器和判别器来学习输入与输出图像之间的复杂映射关系。

总结

本节课中,我们一起学习了生成对抗网络在图像风格转换中的应用。我们了解了条件GAN的基本原理,它通过引入额外的条件信息(如类别标签或另一张图像),指导生成器产生特定风格的输出。我们还看到了这项技术在卫星图转地图、草图生实景、时尚转换等多个领域的实用案例。理解条件GAN是掌握高级图像合成与编辑技术的重要一步。

P68:图像到图像翻译 🖼️➡️🖼️

在本节课中,我们将要学习图像到图像翻译的基本概念。这是一种将输入图像转换为具有不同风格或属性的输出图像的技术,同时保持其核心内容不变。我们将探讨其定义、不同类型以及实际应用示例。

什么是图像到图像翻译?

上一节我们介绍了课程概述,本节中我们来看看图像到图像翻译的具体定义。

想象一下,对一个图像应用变换以得到另一个图像。例如,图像风格的转换。在这里,你看到这个黑白图像被转换为彩色图像。所以某种意义上,这是一种有条件的生成方式,但它是基于一幅图的内容进行条件生成。比如,从这幅黑白图生成一幅新的,它说,基于这幅图,给我生成这幅图的彩色风格。

图像翻译的示例与应用

了解了基本定义后,我们来看看不同种类的图像到图像转换以及其他类型的翻译任务的一些示例。

以下是几个典型的图像翻译任务示例:

  • 从分割图生成照片:这些是道路的汽车行人的人行道的树的分割图。从它生成真实的照片。从它生成真实的照片,这映射到树上,这里标记为树。道路,这里标记为道路和汽车,这里标记为汽车,所以它从一个领域到另一个领域。你可以想象使用语义分割图,你可以得到看起来非常不同的逼真视图。它不必仅仅对应于这个真实的图像。
  • 视频到视频的转换:这里的照片,另一个酷炫的图像翻译任务,或者这里可能是视频到视频的转换。你有视频的帧,映射到另一个视频的帧。所以这本质上是图像到图像的转换,但对于许多许多图像,许多帧,所以你可以将这个黑白火车电影从过去的日子。并使其成为老电影4K,带有一些逼真的彩色。而且这不仅仅是添加逼真的彩色。而是从低分辨率到高分辨率,也被称为超分辨率。

图像翻译是GANs能够大放异彩的地方,因为它们能够创建这些非常逼真的图像。以及视频,每一帧看起来都非常逼真。

配对图像翻译

上一节我们看了一些应用,本节中我们深入探讨一种具体的图像翻译类型:配对图像到图像翻译。

第一种是配对图像到图像翻译,这意味着您正在将输入和输出配对。这意味着,对你训练数据集来说,每一组输入示例。你可能有,都有一个对应的输出图像或目标图像,包含输入图像的内容。但风格不同,所以它们一对一对应。所以基本上,你的条件是输入,以得到输出图像。

正如你可能猜到的,输出对,即每对的第二个图像。所以这座建筑物的立面和这只蝴蝶的彩色图像,它们不是从那个黑白照片生成的唯一图像类型。或者你看到的这段分割图。你可以想象从这些标签中可以生成许多不同的建筑,以及从黑白图像中可以生成许多不同种类的蝴蝶。因此,配对的输出图像不一定是事实真相。但事实真相,所以可能性。

以下是其他配对翻译的例子:

  • 从白天到夜间的照片
  • 从边缘到照片:实际上,你可以通过使用边缘检测算法来获得边缘以创建这些训练数据。这是一个典型的计算机视觉算法。这就是相当酷的,因为你可以轻松地创建这种配对数据集,然后你的生成对抗网络实际上可以从任何类型的边缘。你画的任何东西,训练后生成真实的照片。

更复杂的翻译任务

图像到图像的转换实际上可以变得更加复杂,而不是基于单个输入图像进行条件设置,你可以输入穿着不同衣服的模特,以及他们应该站立的位置的点图。

所以这些点代表不同的姿势,然后从这两个信息中,你想要你的网络生成这个人的不同姿势,所以你在右边看到的就是这样。

当然还有其他类型的翻译任务,超越了仅仅图像的翻译,我认为图像到图像的翻译真的是一个框架,在这个框架上你可以构建并理解这种映射是如何工作的,但实际上它也可以应用于其他模态。

以下是超越图像模态的翻译任务示例:

  • 从文本到图像:例如你可以从文本到图像。在这里你看到的文本,这只鸟是红色的,带有白色,有一个非常短的喙。你可以想象再次看到这段文字并生成出该照片应该看起来的样子。
  • 神经说话的头部:另一个酷的应用是神经说话的头部,或者从图像,说孟若,然后从一个不同的人那里取脸部向量,说或你,然后你实际上可以通过孟若说话。所以这些实际上并不是孟若,根本不说话,这些都是其他人在做面部动作,然后根据这些面部动作,这些脸部向量或脸部地标,加上孟若的这张图片,你可以给这个梦露的图像添加动画。你也可以给爱因斯坦或蒙娜丽莎的图像这样做。

总结

本节课中我们一起学习了图像到图像翻译的核心概念。

总之,图像转换是一个框架,用于条件生成,将图像转换为不同的风格,输入一个图像并将其转换为具有不同风格的不同图像,同时保持内容不变。由于GAN在生成真实图像方面表现很好,它们非常适合图像到图像转换任务。

在接下来的几段视频中,你将了解更多关于这些GAN模型的信息。当然还有其他类型的转换任务,例如,文本到图像或图像到视频,或者图像加面部到视频,这些都是你可以探索的事情,理解图像到图像转换框架将帮助你理解所有这些。

🖼️ 课程69:pix2pix概述

在本节课中,我们将要学习pix2pix,这是一种用于配对图像转换的条件生成对抗网络。

首先,我们将从pix2pix的概述开始,了解其独特的生成器和判别器设计。

1. 什么是pix2pix?

pix2pix的名称来源于“图像到图像”的转换。它是由加州大学伯克利分校发表的论文中提出的一种条件生成对抗网络的非常成功的应用。该网络在输入图像上进行条件设置,并直接生成一个配对的输出图像。

2. 从条件GAN到pix2pix

上一节我们介绍了pix2pix的基本概念,本节中我们来看看它与条件生成对抗网络的关系。

首先,回顾一下条件生成对抗网络。在第一课中,生成器接收一个关于某个类别的向量(例如,柯利犬的独热编码向量)并生成一张该类别的图像。这个类别向量也会传递给判别器,以鼓励输出图像确实属于该类别。

pix2pix与此类似,但输入不是一个类别向量,而是一整张图像。例如,输入可能是一张建筑的分割图,其中不同的颜色代表不同的类别(如窗户、阳台、外墙)。

3. 生成器的输入:为何没有噪声?

以下是pix2pix生成器设计的一个关键点。

在传统的GAN中,生成器通常接收一个随机噪声向量,以产生多样化的输出。然而,pix2pix的作者发现,在配对图像转换任务中,噪声向量对生成器的输出影响不大。这可能是因为存在一个明确的、配对的真实输出图像作为目标,生成器只需学习从输入到该输出的确定性映射。

为了引入一定的随机性,作者选择在训练过程中使用Dropout。Dropout会在神经网络的某些层中随机屏蔽节点,这为输出带来了一些变化,但不像输入不同噪声向量时变化那么剧烈。

4. 判别器的设计

了解了生成器后,我们来看看判别器的设计。

判别器同样接收生成器的输入(即条件图像,如分割掩码)。然后,它会将这个条件图像与另一张图像连接起来。这张图像可能是真实的目标输出(如真实的建筑照片),也可能是生成器产生的输出

判别器的任务是判断这张连接后的图像是“真”还是“假”。换句话说,它需要判断生成器输出的图像,是否看起来像是条件图像的真实映射。这与条件GAN的原理非常相似,只是条件从类别向量变成了整张图像。

5. 网络架构的改进

无论是生成器还是判别器,在pix2pix中都得到了升级。

  • 生成器采用了一种U-Net架构。U-Net通常用于图像分割任务,它包含一个编码器和一个解码器,中间还有跳跃连接。这有助于保留输入图像的细节信息,我们将在下个视频详细介绍。
  • 判别器采用了一种PatchGAN架构。这意味着判别器不再对整个图像给出一个单一的“真/假”判断,而是对图像的不同局部区域(补丁) 分别进行判断,输出一个由多个真/假决策组成的矩阵。这能为生成器提供更细致、更丰富的梯度反馈。

6. 核心要点总结

本节课中我们一起学习了pix2pix的核心概念。

总结一下,pix2pix与条件GAN相似,但有三个关键区别:

  1. 输入是整张图像,而不是类别向量。
  2. 训练数据是严格配对的(输入图像与目标输出图像一一对应)。
  3. 生成器没有明确的噪声向量作为输入,随机性主要通过Dropout引入。
  4. 生成器和判别器的模型架构得到了极大改进,分别采用了U-NetPatchGAN

最终目标仍然是通过对抗训练,生成逼真的、符合输入条件的输出图像。

P7:BCE代价函数详解 🧮

在本节课中,我们将学习二进制交叉熵(BCE)代价函数。该函数是训练生成对抗网络(GANs)等模型的关键组件,特别适用于处理二分类任务,例如区分“真实”与“伪造”的数据。


函数公式与组成部分

完整的BCE代价函数公式如下:

\[J(\theta) = -\frac{1}{m} \sum_{i=1}^{m} \left[ y^{(i)} \log(h_{\theta}(x^{(i)})) + (1 - y^{(i)}) \log(1 - h_{\theta}(x^{(i)})) \right] \]

这个公式可能初看有些复杂,但我们可以将其分解为几个核心部分来理解。

首先,公式开头的求和符号 \(\sum_{i=1}^{m}\) 和除以 \(m\) 表示我们需要计算整个批次(包含 \(m\) 个样本)的平均损失。前面的负号 - 是为了确保最终的损失值为正数,这是优化算法所期望的。

公式中的符号含义如下:

  • \(y^{(i)}\):第 \(i\) 个样本的真实标签,通常为1(真实)或0(伪造)。
  • \(h_{\theta}(x^{(i)})\):模型(例如判别器)对第 \(i\) 个样本 \(x^{(i)}\) 的预测概率,由参数 \(\theta\) 决定。
  • \(\log\):自然对数函数。

公式分解与工作原理

上一节我们介绍了BCE函数的整体结构,本节中我们来看看公式中的两个核心项是如何工作的。它们分别对应了样本标签为1和0的情况。

以下是公式中两个关键项的解读:

  1. \(y \log(h_{\theta}(x))\):此项在真实标签 \(y=1\) 时起作用。

    • 如果模型预测正确(\(h_{\theta}(x) \approx 1\)),则 \(\log(1) \approx 0\),此项贡献的损失很小。
    • 如果模型预测错误(\(h_{\theta}(x) \approx 0\)),则 \(\log(0)\) 会趋向负无穷,此项贡献的损失会非常大。
  2. \((1-y) \log(1 - h_{\theta}(x))\):此项在真实标签 \(y=0\) 时起作用。

    • 如果模型预测正确(\(h_{\theta}(x) \approx 0\)),则 \(\log(1-0) \approx 0\),此项贡献的损失很小。
    • 如果模型预测错误(\(h_{\theta}(x) \approx 1\)),则 \(\log(1-1) = \log(0)\) 趋向负无穷,此项贡献的损失会非常大。

公式前的负号 - 至关重要。它将上述两项中因预测错误而产生的“负无穷大”趋势,转换为“正无穷大”的损失值。这样,神经网络的目标就明确为:通过调整参数 \(\theta\),最小化这个始终为正的损失值 \(J(\theta)\)


损失函数可视化

理解了公式的数学含义后,我们通过图像来直观感受BCE损失函数的行为。

以下是针对不同标签时,损失随预测值变化的示意图:

  • 当真实标签 \(y=1\),损失函数简化为 \(-\log(h_{\theta}(x))\)
    • 当预测值 \(h_{\theta}(x)\) 接近1(正确)时,损失趋近于0。
    • 当预测值 \(h_{\theta}(x)\) 接近0(错误)时,损失会急剧上升并趋向无穷大。

  • 当真实标签 \(y=0\),损失函数简化为 \(-\log(1 - h_{\theta}(x))\)
    • 当预测值 \(h_{\theta}(x)\) 接近0(正确)时,损失趋近于0。
    • 当预测值 \(h_{\theta}(x)\) 接近1(错误)时,损失同样会急剧上升并趋向无穷大。

图像清晰地表明:预测值与真实标签越接近,BCE损失越小;预测值与真实标签差异越大,BCE损失越大,甚至趋向无穷大。 这完美地符合了我们对一个良好损失函数的期望。


批处理计算

在实际训练中,我们很少只计算单个样本的损失。以下是BCE损失在批处理中的计算方式:

模型会同时处理一个批次(例如 \(N=5\) 个)的样本。对于批次中的每一个样本,都独立计算其BCE损失。最终,整个批次的损失是这 \(N\) 个样本损失的平均值。这种批处理方式使得训练过程更加高效和稳定。

# 伪代码示意批处理BCE损失计算
batch_loss = 0
for i in range(batch_size):
    # 计算第i个样本的损失
    sample_loss = bce_loss(y_true[i], y_pred[i])
    batch_loss += sample_loss
average_loss = batch_loss / batch_size # 得到批次的平均损失

总结

本节课中我们一起学习了二进制交叉熵(BCE)代价函数。

我们首先了解了它的完整公式,并拆解了求和、平均以及两个核心对数项的组成部分。我们深入分析了每一项分别在真实标签为1和0时所起的作用,以及负号如何确保损失值为正。通过可视化图像,我们直观地看到了损失如何随着预测准确度而变化:预测正确时损失接近0,预测错误时损失趋向无穷大。最后,我们明确了BCE损失在实际应用中是通过计算一个批次内所有样本损失的平均值来使用的。

总而言之,BCE损失函数通过严厉惩罚错误的预测、轻微奖励正确的预测,有效地驱动模型(如GANs中的判别器)朝着做出准确二分类预测的方向进行学习和优化。

P70:pix2pix PatchGAN 详解 🧩

在本节课中,我们将学习 pix2pix 模型中一个关键的判别器组件——PatchGAN。我们将了解它如何通过输出一个概率值矩阵,而非单一的真假值,来对图像的局部区域进行精细的判别。

上一节我们介绍了生成对抗网络的基本概念,本节中我们来看看 pix2pix 模型中一个特殊的判别器设计。

PatchGAN 架构概述

PatchGAN 判别器的核心特点是输出一个值矩阵,而不是单个标量值。这意味着判别器不再对整个图像给出一个“真”或“假”的总体判断,而是对图像的各个局部区域(即“补丁”)进行独立评估。

因此,PatchGAN 可以输出一个分类矩阵。如下图所示,判别器查看图像的一小块区域,并从整个矩阵中为该区域输出一个概率值。

输出矩阵的含义

在这个输出矩阵中,每个值仍然在 0 到 1 之间。其中,0 代表该区域是“假的”1 代表该区域是“真的”

和传统的判别器一样,PatchGAN 会对图像中所有 70x70 像素的补丁进行处理。矩阵中的每个输出值都对应图像中的一个特定补丁。

通过将判别器的“视野”滑动覆盖输入图像的所有补丁,PatchGAN 能够对图像的每个区域或补丁给出独立的反馈。因为它输出了每个补丁被认为是真实图像的概率。

训练过程

PatchGAN 仍然可以使用二元交叉熵损失进行训练。

对于一个来自生成器的假图像,判别器的目标是尝试输出一个全零的矩阵。因此,对应的标签也是一个全零的矩阵。

公式表示:
目标标签 = 全零矩阵

这意味着判别器认为该图像的每一小块区域都是假的。

同样的逻辑也适用于你数据集中的真实图像。对于真实图像,PatchGAN 模型会尝试输出一个所有元素都为 1 的矩阵。

公式表示:
目标标签 = 全一矩阵

这表示判别器认为图像的每一小块区域都是真实的。

以下是训练过程中的核心步骤:

  1. 对于生成图像,判别器输出应接近 0,损失函数推动其输出全零矩阵。
  2. 对于真实图像,判别器输出应接近 1,损失函数推动其输出全一矩阵。

总结

本节课中我们一起学习了 pix2pix 模型中的 PatchGAN 判别器。

总结来说,对于 pix2pix,其判别器输出一个概率值的矩阵,而不是一个单一的真或假值。矩阵中的 0 仍然对应于该图像区域被分类为“虚假”,而 1 对应于“真实”。这种设计使得模型能够进行更细粒度的图像质量评估,尤其有利于图像到图像的翻译任务。

课程 P71:pix2pix 中的 U-Net 生成器 🧠

在本节课中,我们将要学习 pix2pix 模型的核心组件之一——升级后的生成器,它基于 U-Net 架构。我们将详细解析 U-Net 的结构、工作原理,以及它如何被应用于图像到图像的生成任务中。

概述:什么是 U-Net? 🏗️

U-Net 是一个在图像分割领域非常成功的计算机视觉模型。分割任务是指将一张真实图像中的每个像素进行分类,生成一个分割掩码。例如,在自动驾驶的应用中,模型需要标记出图像中的汽车、人行道、树木、道路和行人等。

上一节我们介绍了图像分割的基本概念,本节中我们来看看 U-Net 如何完成这项任务。

分割任务本质上是一个图像到图像的翻译任务,但它有一个“正确答案”——每个像素的类别是确定的。例如,汽车上的像素必然属于“汽车”类别。

然而,当涉及到图像生成时,情况就不同了。pix2pix 这类模型擅长处理没有单一正确答案的任务。例如,给定一个汽车的分割轮廓图,可以生成无数种外观不同的、但都“正确”的汽车图片。这也是一个图像到图像的翻译任务。

值得注意的是,pix2pix 选择 U-Net 架构作为其生成器,正是因为它擅长接收一张输入图像并将其映射到一张输出图像。

U-Net 的核心架构:编码器-解码器 🔄

传统的生成器(如 DCGAN 中的生成器)通常接收一个小的噪声向量作为输入。而 U-Net 生成器接收的是一整张图像(记作 x)。这意味着生成器需要更强大,能够使用卷积层来处理图像输入。

pix2pix 生成器的架构是典型的编码器-解码器结构。

以下是编码器-解码器的工作流程:

  1. 编码阶段:输入图像 x 经过一系列卷积块,信息被逐步压缩。这个过程类似于一个分类模型,最终将图像信息嵌入到一个称为“瓶颈”的紧凑空间中。
  2. 瓶颈层:这是信息被高度压缩的中间层,它包含了图像中所有重要的高层次特征。
  3. 解码阶段:解码器接收瓶颈层的信息,并通过一系列上采样操作,逐步重建出一张新的输出图像 y

这个过程可能会让你想起自编码器。但在自编码器中,我们希望输出 y 尽可能接近输入 x。而在 pix2pix 中,我们希望 y 是基于 x 条件生成的、风格不同的新图像。

U-Net 的关键创新:跳跃连接 ⚡

由于编码器-解码器网络容易在训练集上过拟合,并且在编码阶段可能会丢失一些细节信息,U-Net 引入了跳跃连接

跳跃连接是 U-Net 架构的核心。它将编码器中每个卷积块的输出,直接连接到解码器中对应分辨率的卷积块的输入之前。

以下是跳跃连接的具体实现方式:

  • 在编码器的每个下采样块后,特征图会被保存。
  • 在解码器的每个上采样块进行卷积操作前,会将来自编码器对应层的特征图与之拼接在一起。

这使得在编码阶段可能被过度压缩的、更精细的细节信息,可以直接传递到解码器的深层,帮助生成更清晰、细节更丰富的输出图像。

除了改善前向传播的信息流,跳跃连接在反向传播中也至关重要。它有助于缓解深度网络中的梯度消失问题,让梯度能够更有效地从解码器流回编码器的浅层,使得整个网络(包括编码器)都能得到良好的训练。

U-Net 的组件详解 🧩

现在,让我们具体看看 U-Net 编码器和解码器的构成。假设输入图像 x 的大小为 256x256x3(高x宽xRGB通道)。

以下是编码器部分的结构:

  • 编码器由 8 个编码块 堆叠而成。
  • 每个编码块通常包含:一个卷积层(步长为2,用于下采样)、批量归一化层ReLU激活函数
  • 经过每个块,空间尺寸(高和宽)会减半。因此,经过8个块后,输出尺寸变为 1x1,但通道数可能增加到 512,以编码丰富的信息。

以下是解码器部分的结构:

  • 解码器同样由 8 个解码块 构成,与编码器对称。
  • 每个解码块通常包含:一个转置卷积层(用于上采样)、批量归一化层ReLU激活函数
  • 在 pix2pix 的实现中,解码器的前三个块还加入了 Dropout 层。Dropout 在训练时随机“关闭”一部分神经元,为模型注入一些随机性,有助于防止过拟合,并让生成结果更具多样性。在推理(测试)阶段,Dropout 会被关闭。
  • 解码器的最终输出 y 与输入 x 尺寸相同,即 256x256x3

将两部分结合起来,就得到了完整的 U-Net 结构:输入图像经过编码器压缩至 1x1 的瓶颈层,再通过解码器(并融合来自编码器的跳跃连接信息)重建出与输入同尺寸的生成图像。

总结 📝

本节课中我们一起学习了 pix2pix 模型所使用的 U-Net 生成器架构。

我们了解到:

  1. U-Net 是一种编码器-解码器架构,最初为图像分割设计,后被成功应用于图像生成任务。
  2. 其核心创新在于跳跃连接,它将编码器各层的特征图与解码器对应层拼接,有效传递了细节信息并改善了梯度流动。
  3. 编码器通过卷积和下采样压缩信息,解码器通过转置卷积和上采样重建图像。
  4. 在 pix2pix 中,Dropout 被用于解码器前几层,在训练时增加随机性。

总而言之,pix2pix 采用 U-Net 作为生成器,利用其强大的图像到图像映射能力和跳跃连接带来的细节保持优势,成功实现了条件图像生成。

P72:pix2pix像素距离损失项 🎨

在本节课中,我们将要学习pix2pix模型中的一个关键组成部分——像素距离损失项。我们将回顾正则化与额外损失项的概念,并深入探讨这个特定损失项的作用、形式及其对图像生成质量的影响。

概述 📋

像素距离损失项是pix2pix生成器的一个额外损失项。它通过计算生成图像与真实配对图像在像素层面的差异,来鼓励生成器产生更接近真实目标的输出。这项损失与主要的对抗损失结合使用,共同指导生成器的训练。

回顾:正则化与额外损失项

上一节我们介绍了pix2pix的基本框架,本节中我们来看看如何通过添加额外损失项来提升模型性能。

在训练生成对抗网络时,对抗损失(如BCE损失或Wasserstein损失)是主要的学习目标。然而,我们经常可以添加额外的损失项来引导模型学习特定的特性或约束。

以下是添加额外损失项的一般形式:

总损失 = 主要对抗损失 + λ * 额外损失项

其中,λ 是一个加权系数,通常小于1,以确保额外损失项不会压倒主要的学习目标。你之前可能接触过类似L1正则化梯度惩罚这样的额外损失项。

pix2pix中的像素距离损失项

在pix2pix的特定情境下,为了使生成的结果看起来更好,我们可以为生成器添加一个像素距离损失项。这个损失项为生成器提供了关于真实目标图像的额外信息,使其能够尝试生成与真实图像更匹配的输出。

它的核心思想是:计算生成器输出的图像(假图像)与真实的配对目标图像(真图像)之间每个像素的差异。

这意味着什么?让我们具体来看:

  • 如果生成图像与真实图像在像素上几乎完全相同,那么像素距离损失值会非常小。
  • 如果两者相差甚远,那么损失值就会很大。

因此,最小化这个损失项,就是在鼓励生成器产生在像素层面上更接近真实目标的图像,这对于提升生成图像的真实感非常有帮助。

损失项的形式与影响

更正式地说,pix2pix生成器的总损失可以表述为以下公式:

总损失 = 对抗损失(BCE) + λ * L1距离(生成输出, 真实输出)

这里,L1距离(即像素距离)是计算两者差异的一种常用方法。通过将这个正则化项添加到生成器的损失函数中,生成器在某种程度上“看到”了真实的目标输出(尽管是以一种间接、软性的方式),其核心目的是让生成的样本质量更高。

在图像到图像的转换任务中,这种方法是可接受的,因为我们的目标输出通常有一个明确、直接的参考(即配对的目标图像)。这项损失最终鼓励生成的图像在整体外观和细节上类似于真实的目标图像。

总结 🎯

本节课中我们一起学习了pix2pix模型中的像素距离损失项

我们了解到:

  1. 它是一个添加到生成器主要对抗损失之外的额外正则化项
  2. 其核心是计算生成图像真实配对图像之间的像素级差异(如L1距离)。
  3. 通过一个加权系数 λ 进行调节,以防止其主导训练过程。
  4. 这项损失的作用是引导生成器产生在像素层面上更接近真实目标的输出,从而提升生成图像的质量和真实感,这在有配对数据的图像转换任务中非常有效。

P73:pix2pix图像翻译教程 🎨

在本节课中,我们将学习如何将pix2pix模型的各个核心组件结合起来,包括生成器、鉴别器以及损失函数,以完成从输入图像到目标图像的翻译任务。


上一节我们介绍了pix2pix的基本概念,本节中我们来看看如何将这些组件整合成一个完整的训练流程。

首先,你需要一个配对的数据集。例如,一个包含真实建筑图像及其对应分割掩码的数据集。分割掩码指明了图像中建筑的位置和轮廓。训练的目标是让模型学会从分割掩码生成逼真的建筑图像。


模型工作流程 🔄

以下是pix2pix模型训练的核心步骤:

  1. 输入与生成
    将分割掩码(输入图像)输入到U-Net生成器中。生成器会输出一张生成图像。

  1. 鉴别器判别
    将生成图像与原始的真实输入图像(即分割掩码)沿通道维度拼接,形成条件输入,然后送入PatchGAN鉴别器
    鉴别器会输出一个分类矩阵(例如 N x N),矩阵中的每个值(0到1之间)代表对应图像块是“真实”的概率。

  1. 计算鉴别器损失
    对于生成图像,我们希望鉴别器将其判别为“假”,因此标签是一个全零矩阵。计算鉴别器预测值与全零矩阵之间的损失(如二元交叉熵损失)。
    对于真实图像,我们希望鉴别器将其判别为“真”,因此标签是一个全一矩阵。计算鉴别器预测值与全一矩阵之间的损失。

  1. 计算生成器损失
    生成器的损失由两部分组成:
    • 对抗损失:生成器希望“欺骗”鉴别器,因此当生成图像输入鉴别器时,其目标是让鉴别器的输出接近全一矩阵。计算此输出与全一矩阵之间的损失。
    • 像素距离损失(L1损失):计算生成器输出图像与真实目标图像之间逐像素的差异。这有助于生成图像在结构上与目标保持一致。
      生成器的总损失是这两项损失的加权和,公式为:
      总损失 = 对抗损失 + λ * L1损失
      其中 λ 是一个控制两项损失权重的超参数。


核心要点总结 ✨

本节课中我们一起学习了pix2pix模型的完整训练流程。

  • pix2pix使用U-Net作为生成器,实现图像到图像的转换。
  • 它使用PatchGAN作为鉴别器,该鉴别器输出一个矩阵,用于评估图像局部区域的真实性,而非整张图像。
  • 生成器的损失函数结合了对抗损失像素级L1损失,这确保了生成结果既逼真(对抗损失驱动),又在结构上与输入条件对齐(L1损失驱动)。

通过这种设计,pix2pix能够有效地学习配对图像数据集之间的映射关系,完成诸如根据分割图生成照片、为草图着色等多种图像翻译任务。

课程P74:pix2pix的进一步发展 🚀

在本节课中,我们将学习pix2pix模型自提出以来的重要改进与扩展。我们将重点介绍两个关键的后续模型:Pix2PixHD和GauGAN,它们分别在高分辨率图像处理和交互式图像生成方面取得了显著进展。

自pix2pix模型问世以来,该领域出现了许多变化和发展。

你将看到pix2pix的一些改进和扩展,这些改进应用于配对图像到图像的转换,包括处理高分辨率图像,以及作为图像编辑应用的明确应用。

Pix2PixHD:高分辨率图像转换 🖼️

上一节我们回顾了pix2pix的基础。本节中我们来看看它的一个重要发展方向——处理高分辨率图像。

首先,来自伯克利大学同一团队的另一个模型出现了。

以及NVIDIA公司,它处理高分辨率图像,所以这个模型叫做Pix2PixHD,即高清高分辨率版本。

Pix2PixHD的核心优势,正是其处理高分辨率图像的能力。

该模型包含很多修改,使其性能显著提升。

因此我推荐查看Pix2PixHD的论文和可选的代码笔记本。

Pix2PixHD的应用实例 🎨

如果你想进行图像翻译,这里展示的是非常出色的功能。

你也可以在常规的pix2pix应用中使用它。基本上,你可以做的是,获得一张人脸的分割掩码。

你可以根据需要调整那个掩码,并生成不同类型的人脸图像。

实际上,我认为这里正在发生的事情是,你甚至不需要改变掩码本身。

你实际上可以从同一个掩码生成许多种不同可能的人脸。

这也是相当酷的,你肯定可以制作版本,使用pix2pix来适应掩码。

GauGAN:交互式语义图像合成 ✏️

另一个非常酷的模型出现了,叫做GauGAN,由NVIDIA开发。

这个名字是对艺术家保罗·高更的一个双关语。

GauGAN在应用方面非常酷。

我仍然记得他们在会议上展示的演示,基本上你做的就是:

你可以在界面左边画草图,并指示草图的不同部分属于哪种类别。

你可以指定,比如“我想要这里是天空”,“我想要这里有一条水线”,然后它就能生成一张真实的风景照片给你。

所以我认为我的艺术水平肯定只停留在左边草图的阶段。

对我来说,模型能生成右边那样逼真的图像是非常酷的。

GauGAN的技术亮点 ⚙️

关于GauGAN的一个酷炫之处是,它使用了你在StyleGAN中看到的一些先进技术。它实际上使用了自适应实例归一化,以便将分割图作为输入并加以利用。

以下是其核心思想的一个简化表示:

# 伪代码:自适应实例归一化 (AdaIN) 的核心思想
output = style_scale * (input - mean(input)) / std(input) + style_bias

它使用自适应实例归一化来为生成的图像添加风格信息。

总结 📝

总之。

Pix2PixHD和GauGAN是pix2pix模型的继承者,它们建立在pix2pix的基础之上。

并在高分辨率图像处理和交互式创作方面对原始模型进行了惊人的改进,我强烈推荐你去深入了解它们。

本节课中我们一起学习了pix2pix的两个重要发展:Pix2PixHD 专注于生成高分辨率、高质量的配对图像转换结果;而 GauGAN 则引入了交互式语义绘制和先进的风格控制技术(如AdaIN),让用户能够通过简单的草图生成逼真的复杂场景。它们共同代表了条件生成对抗网络在实用化和高性能化方向上的重要进步。

P75:【2025版】75. 欢迎来到第3周 🎯 - 小土堆Pytorch教程

在本节课中,我们将学习一种无需配对图像即可实现风格转换的先进方法——CycleGAN。我们将了解其核心思想,并探索两个生成对抗网络(GAN)如何协同工作,完成从“马”到“斑马”的图像转换任务。


概述

恭喜你进入本专题的最后一周。本周内容将在上周图像转换知识的基础上进行构建。关键区别在于,你不再需要知道两张配对图像之间的精确对应关系。你只需要准备两堆不同风格的图像集合。

你的GAN模型会从这些数据中自动学习映射关系。更准确地说,这将是两个GAN共同协作来找出这个映射。


核心思想:双向循环映射

上一节我们介绍了无需配对数据的基本前提,本节中我们来看看CycleGAN是如何实现这一点的。

其核心洞察力在于建立一个循环。这个想法让一个GAN将马图像转换成斑马,然后让另一个GAN将这个生成的“假斑马”图像再转换回马。

由于GAN被设计为只改变图像的风格而不改变其内容,因此第二个GAN生成的“马”应该与最初输入的真实马图像非常相似。


网络结构与工作流程

理解了循环的思想后,我们来看看两个GAN是如何具体交互的。

以下是CycleGAN中两个生成器的基本工作流程:

  1. 生成器G:负责将域A(例如马)的图像转换到域B(例如斑马)。
    • 假斑马 = G(真马)
  2. 生成器F:负责将域B(例如斑马)的图像转换回域A(例如马)。
    • 重建马 = F(假斑马)

这两个生成器之间的相互作用形成了一个闭合循环,因此得名CycleGAN。你首先将真实马图像输入到第一个GAN(G)中,得到假斑马图像,然后再将这个假斑马图像输入到第二个GAN(F)中,目标是重建出原始的马图像。

这个循环一致性是模型能够在不使用配对数据的情况下学习正确映射的关键。


总结

本节课中,我们一起学习了CycleGAN的基本原理。我们了解到,通过使用两个生成器并构建一个循环重建的约束,模型可以仅凭两堆未配对的图像集(如一堆马图和一堆斑马图),自动学习到两种风格之间的双向映射关系。这解决了收集精确配对训练数据的难题,是图像风格转换领域的一个重要进展。

🖼️ 课程 P76:非配对图像到图像翻译

在本节课中,我们将要学习非配对图像到图像翻译的核心概念。我们将从比较它与配对翻译的区别开始,理解其工作原理,并探讨模型如何从两个不同风格的图像集合中学习,以完成风格转换任务。


🔄 配对与非配对翻译的比较

上一节我们介绍了图像翻译的基本概念,本节中我们来看看两种主要的范式:配对翻译与非配对翻译。

你之前已经看到了配对图像翻译。这是有明确输入输出配对的情况。例如,边缘检测任务中,输入是真实图像,输出是其对应的边缘图。因为你可以使用边缘检测器将真实图像转换为边缘,所以很容易获得这种配对数据集。

其数据关系可以表示为:
公式: {(x_i, y_i)},其中 i = 0, 1, 2, ...x_iy_i 是严格对应的。

然而,非配对图像翻译则不同。例如,你想将一匹马变成斑马,或者将一张照片变成莫奈风格的画作。这类任务要困难得多,因为你通常没有现成的配对训练数据。你不可能为每张照片都有一幅对应的莫奈风格画作,反之亦然。


🗂️ 非配对翻译的核心:两个图像堆

在非配对图像翻译中,你实际上只有两个不同风格的图像集合(或称“堆”)。

以下是两个图像堆的典型例子:

  • 一堆 X:可能是真实的照片。
  • 一堆 Y:可能是莫奈的画作、夏季场景的图像,或者斑马的图片。

模型的目标是使用这两个堆 XY,学习从一个堆到另一个堆的一般风格元素映射,并将图像从一个域转换到另一个域。这种转换通常是双向的,例如既可以从照片到莫奈风格,也可以从莫奈风格“还原”到照片。


🎯 任务关键:分离内容与风格

理解非配对翻译任务的关键在于认识到图像中存在共享的内容独特的风格

具体来说,从斑马图像生成马图像时,生成的马应该保持与原始斑马相同的姿态、背景和基本形状。你只想让那些条纹消失

  • 内容:指两个图像堆之间共享的元素,例如物体的一般形状、构图和背景。
    代码/概念描述: 内容 = 跨域共享的语义信息
  • 风格:指每个图像堆独特的外观元素,例如斑马的条纹、莫奈的笔触和色彩。
    代码/概念描述: 风格 = 域特定的外观特征

因此,模型的核心目标是学会区分并分离这两部分:保留跨域通用的内容,同时转换域特定的风格


📝 总结

本节课中我们一起学习了非配对图像到图像翻译。

我们首先比较了它与配对翻译的区别:配对翻译依赖于严格对应的输入输出对 (x_i, y_i),而非配对翻译则只有两个未配对的不同风格图像集合 XY

接着,我们探讨了其工作原理。模型需要从这两个“堆”中学习,找出它们之间的共同内容(如物体形状)和差异风格(如纹理、颜色)。最终目标是实现图像风格的转换,同时保留其核心内容。

简单来说,非配对图像到图像转换利用不同风格的图像集合进行训练。模型通过保留两个集合中共有的内容,并改变各自独特的风格,来学习它们之间的映射关系。

在接下来的课程中,我们将深入探讨实现这一目标的经典算法。

P77:CycleGAN概述 🌀

在本节课中,我们将学习CycleGAN的核心概念。CycleGAN是一种用于无配对图像到图像转换的生成对抗网络。我们将了解其工作原理、核心组件以及它如何在没有成对训练数据的情况下实现风格转换。


什么是CycleGAN?🤔

CycleGAN旨在解决一个特定问题:无配对图像到图像转换。这意味着我们有两组不同风格的图像(例如,马和斑马),但它们之间没有一一对应的配对关系。CycleGAN的目标是学习如何将一种风格的图像转换为另一种风格,而无需知道具体的对应样本。

上一节我们介绍了CycleGAN的目标,本节中我们来看看其核心思想——“循环”的含义。

循环一致性:CycleGAN的核心洞察 🔄

“循环”在CycleGAN中指的是一个关键概念:循环一致性。其核心思想是,如果你将一个图像(例如,一张真实的斑马图片)转换为目标风格(例如,马),然后再将这个生成的图像转换回原始风格(斑马),最终得到的图像应该与原始图像非常相似。

这个过程之所以有效,是因为转换过程只应改变图像的风格,而不应改变其内容。通过强制这个“循环”过程,模型可以学习到内容的一致性。这通常通过计算原始图像与循环重建图像之间的像素级差异(即循环一致性损失)来实现。

理解了循环一致性的原理后,我们来看看CycleGAN是如何通过具体架构实现这一点的。

CycleGAN的架构:两个GAN的组合 🤝

CycleGAN由两个生成对抗网络(GAN) 组合而成,它们共同工作以实现双向转换。

以下是CycleGAN的主要组成部分:

  • 生成器G(斑马 -> 马):负责将斑马图像转换为马风格的图像。
  • 生成器F(马 -> 斑马):负责将马图像转换为斑马风格的图像。
  • 判别器D_X:判断一张图像是“真实的马”还是“由G生成的假马”。
  • 判别器D_Y:判断一张图像是“真实的斑马”还是“由F生成的假斑马”。

这两个GAN协同工作。判别器确保生成的图像在目标域中看起来逼真,而循环一致性损失则确保图像内容在转换过程中得以保留。

了解了整体架构,接下来我们深入看看生成器和判别器的具体设计。

生成器与判别器的设计 🛠️

判别器:PatchGAN

CycleGAN的判别器采用PatchGAN结构。与输出单个真/假值的传统判别器不同,PatchGAN对图像的多个局部区域(补丁)进行判断,并输出一个矩阵,其中每个值代表对应补丁为真的概率。这有助于模型捕捉更精细的局部纹理和风格。

生成器:基于U-Net与ResNet的改进

CycleGAN的生成器架构融合了之前课程中学到的多种技术:

  1. U-Net框架:借鉴了图像分割中的U-Net结构,包含一个下采样(编码) 部分和一个上采样(解码) 部分,有助于保留图像的低级特征。
  2. DCGAN风格:在U-Net的瓶颈部分(编码与解码之间)增加了多个卷积层,以增强模型的变换能力,这借鉴了DCGAN生成器的思想。
  3. 残差连接(跳跃连接):在瓶颈部分的卷积层之间引入了残差块(Residual Blocks)。残差连接允许网络学习恒等映射,使得添加更深的层变得更容易,有助于训练更稳定的生成器。


生成器的代码结构可以抽象为以下形式:

# 简化的生成器结构示意
输入图像 -> 下采样(编码) -> 残差块(瓶颈) -> 上采样(解码) -> 输出图像

总结 📝

本节课中我们一起学习了CycleGAN。我们了解到:

  1. CycleGAN用于无配对图像翻译,解决了在没有成对数据的情况下进行风格转换的难题。
  2. 其核心是循环一致性损失,它通过强制转换循环的可逆性来保留图像内容。
  3. CycleGAN的架构由两个GAN组成,分别负责两个方向的转换。
  4. 其判别器采用PatchGAN结构,用于评估图像局部区域的真实性。
  5. 其生成器结合了U-Net的编码-解码结构、DCGAN的深度卷积设计以及残差连接,构成了一个强大的图像转换网络。

总之,CycleGAN通过巧妙的“循环”设计和组合已有的神经网络组件,实现了令人印象深刻的、无需配对数据的图像到图像转换。

P78:CycleGAN 双生成对抗网络 🌀

在本节课中,我们将学习 CycleGAN 的核心架构。CycleGAN 是一种用于图像风格转换的模型,它能够在没有成对训练数据的情况下,学习两个不同域(例如马和斑马)之间的映射关系。


模型架构概览

正如预期的那样,CycleGAN 包含两个独立的生成对抗网络(GAN),每个 GAN 又由一个生成器和一个判别器组成。因此,整个模型共有四个核心组件。


两个方向的GAN

首先,我们有一个从斑马图像转换到马图像的 GAN。其次,我们还有一个从马图像转换到斑马图像的 GAN。这两个 GAN 共同构成了一个循环。

以下是四个组成部分的具体描述:

  • 斑马到马 GAN:包含一个学习从斑马映射到马的生成器,以及一个负责判别马图像真伪的判别器。
  • 马到斑马 GAN:包含一个学习从马映射到斑马的生成器,以及一个负责判别斑马图像真伪的判别器。


前向转换过程

现在,让我们具体看看一个方向的转换是如何工作的。

当输入一张斑马图像时,它会被送入 斑马到马的生成器,该生成器会将其映射(转换)成一张马的图像。

接着,这张生成的马图像会被送到 马的判别器。判别器的任务是检查图像的真实性,它需要从一堆真实的马图像和生成的“假”马图像中,判断出哪些是真实的。

需要特别注意的是,这里的判别器是一个 PatchGAN。这意味着它不会对整个图像输出一个单一的真/假判断,而是会输出一个分类矩阵,矩阵中的每个元素对应图像中的一个“补丁”(局部区域)的真实性判断。


反向转换过程

相反方向的转换过程是完全对称的。从马到斑马的生成器将马图像转换为斑马图像,而 斑马的判别器 则专注于判断斑马图像的真伪。


与Pix2Pix的对比

总结来说,CycleGAN 由四个部分组成:两个生成器和两个判别器。

生成器和判别器的输入形式与另一个图像转换模型 Pix2Pix 类似。但是,两者有一个关键区别:CycleGAN 不需要成对的训练数据

因为没有配对的真实图像作为目标输出,所以 CycleGAN 无法使用 Pix2Pix 中的 像素距离损失(如 L1 Loss)。在 Pix2Pix 中,生成器的输出会与一个真实的目标图像进行比较来计算损失。

而在 CycleGAN 中,由于没有这个“目标输出”,模型的学习完全依赖于两个判别器对各自域内图像真实性的判断,以及我们将在后续课程中介绍的“循环一致性”约束。


本节总结

本节课中,我们一起学习了 CycleGAN 的基本架构。我们了解到 CycleGAN 包含两个方向的 GAN,共计两个生成器和两个判别器。最重要的是,我们明白了 CycleGAN 与 Pix2Pix 的核心区别在于它不需要成对的训练数据,因此其损失函数的设计也截然不同。在下一节中,我们将深入探讨 CycleGAN 是如何在没有配对数据的情况下进行有效训练的。

P79:CycleGAN循环一致性 🚲

在本节课中,我们将要学习CycleGAN中的核心概念——循环一致性。我们将了解它是什么、为什么重要、如何计算,并通过消融研究来观察其实际效果。


概述

循环一致性是添加到CycleGAN损失函数中的最后一个关键项,它使得图像风格转换的“循环”过程得以实现。本节将详细解释循环一致性的原理、计算方式及其重要性。


什么是循环一致性?

循环一致性是损失函数中的一个额外损失项,它同时适用于CycleGAN中的两个生成器。接下来,我们将解释循环一致性如何具体发挥作用,以及如果在CycleGAN中不包含它会发生什么。

首先,我们检查“斑马 -> 马 -> 斑马”这个方向。第一个生成器(斑马到马)会将一张真实的斑马图像映射为一匹假的马。

然后,另一个生成器(马到斑马)会将那匹假的马映射回一张假的斑马图像。因此,循环一致性期望的是:生成的假斑马图像应该与输入的真实斑马图像尽可能一致,因为理论上只有图像的“风格”(如纹理)发生了变化,而“内容”(如物体形状和位置)应该保持不变。

以下是实现这一目标的方法:

你可以计算这两张图像(真实斑马与循环生成的假斑马)之间的像素差异,并将这个差异值添加到损失函数中。这样做的目的是鼓励生成器使这两张图像尽可能接近。

同样的原理也适用于相反的方向,即“马 -> 斑马 -> 马”。

你需要再次计算真实马图像与循环生成的假马图像之间的像素差异。因此,整个循环一致性损失可以通过将两个方向的像素差异相加来构建。

  • 方向一(斑马->马->斑马):计算真实斑马与循环生成的假斑马之间的差异。
  • 方向二(马->斑马->马):计算真实马与循环生成的假马之间的差异。

你可以简单地对每个训练样本 i 在这两个方向上的差异进行求和。这就构成了生成器的循环一致性损失项

其核心公式可以表示为:
循环一致性损失 = Σ_i [ ||G_BA(G_AB(x_i)) - x_i|| + ||G_AB(G_BA(y_i)) - y_i|| ]
其中,G_AB 是将A域(如斑马)转换到B域(如马)的生成器,G_BA 是反向的生成器,x_iy_i 分别是来自A域和B域的真实图像。


如何将循环一致性整合到训练中?

你是如何将这一项添加到模型中的呢?你需要将其添加到生成器的对抗损失中。

由于两个方向的转换都涉及到了这两个生成器,你实际上使用一个优化器来同时优化它们。两个生成器共享这个循环一致性损失项。

  • 对抗损失:这是主要的GAN损失函数,用于鼓励生成器生成逼真的图像,并让判别器区分真假。CycleGAN中的对抗损失与你之前见过的标准GAN略有不同。
  • 循环一致性损失:在训练数据集中的所有斑马和马图像上计算,并用一个超参数 λ(lambda)进行加权。

这样,你就可以得到全局的循环一致性损失项,将其加到生成器的对抗损失中,从而得到生成器的最终总损失。


循环一致性的广泛应用

有趣的是,循环一致性的概念在CycleGAN之外的应用也比想象中更广泛。它在深度学习的多个领域都有应用:

  • 数据增强:例如,在图像处理中,可以通过循环转换来生成新的训练样本。
  • 文本翻译:从法语翻译成英语,再翻译回法语,你期望得到相同或语义相近的短语。即使不完全相同,这个过程也可能为数据集引入有益的噪声,增强模型的鲁棒性。

所以,循环一致性可以实现一些很酷的功能。以上就是循环一致性损失的基本原理。


消融研究:验证循环一致性的重要性

原论文(“自行车纸”)展示了一些很酷的标记研究,并且进行了消融研究

“消融”这个词意味着你在模型中逐一移除或“切除”各种组件,然后观察模型在没有这些组件的情况下性能如何变化。

以下是论文中的消融实验结果:

  1. 仅使用循环一致性损失(无GAN组件)
    如果模型只使用循环一致性损失,而没有对抗损失(即GAN组件),会发生什么?
    你可以看到这种模型的效果很差。生成的图像质量不佳,几乎全是黑色的方块,可能发生了模式崩溃,并且图像毫无真实感。这说明,仅靠循环一致性无法生成逼真的图像。

  1. 仅使用对抗损失(无循环一致性)
    如果模型只有GAN的对抗损失,而没有循环一致性损失,输出看起来相当逼真。
    然而,仔细观察会发现存在模式崩溃的问题。例如,两张完全不同的输入图像,经过转换后得到的分割掩码(或风格化结果)却非常相似。生成的图像虽然真实,但缺乏多样性,所有输出都具有相似的特征。

  1. 同时使用对抗损失和循环一致性损失
    当同时使用对抗损失和(双向的)循环一致性损失时,结果得到了显著改善。
    模式崩溃现象减少,输出图像的多样性增加,并且看起来相当逼真。这是目前能达到的最佳效果。

因此,循环一致性结合了两种损失的优势。这些消融研究表明,如果去掉其中任何一个损失项,模型性能都会下降。这也说明了为什么CycleGAN论文强调这是一个重要的贡献。在研究论文中,你经常会看到这种消融研究,用于验证每个组件的必要性。


总结

本节课中,我们一起学习了CycleGAN中的循环一致性。

  • 核心作用:循环一致性在转换不常见的风格元素(如斑马条纹)时,对于保持图像中的常见内容(如马的形状)至关重要。
  • 实现方式:它是一个非常重要的损失项,通过将两个方向(斑马->马->斑马, 马->斑马->马)的像素级差异损失,加权后添加到生成器的对抗损失中来实现。
  • 实验验证:消融研究显示,双向的循环一致性损失项能有效帮助防止模式崩溃,促使模型生成既逼真又多样化的结果。

通过理解循环一致性,你便掌握了CycleGAN能够实现高质量、非配对图像风格转换的关键所在。

P8:结合各个部分 🧩 - 小土堆PyTorch教程

在本节课中,我们将学习如何将生成对抗网络(GAN)的各个组成部分整合在一起,并理解其完整的训练流程。我们将回顾生成器与判别器的核心概念,并详细讲解它们如何通过交替训练的方式协同工作,最终生成逼真的数据。


GAN架构回顾

上一节我们介绍了GAN的基本组成部分。本节中,我们来看看一个基础GAN架构的可能表示。

在一个基本的GAN中,包含两个核心神经网络:

  • 生成器 (Generator):以随机噪声 ψ 作为输入,生成假样本
  • 判别器 (Discriminator):接收真实样本 x 和生成器产生的假样本 ,输出一个概率值 ŷ,用于判断输入样本是真实(接近1)还是虚假(接近0)。

生成器的目标是生成足以“愚弄”判别器的假样本,使其看起来尽可能真实。判别器的目标是准确地区分真实样本与生成样本。


判别器的训练过程

理解了整体架构后,我们首先深入探讨判别器是如何被训练的。

判别器的训练目标是最大化其区分真假样本的能力。以下是其训练步骤:

  1. 准备数据:从数据集中采样一批真实样本 x,同时从生成器获取一批由噪声 ψ 生成的假样本
  2. 前向传播:将混合的真假样本(不告知标签)输入判别器,获得预测概率 ŷ
  3. 计算损失:将预测值 ŷ 与对应的真实标签(真样本为1,假样本为0)进行比较,计算二元交叉熵损失。
  4. 反向传播与更新:损失梯度反向传播,仅更新判别器的参数 θ_d

此过程仅优化判别器,生成器的参数在此步骤中保持固定。


生成器的训练过程

在判别器得到更新后,接下来我们看看如何训练生成器。

生成器的训练目标是使判别器将其生成的样本误判为真实样本。以下是其训练步骤:

  1. 生成假样本:生成器接收一批随机噪声 ψ,并生成假样本
  2. 前向传播:将这些假样本 输入固定参数的判别器,获得预测概率 ŷ
  3. 计算损失:这里的关键是,生成器希望这些假样本被判别为“真”。因此,损失计算是将预测值 ŷ全为1的标签进行比较(即希望判别器输出全部为1)。
  4. 反向传播与更新:计算出的损失梯度反向传播,仅更新生成器的参数 θ_g

在此过程中,判别器的参数被冻结,不会被更新。


交替训练与平衡的重要性

我们已经分别了解了生成器和判别器的训练步骤。现在,我们将它们结合起来,理解交替训练的核心思想及其关键注意事项。

GAN的训练采用交替迭代的方式进行:

  1. 训练判别器 k 步(通常 k=1)。
  2. 训练生成器1步。
  3. 重复此过程。

以下是维持有效训练的关键点:

  • 动态平衡:生成器与判别器必须同步提升,并始终保持相近的“技能水平”。
  • 判别器过强的后果:如果判别器过于强大,能轻易识别所有假样本(输出 ŷ=0),则生成器获得的梯度会非常小(“梯度消失”),导致其无法学习如何改进。
  • 生成器过强的后果:如果生成器过于强大,生成样本完全逼真,判别器将无法给出有意义的反馈(输出 ŷ=1),同样会阻碍训练。
  • 信息丰富的梯度:理想的训练状态是判别器给出具有信息量的预测(例如 ŷ=0.6ŷ=0.05),而非绝对化的0或1。这些“不确定”的预测能为生成器提供更丰富的梯度信号,指导其向生成更真实样本的方向更新。

由于判别器的任务(二分类)通常比生成器的任务(从噪声生成复杂数据)更简单,因此在实践中,防止判别器过快领先是GAN训练中的一个常见挑战。


总结

本节课中,我们一起学习了GAN的完整训练流程。

我们首先回顾了GAN的基本架构,它由生成器和判别器组成。接着,我们拆解了判别器和生成器各自的训练步骤,明确了它们如何通过计算不同的损失函数来更新各自的参数。最后,我们深入探讨了交替训练的核心机制,并强调了保持生成器与判别器之间动态平衡的重要性,这是GAN能够成功收敛并生成高质量数据的关键。

理解了这个交替训练与平衡的框架,你就掌握了基础GAN运作的核心原理。

P80:【2025版】80. CycleGAN最小二乘损失 🎯

在本节课中,我们将学习CycleGAN中使用的最小二乘损失。我们将从统计学中的最小二乘法概念讲起,然后探讨它在生成对抗网络(GAN)中作为对抗性损失的含义与作用,并了解它如何替代传统的BCE损失或Wasserstein损失。

概述 📋

最小二乘损失出现在与WGAN-GP相似的时期,当时训练生成对抗网络的稳定性是一个重大问题。该损失函数被用来帮助解决训练稳定性问题,例如梯度消失和模式崩溃,这些问题在BCE损失中常见,并可能导致学习过程提前终止。

在深入之前,请注意,存在许多GAN损失函数,人们通常会根据经验为特定数据集选择效果更好的损失函数。训练时间也是选择损失函数时的一个重要考量因素。

最小二乘法基础 📈

最小二乘法是统计学中一个简单的概念,它是一种通过最小化平方残差来找到最佳拟合线的方法。这意味着它试图找到一条直线,使得所有数据点到这条直线的平方距离之和最小。

以下是其核心思想:

  1. 假设有一些数据点,你想画一条直线来拟合它们。
  2. 计算每个点到这条直线的垂直距离。
  3. 将这些距离进行平方(以避免正负抵消),然后求和。
  4. 通过调整直线的参数,最小化这个平方和,此时得到的直线就是最佳拟合线。

用公式表示,对于一组点 (x_i, y_i) 和直线 y = ax + b,最小二乘法的目标是找到参数 ab,使得以下值最小:
S = Σ (y_i - (a*x_i + b))^2

最小二乘损失在GAN中的应用 🤖

在GAN的语境中,“直线”变成了判别器(Discriminator)的目标标签。具体来说:

  • 对于真实图像,目标标签是 1。点则是判别器对真实图像的预测值 D(x)
  • 对于生成图像,目标标签是 0。点则是判别器对生成图像的预测值 D(G(z))

最小二乘损失的目标,就是最小化判别器预测值与其对应目标标签之间的平方距离

以下是判别器和生成器的损失函数公式:

判别器损失 (D Loss)
L_D = E_{x~p_data}[(D(x) - 1)^2] + E_{z~p_z}[(D(G(z)) - 0)^2]

  • 第一项鼓励判别器将真实图像判别为 1
  • 第二项鼓励判别器将生成图像判别为 0

生成器损失 (G Loss)
L_G = E_{z~p_z}[(D(G(z)) - 1)^2]

  • 生成器的目标是“欺骗”判别器,因此它希望判别器将生成图像判别为 1

与BCE损失的对比 ⚖️

上一节我们介绍了最小二乘损失的公式,本节中我们来看看它与二元交叉熵(BCE)损失的关键区别。

最小二乘损失的一个主要优势在于它缓解了梯度消失问题。在BCE损失中,当判别器的预测非常自信(接近0或1)时,损失函数的梯度会变得非常平缓(饱和),导致生成器难以获得有效的更新信号。

而最小二乘损失函数只在预测完全正确(即预测值等于目标标签1或0)时才会变得平坦。在其他情况下,损失值是一个平滑的二次函数,能提供持续的梯度,从而改善了GAN训练的稳定性。

对于熟悉其他概念的读者,最小二乘损失也被称为均方误差(MSE)

在CycleGAN中的整体损失 🚴

在CycleGAN的背景下,最小二乘损失被用作其对抗性损失部分。完整的CycleGAN损失函数由两部分组成:

  1. 对抗损失(Adversarial Loss):即我们刚刚学习的最小二乘损失,用于确保生成图像在目标域中的真实性。
  2. 循环一致性损失(Cycle Consistency Loss):这是我们之前学过的内容,用于保持图像转换前后的内容一致性,用超参数 λ 来控制其权重。

因此,CycleGAN的总生成器损失是这两部分的和。

总结 🎓

本节课中我们一起学习了最小二乘损失。

  • 我们首先回顾了统计学中最小二乘法的基本概念,即通过最小化平方距离之和来寻找最佳拟合。
  • 接着,我们探讨了如何将这一概念应用于GAN中,定义了判别器生成器对应的最小二乘对抗损失公式。
  • 然后,我们对比了最小二乘损失与BCE损失,指出前者由于梯度非饱和的特性,有助于缓解训练中的梯度消失问题,从而提升训练稳定性。
  • 最后,我们明确了在CycleGAN中,最小二乘损失作为对抗损失,与循环一致性损失共同构成了模型的完整目标函数。

记住,最小二乘损失是众多改进GAN训练稳定性的技巧之一,在实践中需要根据具体任务进行选择和实验。

课程 P81:CycleGAN 身份损失详解 🎨

在本节课中,我们将要学习 CycleGAN 中的一个重要概念——身份损失。我们将了解它的工作原理、作用以及如何通过它来改善图像转换任务中的颜色保真度。


上一节我们介绍了 CycleGAN 的基本框架和核心损失函数。本节中我们来看看一个可选的、但非常有用的额外损失项——身份损失。

身份损失是一个额外的损失项,主要用于帮助生成器在输出中更好地保存输入图像的颜色信息。

除了对抗性损失和循环一致性损失,CycleGAN 还可以使用一个基于像素差异的损失项,称为身份损失。这个损失项是可选的,但它有助于保留图像的颜色,使风格映射更具意义。

它的核心思想是:当一个已经属于目标风格的图像被输入到对应的生成器时,生成器应该输出一个与输入完全相同的图像,即执行身份映射

例如,将一个真实的马图像输入到“斑马到马”的生成器中。由于输入图像已经是马的风格,生成器理想情况下应该不做任何改变,直接输出原图。

以下是身份损失的计算方式:

你可以计算真实输入图像与生成器输出图像之间的像素距离。

并将这个距离值添加到总的损失函数中。在理想的身份映射情况下,这个像素距离应为零。

这意味着身份损失为零,这正是我们希望生成器做到的行为:当输入已经是目标风格时,不做任何改变。

所以,身份损失的目的就是鼓励生成器的这种身份映射行为。

相反,如果生成器将一个马的图像错误地映射成其他奇怪的东西(例如改变了颜色),我们就需要计算输入与输出之间的像素距离,并通过损失函数来惩罚这种非身份映射。

在 CycleGAN 完整的损失函数中,除了对抗性损失和循环一致性损失,你现在可以为两个生成器都添加身份损失。

  • 为“斑马到马”生成器添加身份损失:输入真实的马图像。
  • 为“马到斑马”生成器添加身份损失:输入真实的斑马图像。

与循环一致性损失类似,身份损失在总损失中也需要一个权重系数(通常表示为 λ_id)。这允许你平衡不同损失项的重要性。

为了更直观地理解,假设一个任务是将夏季场景转换为冬季场景。在没有身份损失的情况下,生成器可能会过度调整,导致所有输入(包括已经是冬季的场景)都带上一种偏蓝的色调,造成颜色失真。

而有了身份损失,当输入一个冬季场景时,生成器会被鼓励直接输出原图,从而更好地保持颜色保真度。


本节课中我们一起学习了 CycleGAN 的身份损失。总结如下:

  1. 目的:身份损失通过鼓励身份映射,帮助生成器在图像转换任务中更好地保持输入图像的颜色和内容。
  2. 计算:它通过计算真实输入图像与生成器输出图像之间的像素距离来实现。
  3. 作用:当输入图像已经具备目标风格时,理想的生成器应输出原图,此时身份损失为零。
  4. 性质:它是一个可选的损失项,通过一个权重系数 λ_id 加入到总损失函数中。它在需要高颜色保真度的任务中特别有用,但并非在所有场景下都是必需的。

P82:CycleGAN 整体架构与损失函数详解 🧩

在本节课中,我们将学习如何将 CycleGAN 的各个组成部分整合起来,理解其完整的训练流程和损失函数构成。我们将重点关注两个生成器、两个判别器以及将它们联系在一起的多种损失项。

概述

CycleGAN 的核心思想是通过两个生成对抗网络(GAN)形成一个循环,实现两个不同域(例如马和斑马)之间的图像风格转换,而无需成对的训练数据。其成功的关键在于精心设计的损失函数。

整体架构与流程

上一节我们介绍了 CycleGAN 的基本组件,本节中我们来看看它们是如何协同工作的。

整个流程从一个域的真实图像开始。例如,我们输入一张真实的斑马图像。

这个图像首先被送入从斑马到马的生成器(记作 G_Z2H),该生成器会输出一张假的马图像。

对抗损失

接下来,这张假马图像和真实的马图像会一起被送入马的判别器(记作 D_H)。

判别器的任务是区分输入图像的真假,它会输出一个分类矩阵(或称 Patch),矩阵中的每个值代表对应图像块为“真”的程度。

CycleGAN 采用最小二乘对抗损失(Least Squares GAN Loss)来训练判别器和生成器。

以下是其工作原理:

  • 对于真实的图像,我们希望判别器的输出矩阵值全为 1。
  • 对于生成的假图像,我们希望判别器的输出矩阵值全为 0。

判别器的损失是促使它对真图输出 1,对假图输出 0。而生成器 G_Z2H 的对抗损失则是要“欺骗”判别器,使其对生成的假马图像也输出 1。

用公式表示,对于生成器 G 和判别器 D,对抗损失如下:

  • 判别器损失:L_D = (D(real) - 1)^2 + (D(fake))^2
  • 生成器损失:L_G_adv = (D(fake) - 1)^2

循环一致性损失

仅仅使用对抗损失可能导致模式崩溃或无意义的转换。为了确保转换只改变风格而不改变内容,CycleGAN 引入了循环一致性损失

除了对抗损失,我们还将上一步生成的假马图像,送入另一个生成器——从马到斑马的生成器(记作 G_H2Z)。

这个生成器会输出一张假的斑马图像。

循环一致性要求,这张重新生成的假斑马图像应该与最初输入的真实斑马图像在内容上保持一致。因此,我们计算两者之间的像素级差异(如 L1 损失)。

用公式表示,从斑马(Z)到马(H)再回到斑马的循环一致性损失为:
L_cyc_Z = || G_H2Z(G_Z2H(zebra)) - zebra ||_1

同理,反向过程(从马到斑马再回到马)也会计算一个对称的循环一致性损失。

L_cyc_H = || G_Z2H(G_H2Z(horse)) - horse ||_1

身份损失(可选)

为了进一步增强颜色和纹理的稳定性,CycleGAN 可以引入可选的身份损失

其思想是:如果一个斑马图像已经属于目标域(斑马域),那么通过从马到斑马的生成器 G_H2Z 后,它应该基本保持不变。

因此,我们将真实的斑马图像也输入 G_H2Z,得到输出,并计算输出与输入之间的像素差异作为身份损失。

用公式表示,斑马的身份损失为:
L_id_Z = || G_H2Z(zebra) - zebra ||_1

同样,对马图像和生成器 G_Z2H 也进行相同的操作。

L_id_H = || G_Z2H(horse) - horse ||_1

损失函数总结

现在,让我们将所有损失项汇总起来。CycleGAN 的巧妙之处在于,通过简单叠加这些直观的损失项,就能实现强大的无监督图像转换。

以下是生成器的总损失构成,共有六项:

  1. 对抗损失(两项):每个生成器对应一项,用于欺骗其对应的判别器。

    • G_Z2H 的对抗损失:L_adv_Z2H
    • G_H2Z 的对抗损失:L_adv_H2Z
  2. 循环一致性损失(两项):确保转换的可逆性。

    • 前向循环损失:L_cyc_Z
    • 后向循环损失:L_cyc_H

  1. 身份损失(两项,可选):稳定生成器的颜色和纹理。
    • G_H2Z 的身份损失:L_id_Z
    • G_Z2H 的身份损失:L_id_H

生成器的总损失是这些项的加权和:
L_G_total = L_adv_Z2H + L_adv_H2Z + λ_cyc * (L_cyc_Z + L_cyc_H) + λ_id * (L_id_Z + L_id_H)
其中 λ_cycλ_id 是超参数,用于平衡各项损失的重要性。

这个总损失函数同时用于优化两个生成器。

对于判别器,其任务则相对简单,每个判别器只负责一项最小二乘对抗损失:

  • 马的判别器 D_H 的损失:L_D_H
  • 斑马的判别器 D_Z 的损失:L_D_Z

总结

本节课中我们一起学习了 CycleGAN 的整体架构和损失函数。总结来说,CycleGAN 由两个GAN组成一个循环,它们相互依赖,通过计算多种损失项来学习无配对的域间映射。

生成器的损失包含六项:核心的最小二乘对抗损失、保证内容不变的循环一致性损失以及可选的身份损失

判别器的目标则相对单一,仅使用最小二乘对抗损失来提升自身的判别能力。

理解这些损失项如何共同作用,是掌握 CycleGAN 工作原理的关键。

P83:CycleGAN应用及变种 🎨➡️🦓

在本节课中,我们将学习CycleGAN的实际应用场景以及其重要的变体模型。我们将了解CycleGAN如何被用于艺术创作、医疗数据增强等领域,并探索UNIT和MUNIT这两种基于共享潜在空间假设的先进无监督图像翻译模型。


应用领域

上一节我们介绍了CycleGAN的基本原理,本节中我们来看看它在现实世界中的具体应用。

CycleGAN可以用于许多不同的事情。

以下是其主要应用方向:

  • 社交媒体滤镜:例如Snapchat上的各种滤镜,使人变老或改变性别感知。
  • 物体转换:例如将马变成斑马,并且能可靠地保持转换后物体(如斑马条纹)的特征。
  • 场景风格迁移:改变场景的季节,或将照片转换为特定的绘画风格(如莫奈风格),反之亦然。
  • 数据增强:在医疗等领域,CycleGAN是一种常用的数据增强技术。


医疗数据增强示例

现在,让我们深入了解CycleGAN在医疗数据增强中的具体作用。

找到同时包含肿瘤和未包含肿瘤的配对医学图像非常困难。这种预知能力目前可能无法实现,因此CycleGAN提供了一种数据增强的方法。

以下是CycleGAN在医疗图像处理中的两种应用:

  • 创造肿瘤:可以在健康图像上生成肿瘤,以模拟患病情况。
  • 消除肿瘤:可以从患病图像中移除肿瘤,以模拟健康情况。

这些生成的配对示例可用于下游任务,例如肿瘤分类、分割以及监测肿瘤生长,这在医疗应用中非常重要。

例如,使用CycleGAN可以移除CT扫描图像中的肿瘤大块,或者向图像中添加逼真的肿瘤。在数据增强中,像SegGAN这样的模型能够生成极其逼真的分割示例,其效果是标准数据增强方法无法达到的。


无监督图像翻译变体:UNIT

CycleGAN并不是唯一能够进行无配对图像翻译的模型。接下来,我们介绍一种重要的变体——UNIT。

有一种变体称为UNIT,它代表无监督图像到图像转换。无配对图像转换本身就是无监督的,因为你没有成对的图像标签。例如,实现白天与夜间驾驶场景的转换。

这个模型的关键洞察被称为共享潜在空间。其核心思想是,两个不同域的图像可以映射到同一个潜在空间中的向量。

我们可以用以下公式化描述:

  • 给定潜在空间中的一个噪声向量 z,生成器 G1 可以在域 X1 中生成图像:X1 = G1(z)
  • 同时,存在一个编码器 E1 可以将 X1 域的图像映射回潜在向量:z' = E1(X1)
  • 同样的潜在向量 z,也可以通过另一个生成器 G2 在域 X2 中生成图像:X2 = G2(z)
  • 并且,域 X2 的图像也能通过编码器 E2 映射回潜在空间。

你可以想象这两个域,X1 是白天的驾驶场景,X2 是夜间的驾驶场景。X1X2 共享相同的内容(即潜空间向量 z),但表现出不同的风格(白天或夜间)。模型可以学习在这两个风格之间来回映射。


多模态生成:MUNIT

UNIT模型的能力不仅限于单一风格的转换。它的一个扩展版本,称为多模态UNIT(MUNIT),能够实现更丰富的生成。

多模态的意思是从一个域的输入(如草图),可以生成第二个域的多种不同风格输出。MUNIT不仅能找到一个映射,还能发现并生成目标域的多种潜在模式。

这非常酷,因为你从未明确告诉模型关于所有不同的风格。例如,给定一个鞋子的草图,它能够自动找出所有不同的鞋类风格(如靴子、运动鞋、高跟鞋),并生成对应的多种图像。这一切都是在无监督的情况下完成的,模型自行发现了鞋子之间的风格差异。


技术背景与总结

最后,我们来总结一下本节课的核心内容。

需要快速说明的是,UNIT和MUNIT这两种技术都依赖于将图像编码到潜在空间(从变分自编码器VAE中获得灵感),同时使用GAN的组件来确保生成图像的真实性。

总结来说,CycleGAN的扩展模型包括UNIT和MUNIT,它们使用了共享潜在空间的假设。特别是MUNIT,实现了多模态生成,这非常强大。GAN,尤其是其变体,在艺术、医疗、视频和游戏等领域有大量应用。

本节课中,我们一起学习了CycleGAN的广泛应用、其在医疗数据增强中的价值,以及UNIT和MUNIT这两种基于共享潜在空间的无监督图像翻译模型。它们为图像生成和转换任务提供了更强大、更灵活的解决方案。

P9:PyTorch入门可选内容 🚀

在本节课中,我们将学习PyTorch这一流行的深度学习框架。课程将首先比较PyTorch与TensorFlow的主要区别,然后介绍如何使用PyTorch定义模型并进行训练。内容力求简单直白,适合初学者理解。

PyTorch与TensorFlow对比 🔄

PyTorch是由Facebook开发的深度学习框架,在本专业的一些笔记本中会使用到。如果你尚未使用过PyTorch,无需担心,你会发现它与其他框架(如TensorFlow)非常相似。在每个笔记本任务中,都会有提示帮助你使用PyTorch框架。

上一节我们介绍了课程概述,本节中我们来看看PyTorch与TensorFlow的核心区别。

PyTorch和TensorFlow可以说是目前最受欢迎的深度学习框架。如果你参加了深度学习专业,可能对TensorFlow很熟悉。但需要说明的是,我个人更喜欢PyTorch。

它们之间的主要区别在于计算方式:

  • 在PyTorch中,你在运行中进行计算,这种方式有时被称为命令式编程。例如,你有变量 a=1b=2,当你把它们相加时,会立即得到结果 3
  • 在TensorFlow中,你首先定义如何计算,之后再执行计算,这被称为象征性方法。例如,你定义 c = a + b,然后编译 c 并为其赋值以获取计算结果。

这使得PyTorch能够拥有动态计算图。这意味着你的神经网络可以在每次运行时轻松改变其结构。然而,由于TensorFlow的计算图是静态的,这些模型倾向于运行时间更短。在TensorFlow 2.0中,引入了急切执行模式,这与PyTorch的动态计算图非常相似。

总之,动态计算图在PyTorch中感觉更自然。目前,这些框架非常相似,你会发现从一个框架转换到另一个框架(特别是从TensorFlow到PyTorch)从未如此容易。

使用PyTorch定义模型 🏗️

上一节我们比较了PyTorch与TensorFlow,本节中我们来看看如何使用PyTorch定义模型。

首先,你需要导入PyTorch库。

import torch
import torch.nn as nn  # nn代表神经网络模块

在PyTorch中定义模型的常见方法是使用 nn.Module 的子类。以下是一个逻辑回归模型的示例:

class LogisticRegression(nn.Module):
    def __init__(self, input_size):
        super(LogisticRegression, self).__init__()
        self.logistic_regression = nn.Sequential(
            nn.Linear(input_size, 1),
            nn.Sigmoid()
        )
    
    def forward(self, x):
        return self.logistic_regression(x)

以下是代码关键部分的解释:

  • __init__ 方法是构造函数,用于定义模型的架构。这里使用 nn.Sequential 模块顺序地添加层:首先是一个线性层 (nn.Linear),然后是一个Sigmoid激活函数 (nn.Sigmoid)。
  • forward 方法定义了模型的前向传递过程,即给定输入 x 时,如何产生输出。它并不是指反向传播。

这是一个非常简单的概述,展示了如何在PyTorch中定义模型。当然,你也可以用不同的结构实现相同的结果。

使用PyTorch训练模型 🏋️‍♂️

上一节我们介绍了如何定义模型,本节中我们来看看如何训练这个模型。

为了训练模型,你需要遵循以下步骤:

首先,初始化模型实例、定义成本函数(在PyTorch中常称为criterion)并选择优化器。

# 1. 初始化模型
model = LogisticRegression(input_size=16)

![](https://github.com/OpenDocCN/dsai-notes-zh/raw/master/docs/dlai25/img/cfd4115b4dabb63861ce5852d90dfad6_84.png)

![](https://github.com/OpenDocCN/dsai-notes-zh/raw/master/docs/dlai25/img/cfd4115b4dabb63861ce5852d90dfad6_86.png)

# 2. 定义成本函数(准则)
criterion = nn.BCELoss()  # 二元交叉熵损失

![](https://github.com/OpenDocCN/dsai-notes-zh/raw/master/docs/dlai25/img/cfd4115b4dabb63861ce5852d90dfad6_88.png)

![](https://github.com/OpenDocCN/dsai-notes-zh/raw/master/docs/dlai25/img/cfd4115b4dabb63861ce5852d90dfad6_90.png)

# 3. 选择优化器(例如随机梯度下降)
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)

然后,你可以开始训练循环。以下是训练循环的基本结构:

num_epochs = 100
for epoch in range(num_epochs):
    # 前向传递:获取预测
    predictions = model(inputs)
    
    # 计算损失
    loss = criterion(predictions, labels)
    
    # 反向传播与优化
    optimizer.zero_grad()  # 清零梯度
    loss.backward()        # 反向传播,计算梯度
    optimizer.step()       # 更新模型参数

以下是训练循环中关键步骤的说明:

  • optimizer.zero_grad():在每次反向传播前清零梯度,这是重要的一步。
  • loss.backward():执行反向传播,计算损失相对于模型参数的梯度。
  • optimizer.step():优化器根据计算出的梯度和学习率更新模型参数。

你无需过分担心这里的确切语法,但需要理解这个基本流程:前向计算预测、计算损失、反向传播梯度、优化器更新参数。

总结 📝

本节课中我们一起学习了PyTorch的基础知识。

我们首先了解了PyTorch与TensorFlow的主要区别:PyTorch采用动态计算图和命令式编程,计算在运行时进行;而TensorFlow传统上采用静态计算图。这使得PyTorch在模型调试和动态结构变化上更灵活。

接着,我们学习了如何使用PyTorch定义模型,即通过创建 nn.Module 的子类,并在其中定义 __init__forward 方法。

最后,我们介绍了训练PyTorch模型的基本流程:初始化模型、定义损失函数和优化器,然后在循环中执行前向传播、计算损失、反向传播和参数更新。

总之,PyTorch因其动态性和易用性而受到许多研究者和开发者的青睐。但正如本课所示,它与其他深度学习框架(如TensorFlow)在核心概念上非常相似,掌握其中一个后,切换到另一个并不困难。

posted @ 2026-02-03 19:58  绝不原创的飞龙  阅读(18)  评论(0)    收藏  举报