准备构建用于特征提取的自编码器时,回顾神经网络的基本构成元素很有帮助。自编码器本质上是一种特定类型的神经网络,其效能取决于这些相同部件共同发挥作用。本次回顾将确保我们在研究自编码器架构具体内容前,具备一致的认识。层:网络的结构可以把层看作神经网络中的主要组织单元。数据流经这些层,并在每一步进行转换。在典型的全连接网络中(这是简单自编码器的基础),我们遇到三种主要的层类型:输入层:这是过程的起点。输入层接收原始数据,无论是图像的像素值、表格中的数值特征,还是文本中的词嵌入。输入层中的每个神经元(或单元)通常对应输入数据的一个特征。它不执行任何计算;它只是将数据传递给第一个隐藏层。隐藏层:隐藏层位于输入层和输出层之间,是大部分计算和学习发生的地方。隐藏层中的每个神经元接收来自前一层所有神经元的输入(在全连接或密集层中),对这些输入应用加权和,添加一个偏置,然后将结果通过激活函数。网络可以有一个或多个隐藏层。更深的网络(更多隐藏层)可以学习更复杂的模式。在自编码器中,“编码器”部分的隐藏层逐步将输入数据压缩成低维表示,而“解码器”部分的隐藏层则从这种压缩形式重建原始数据。输出层:这是产生网络预测或输出的最后一层。输出层中使用的神经元数量和激活函数取决于具体任务。对于自编码器,输出层旨在重建原始输入,因此其大小通常与输入层的大小匹配。对于分类任务,它可能每个类别有一个神经元。以下是一个简单图表,呈现了前馈神经网络中的这些层:digraph G { rankdir=TB; splines=line; node [shape=circle, style=filled, margin=0.1, width=0.6, height=0.6, fontname="Arial", fontsize=10]; edge [fontname="Arial", fontsize=9]; subgraph cluster_input { label = "输入层"; bgcolor="#e9ecef"; style=filled; i1 [label="x₁", fillcolor="#a5d8ff"]; i2 [label="x₂", fillcolor="#a5d8ff"]; i3 [label="...", fillcolor="#a5d8ff"]; i4 [label="xₙ", fillcolor="#a5d8ff"]; } subgraph cluster_hidden1 { label = "隐藏层 1"; bgcolor="#dee2e6"; style=filled; h1_1 [label="h₁₁", fillcolor="#74c0fc"]; h1_2 [label="h₁₂", fillcolor="#74c0fc"]; h1_3 [label="...", fillcolor="#74c0fc"]; h1_4 [label="h₁ₘ", fillcolor="#74c0fc"]; } subgraph cluster_output { label = "输出层"; bgcolor="#e9ecef"; style=filled; o1 [label="ŷ₁", fillcolor="#a5d8ff"]; o2 [label="ŷ₂", fillcolor="#a5d8ff"]; o3 [label="...", fillcolor="#a5d8ff"]; o4 [label="ŷₖ", fillcolor="#a5d8ff"]; } {rank=same; i1; i2; i3; i4;} {rank=same; h1_1; h1_2; h1_3; h1_4;} {rank=same; o1; o2; o3; o4;} i1 -> h1_1; i1 -> h1_2; i1 -> h1_4; i2 -> h1_1; i2 -> h1_2; i2 -> h1_4; i4 -> h1_1; i4 -> h1_2; i4 -> h1_4; h1_1 -> o1; h1_1 -> o2; h1_1 -> o4; h1_2 -> o1; h1_2 -> o2; h1_2 -> o4; h1_4 -> o1; h1_4 -> o2; h1_4 -> o4; }一个具有输入层、隐藏层和输出层的基本前馈神经网络结构。数据从上到下流动。在基本神经网络和简单自编码器中,你最常遇到的是全连接层(或密集层)。在全连接层中,每个神经元都连接到前一层中的每个神经元。激活函数:引入非线性如果神经网络仅由线性操作(如加权和)构成,即使是多层堆叠也只会表现得像一个单一的线性层。这将严重限制网络对数据中复杂关系的建模能力。激活函数是解决之道。它们将非线性引入网络,使其能够学习更精细的模式。激活函数接收神经元的输入加权和与偏置(通常称为预激活值或逻辑值),并将其转换为神经元的输出(或激活值)。$$ \text{激活值} = f(\sum_{j} (w_j \cdot x_j) + b) $$其中 $f$ 是激活函数,$w_j$ 是权重,$x_j$ 是输入,$b$ 是偏置。常用激活函数包括:Sigmoid: $$ \sigma(z) = \frac{1}{1 + e^{-z}} $$ Sigmoid 函数将其输入压缩到 0 到 1 之间。它常用于二元分类问题的输出层,或在像素值归一化到 0 到 1 之间的自编码器中。然而,它在深层网络中可能面临“梯度消失”问题,导致梯度变得非常小,减缓学习速度。双曲正切 (Tanh): $$ \tanh(z) = \frac{e^z - e^{-z}}{e^z + e^{-z}} $$ Tanh 与 Sigmoid 相似,但将值压缩到 -1 到 1 之间。它也是 S 形的,并可能面临梯度消失问题,但其零中心输出有时有助于训练收敛,相较于 Sigmoid。修正线性单元 (ReLU): $$ \text{ReLU}(z) = \max(0, z) $$ ReLU 是目前最受欢迎的激活函数之一。如果输入为正,它直接输出输入值,否则输出零。它计算效率高,有助于缓解正输入下的梯度消失问题。一个潜在的问题是“死亡 ReLU”问题,即如果神经元的输入始终为负,它们可能变得不活跃。诸如 Leaky ReLU 或 Parametric ReLU (PReLU) 等变体通过在单元不活跃时允许一个小的非零梯度来解决此问题。Softmax:尽管 Softmax 常与激活函数一同讨论,但它通常用于多类别分类网络的输出层。它将原始分数向量(逻辑值)转换为概率分布,其中每个值都在 0 到 1 之间,所有值的和为 1。激活函数的选择很重要。对于自编码器中的隐藏层,ReLU 通常是一个不错的起点,因为它效率高且能够对抗梯度消失。输出层的激活将取决于待重建输入数据的性质(例如,对于归一化到 [0,1] 的输入使用 Sigmoid,对于无界输入使用线性激活)。损失函数:衡量模型表现我们如何判断神经网络是否在有效学习?这就是损失函数(也称为代价函数或目标函数)的作用所在。损失函数量化了网络预测与实际目标值之间的差异。训练神经网络的目标是调整其权重和偏置,以使这种损失最小化。损失函数的选择取决于具体任务:均方误差 (MSE):常用于回归任务,目标是预测连续值。它也是自编码器的标准选择,网络尝试重建其输入。MSE 衡量原始输入 $x_i$ 和重建输出 $\hat{x}i$ 之间的平均平方差。 $$ L{MSE} = \frac{1}{N} \sum_{i=1}^{N} (x_i - \hat{x}_i)^2 $$ $N$ 代表数据点数量(如果进行重建,则是单个数据样本中的特征数量)。更低的 MSE 表示自编码器具有更好的重建质量。二元交叉熵:用于输出为概率(例如,预测两个类别之一)的二元分类问题。 $$ L_{BCE} = -\frac{1}{N} \sum_{i=1}^{N} [y_i \log(\hat{y}_i) + (1-y_i) \log(1-\hat{y}_i)] $$ 这里,$y_i$ 是真实标签(0 或 1),$\hat{y}_i$ 是类别 1 的预测概率。类别交叉熵:用于多类别分类问题,其中每个输入属于 $C$ 个类别之一。它通常与输出层中的 Softmax 激活一同使用。对于自编码器,由于主要任务是尽可能准确地重建输入,MSE 是处理连续输入数据(如图像像素强度或归一化数值特征)时非常常用的损失函数。如果输入数据是二元的(例如,黑白图像),则可能按像素使用二元交叉熵。优化器:指导学习过程一旦我们有了一个损失函数,能够告诉我们网络表现如何(好或差),我们就需要一种机制来更新网络的参数(权重 $w$ 和偏置 $b$),以减少这种损失。这就是优化器的任务。优化器使用损失函数相对于网络参数的梯度(通过一个称为反向传播的算法计算)来引导更新。把它想象成试图找到山谷底部,山谷的高度就是损失。优化器沿着最陡峭的下降方向迈步。优化器的重要方面包括:学习率:这可能是优化器最重要的超参数。它决定了优化过程中所迈步长的大小。学习率过小可能导致收敛非常缓慢,而学习率过大则可能导致优化器越过最小值,无法收敛,甚至发散。 $$ w_{new} = w_{old} - \eta \cdot \nabla_w L $$ 这里,$\eta$ (eta) 是学习率,$\nabla_w L$ 是损失 $L$ 对权重 $w$ 的梯度。常用优化器包括:随机梯度下降 (SGD):这是一种基本的优化算法。与使用整个数据集计算梯度(批量梯度下降)不同,SGD 使用单个训练样本或一小批样本的梯度来更新参数。这使得更新更频繁,并有助于逃离局部最小值。变体通常包含动量项,这有助于在相关方向上加速 SGD 并抑制振荡。Adam(自适应矩估计):Adam 是一种流行且有效的优化器。它通过跟踪过去梯度的指数衰减平均值(一阶矩,类似于动量)和过去平方梯度的指数衰减平均值(二阶矩,类似于 AdaDelta 或 RMSProp)来计算每个参数的自适应学习率。它通常被认为是稳定的,在广泛的问题上表现良好,常作为良好的默认选择。RMSprop(均方根传播):该优化器也为每个权重维护一个平方梯度的移动平均值,并用该平均值的根来除学习率。这有助于调整每个参数的学习率。Adagrad(自适应梯度算法):Adagrad 根据参数调整学习率,对与频繁出现特征相关的参数进行较小的更新,对与不频繁特征相关的参数进行较大的更新。它通常对稀疏数据表现良好。优化器的选择及其配置(尤其是学习率)会明显影响自编码器的训练速度和最终表现。通常需要进行实验才能找到给定问题的最佳组合。随着对这些核心组件的重新熟悉,我们能更好地理解它们如何组合成自编码器,以及这些网络如何从数据中学习并提取有意义的特征。自编码器的编码器、解码器和瓶颈层都是根据这些关于层和激活的原则构建的,并使用特定的损失函数和优化器进行训练。