Skip to content

Auto-Encoder

约 857 个字 35 行代码 5 张图片 预计阅读时间 3 分钟

一、核心思想:逐层预训练与微调

自动编码器被提出来解决神经网络的参数初始化问题。假设我们的目标是训练一个从输入\(X\)到输出\(Y\)的多层深度神经网络:

|500

传统的训练方法是随机初始化所有层的参数,然后使用反向传播(Backpropagation, BP)算法在有标签数据上端到端地训练整个网络。但对于深度网络,这种方法容易陷入局部最优解,导致性能不佳。

自动编码器采用了一种分为两步的策略:无监督预训练有监督微调

第一步:逐层无监督预训练 (Layer-wise Unsupervised Pre-training)

这一步的目标是为网络的每一层找到一个好的初始参数,使其能够提取数据中的有效特征。这个过程是逐层进行的,并且是无监督的(即不需要数据标签\(Y\))。

  • 训练第1层:
    我们首先只训练第一层。构建一个简单的神经网络,它的输入是原始数据\(X\),目标输出也是\(X\)。这个网络被称为自动编码器,它试图学习一个恒等函数,即重构输入。通过反向传播算法训练这一层,使其能够从\(X\)中学习到一个压缩表示,并能从该表示中恢复出\(X\)

|307

  • 训练第2层:
    当第1层训练完毕后,我们固定住第1层的参数。然后,将原始数据\(X\)通过训练好的第1层,得到输出\(X_1\)。接着,我们训练第2层,构建一个新的自动编码器,其输入是\(X_1\),目标输出也是\(X_1\)

    $$ X \xrightarrow{\text{Encoder (Layer 1)}} X_1 \xrightarrow{\text{Decoder}} X' $$

Tip

把自动编码器想象成一个文件压缩/解压工具:

  • 编码器 (Encoder) 就像是 压缩程序 (ZIP):它接收一个大文件 (输入 \(X\)),并生成一个小的压缩文件 (隐藏表示 \(X_1\))。
  • 解码器 (Decoder) 就像是 解压程序 (UNZIP):它接收压缩文件 (\(X_1\)),并尝试恢复出原始的大文件 (重构输出 \(X'\))。

|450

  • 以此类推,训练第M层:
    重复以上步骤,直到所有中间层(例如从第1层到第M-1层)都训练完毕。在训练第M层时,我们会固定住前面所有层的参数,用第M-1层的输出来训练第M层,使其能够重构自身的输入。

|500

通过这个过程,网络的每一层都学习到了如何提取前一层输出的有效特征。这为整个网络提供了一个远比随机初始化好得多的参数初始状态。

第二步:全局有监督微调 (Supervised Fine-tuning)

在所有层都经过预训练之后,我们将这些预训练好的层堆叠起来,并在网络的顶端加上最终的输出层(用于分类或回归等特定任务)。

然后,我们使用带标签的数据(即输入\(X\)和目标输出\(Y\)),通过标准的反向传播算法来同时调整整个网络的所有参数。这个过程被称为“微调”,它在预训练找到的良好初始值基础上,对整个模型进行优化,以适应最终的监督学习任务。

3. 伪代码逻辑解析

function dnn = dnn_train(dnn, train_x, train_y)
for k = 1 : numel(dnn.size)-2
    sae = sae_create([dnn.size(k), dnn.size(k+1)]);   
    sae = sae_train(sae, option, train_x);            
    dnn.W{k} = sae.W{1};                              
    dnn.b{k} = sae.b{1};                              
    sae = nn_predict(sae, train_x);                   
    train_x = sae.a{2}';                              
end
k = k + 1;
nn = nn_create([dnn.size(k), dnn.size(k+1)]);
nn = nn_train(nn, option, train_x, train_y);
dnn.W{k} = nn.W{1};
dnn.b{k} = nn.b{1};
end
function sae = sae_create(SIZE)
    sae = nn_create([SIZE(1),SIZE(2),SIZE(1)]);
end

function sae = sae_train(sae,option,train_x)
    sae.encoder = 1;
    sae = nn_train(sae,option,train_x,train_x);
end
function dnn = dnn_adjust(dnn,train_x,train_y)
    ...参数设置...()
    for k = 1 : iteration
        kk = randperm(m);
        for l = 1 : num_batches
            batch_x = train_x(kk((l-1)*batch_size+1 : l*batch_size), :);
            batch_y = train_y(kk((l-1)*batch_size+1 : l*batch_size), :);
            dnn = nn_forward(dnn,batch_x,batch_y);
            dnn = nn_backpropagation(dnn,batch_y);
            dnn = nn_applygradient(dnn);
        end
end

Comments