Part V · 第 18 章 无监督与自监督学习 · 18.2

自编码器 (Autoencoder)

机器人相机一帧有几十万个数,可场景真正在变的往往只有几个量:物块在哪、夹爪张开多少。自编码器让一个网络把输入压缩成很短的编码,再从编码把输入还原出来,训练目标就是输入本身,不需要任何标签。线性的自编码器恰好学到 PCA 的子空间;非线性的能沿着弯曲的数据流形压缩,用 2 个数做到 PCA 要十几个主成分才能做到的事。本节在浏览器里现场训练六个小网络,看它们怎样压缩、去噪、在哪里失败,以及为什么“编码好”不等于“能生成”,也不等于“能拿来控制”。

约 40 分钟 前置:18.1 聚类与 PCA · 16.3 反向传播 · 1.12 SVD · 4.6 MLE 6 个交互

    1为什么机器人需要它

    一台 640×480 的彩色相机,每帧给出 921 600 个数。把这样的向量直接交给控制器或强化学习算法,几乎学不动:输入维度巨大,相邻像素高度相关,而决定任务的量(物体位置、姿态、夹爪开合)只有几个。我们希望先把观测压成一个短向量 \(\mathbf z\),让它保留“场景处在什么状态”,丢掉其余的东西,再在 \(\mathbf z\) 上做规划、学策略、检测异常。

    18.1 节的 PCA 已经是一种压缩:找一个 \(k\) 维线性子空间,使数据投影上去之后丢掉的方差最少。但 PCA 只会用平直的子空间。一个圆盘在桌面上平移,这些图像构成一张只有 2 个自由度的“曲面”,可它在像素空间里弯得厉害:圆盘挪开一个直径,新旧两张图几乎不重叠,彼此近似正交。用平面去贴这种曲面,需要很多维。

    自编码器(autoencoder,AE)是 PCA 的非线性推广:一个编码器网络 \(f_\phi\) 把 \(\mathbf x\) 映成短编码 \(\mathbf z\),一个解码器网络 \(g_\theta\) 再把 \(\mathbf z\) 还原成 \(\hat{\mathbf x}\),用 16.3 节的反向传播一起训练,目标是让 \(\hat{\mathbf x}\) 尽量接近 \(\mathbf x\)。标签就是输入本身,所以它是自监督的:机器人随手录下的视频就是训练数据。它也是本章后面几种方法的起点:VAE(19.1 节)给编码加上概率解释,使它能生成;对比学习(18.3 节)和 Masked Modeling / JEPA(18.4 节)换掉“逐像素还原”这个目标;去噪自编码器则直接通向扩散模型(19.6 节)。

    2直觉:从一个窄口挤过去

    自编码器的结构像一个沙漏:宽的输入,窄的中间,宽的输出。

    $$ \hl{z}{\mathbf z}=\hl{enc}{f_\phi}(\mathbf x)\in\R^{k},\qquad \hl{rec}{\hat{\mathbf x}}=\hl{dec}{g_\theta}(\mathbf z)\in\R^{D},\qquad k\ll D,\qquad \min_{\phi,\theta}\ \frac1N\sum_{i=1}^{N}\big\|\mathbf x_i-g_\theta(f_\phi(\mathbf x_i))\big\|^2 $$

    中间那层叫瓶颈(bottleneck),它的输出 \(\mathbf z\) 叫编码或隐变量(latent code)。如果 \(k\ge D\),网络只要学会“原样照抄”就能把误差降到零,什么也没学到;正是因为 \(k\) 很小,网络被迫找出数据里最省字数的描述方式。如果数据点其实都落在一条曲线上,一个数(沿曲线走了多远)就够了。

    下面是最小的例子:机器人示教时夹爪在桌面上走过的一条弯曲路径,160 个二维位置(单位 m,带 3 cm 噪声)。编码器是 2→24→1 的小网络(tanh),解码器是 1→24→2。PCA 只能用一条直线来表示一维结构;自编码器的解码器 \(\hl{dec}{g_\theta}\) 把整条一维的“编码轴”弯成一条曲线,训练就是让这条曲线去贴合数据。

    FIG 1一维瓶颈:把弯曲的夹爪路径压成一个数
    左:数据点按它的编码 \(z\) 着色(红 = 编码最小,蓝 = 编码最大);琥珀色曲线是解码器 \(g_\theta(z)\) 在整个编码范围上画出的曲线,琥珀色小点是每个点的重建 \(\hat{\mathbf x}\),细线连接点和它的重建;绿色虚线是 PCA 的第一主方向(最好的一维直线)。滑块“编码 z”在编码范围内移动,琥珀色圆环是 \(g_\theta(z)\)。右:每个坐标的均方重建误差(对数坐标),琥珀色为自编码器,绿色虚线为 PCA-1,灰色点线是 3 cm 噪声决定的下限 \(\sigma^2/2\)。
    试一试
    • 在“弧线”数据上按“训练”:几百步之内,自编码器的误差降到 PCA-1 的十分之一以下(读数里的“AE / PCA”小于 0.1)。再拖“编码 z”滑块,看琥珀色圆环沿着路径从红端走到蓝端。
    • 换成“闭合圆”并训练,直到“AE / PCA”低于 0.3(大约 2000 步,前一千多步会停在 1 附近)。颜色在圆上某处从红直接跳到蓝:一个连续的数无法不重不漏地给一个圆编号,网络只能在那里“剪开”。

    在弧线上,默认种子大约 300 步时误差约为 PCA 的 11%,1000 步时约 5%,最后停在 3% 到 4% 左右,已经接近噪声下限(约 PCA 的 2%):剩下的误差基本是垂直于路径的噪声,任何一维描述都去不掉。S 形曲线更有意思:前一千步左右误差一直停在 PCA 的水平(解码器还是一条直线),然后突然下降到约 8%。这种“平台期再突降”在训练自编码器时很常见,不要过早判断它学不会。

    核心洞见

    瓶颈逼着网络学会数据的“坐标系”:编码器给每个点在数据流形上的一个坐标,解码器把坐标还原成点。PCA 的坐标轴是直的,自编码器的可以是弯的。但这个坐标只为“还原得好”而设计,没有任何东西要求它光滑、均匀或有意义:圆上的剪口就是第一个警告。

    3动手:压缩机器人相机的图像

    现在换成真正的高维输入。俯视相机看着桌上的一个圆盘(半径 1.8 像素,边缘有 1 像素的过渡),图像只有 12×12 = 144 个像素。圆盘的位置 \((p_x,p_y)\) 是唯一在变的量,所以这些图像构成像素空间 \(\R^{144}\) 里的一张二维曲面。训练集是 300 张随机位置的图,另有 60 张测试图只用来评估。

    自编码器是 144→32→\(K\)→32→144(tanh 隐层,sigmoid 输出把像素限制在 0 到 1),用 Adam、每批 16 张训练。对照组是同一训练集上的 PCA:保留前 \(k\) 个主成分再重建。两者的误差都是测试图上每个像素的均方误差。

    FIG 22 个数 vs 十几个主成分:圆盘图像的自编码器
    左:6 张测试图(每列一张,窄屏上只显示 4 张)。第一行是输入,第二行是自编码器的重建(编码 \(K\) 个数),第三行是 PCA 保留 \(k\) 个主成分的重建;像素亮度画成青色的不透明度(越不透明越亮),PCA 重建里小于 0 的像素画成红色。右:测试误差(对数坐标),琥珀色为自编码器,绿色虚线为 PCA-\(k\)(它不需要训练,是一条水平线)。改变 \(K\) 会重新开始训练。
    • 保持 \(K=2\)、PCA \(k=2\),按“训练”:自编码器的测试误差降到 PCA-2 的三分之一以下(大约 1500 到 2000 步)。比较第二行和第三行:PCA-2 只能给出位置大致对的一团模糊,自编码器给出一个清晰的圆盘。
    • 自编码器的测试误差低于 0.01 之后,把 PCA 的 \(k\) 往上拖,直到 PCA 的测试误差不高于自编码器的。PCA 需要多少个主成分才追上 2 个数?

    按默认种子,3000 步后 \(K=2\) 的测试误差约 0.0073,而 PCA 要用约 13 个主成分(0.0068)才能做到,PCA-2 是 0.0363,只解释了训练集 31% 的方差。原因正是第 1 节说的:圆盘在不同位置的图像彼此几乎不重叠,像素空间里的这张曲面“卷曲”得厉害,任何平面都贴不住它。

    还有一个反直觉的现象:再试 \(K=1\)、\(4\)、\(8\)。\(K=1\) 当然不够(4000 步后测试误差仍约 0.019),但 \(K=4\) 在 3000 步时只有约 0.0008,比 \(K=2\) 低一个数量级,虽然数据只有 2 个自由度。理论上 2 个数足够,可是要把一张二维曲面无折叠地摊平到二维编码上,优化很难找到;多给几维,网络可以用“弯着放”的编码绕开这个困难。FIG 4 会看到 \(K=2\) 的编码里确实有折痕。

    核心洞见

    PCA 按“方差”压缩,自编码器按“自由度”压缩。当数据是少数几个物理量的非线性函数(相机图像几乎总是这样),两者的差距可以是一个数量级。但能达到的编码长度和容易训练出来的编码长度是两回事:瓶颈略宽于真实自由度,往往训练得更好。

    4另外三个视角:线性情形、隐空间、去噪

    线性自编码器学到的就是 PCA 子空间

    去掉所有非线性,自编码器还剩什么?编码器变成一个矩阵 \(E\)(加偏置),解码器变成矩阵 \(W\)(加偏置),重建 \(\hat{\mathbf x}=W E\mathbf x+\mathbf c\) 必然落在 \(W\) 的列空间(平移到某一点)里。第 5 节会证明:只要第 \(k\) 和第 \(k+1\) 个特征值不相等,平方误差的最优解里 \(W\) 的列空间就是前 \(k\) 个主方向张成的子空间,误差恰好等于 PCA-\(k\) 的误差。下面的例子是两个手指关节的角度(单位 rad):它们倾向于一起弯曲,所以数据沿一条斜线分布,就像 18.1 节的“协同”(synergy)。线性自编码器 2→1→2 用 Adam 从随机初值开始训练。

    FIG 3线性自编码器收敛到 PCA 的子空间,但基不唯一
    横轴、纵轴是两个关节角(rad)。紫点是 200 个数据点;拖紫色圆环改变数据的主方向和长轴(圆环在长轴方向 2 个标准差处);滑块调短轴的标准差。绿色虚线是 PCA 第一主方向,琥珀色直线是解码器能输出的所有点 \(W z+\mathbf c\)(\(W\) 是一个二维列向量),琥珀色小点是重建;红色箭头是编码器的行向量 \(E\)(\(z=E\mathbf x+b\))。右侧读数:两条线的夹角、误差与 PCA-1 之比、\(E W\) 以及 \(\|W\|\);下方比较 \(W E\) 和 PCA 的投影矩阵 \(\mathbf u_1\mathbf u_1^\top\)。
    • 按“训练”:琥珀色直线转到绿色虚线上,夹角小于 1°,误差与 PCA-1 之比在 1.00 ± 0.01 之内(一两百步)。此时 \(E W\approx1\),\(W E\) 与 \(\mathbf u_1\mathbf u_1^\top\) 一致。
    • 收敛之后(夹角小于 1°)按“编码 ×2”:编码器乘 2、解码器除以 2,\(\|W\|\) 减半,误差一点都不变。再按“重置”换一个随机初值重新训练:收敛后的 \(\|W\|\) 也不同。线性自编码器只确定子空间,不确定子空间里的坐标。

    隐空间:编码之间的空隙与折痕

    既然解码器能把编码变回图像,能不能随便挑一个编码,“生成”一张没见过的图?下图把 FIG 2 训练出的模型的隐空间画出来(两者共用同一个模型,在哪个图里训练都行)。\(K=2\) 时每张训练图的编码是平面上的一个点;\(K>2\) 时画的是编码的前两维,其余维固定在训练编码的平均值。拖动琥珀色手柄选择一个编码,右侧显示它解码出的图像,以及这张图离“某个真实圆盘图像”有多远:在所有圆盘位置里找最接近的那张,算每像素的均方误差,小于 0.01 判为“像一个圆盘”。

    FIG 4隐空间:编码不是一个可以随手采样的分布
    左:每个小点是一张训练图的编码,按圆盘的 \(p_x\) 着色(紫 = 圆盘在左,青 = 在右),或切换成按 \(p_y\) 着色(琥珀 = 在上,蓝 = 在下)。“画出解码器地图”把可见区域分成小格,逐格解码并上色:绿色格解码成圆盘,红色格不是(地图只对当前模型有效,继续训练后会隐藏)。右:琥珀色手柄处编码的解码图像,像素亮度画成青色的不透明度。下:从按每一维拟合到训练编码上的高斯分布里采样 16 个编码并解码,绿框 = 像一个圆盘,红框 = 不像。
    • 在 \(K=2\)、测试误差低于 0.015 的模型上,按“画出解码器地图”,再把琥珀色手柄拖进一个远离所有训练编码的红色区域(离最近训练编码的距离超过编码范围的 8%),使解码图不像圆盘(误差大于 0.01)。
    • 在 FIG 2 里选 \(K=8\) 并训练到测试误差低于 0.003(重建几乎完美),然后在这里按“采样 16 个编码”至少两次:累计下来像圆盘的不到一半。

    按默认设置训练 3000 步后,我们在 node 里用同样的代码各采了 200 个编码:\(K=2\) 时约 86% 解码成圆盘,\(K=8\) 时只有约 37%;而测试图的重建在两种情况下都 100% 合格。\(K=8\) 的重建误差更低,采样反而更差:训练编码只占据 8 维空间里一张薄薄的二维“片”,按每一维独立的高斯去采,几乎总是落在片外,那里的解码器从没被训练过。即使在 \(K=2\) 时,解码器地图里也能看到远离数据的大片红区,以及数据区内部细长的红色折痕。

    核心洞见

    普通自编码器只要求“编码能被还原”,对编码在隐空间里怎么分布没有任何约束:没有先验,不知道该从哪里采样,空隙处的解码结果没有保证。要能生成,就得让训练同时规定编码的分布,这正是 19.1 节 VAE 做的事:编码器输出一个分布,再用 KL 项把它拉向标准正态。

    去噪自编码器:学会回到数据上

    真实相机有噪声。去噪自编码器(denoising AE,DAE)的改动只有一处:输入换成被破坏的版本 \(\hl{noise}{\tilde{\mathbf x}}=\mathbf x+\sigma\boldsymbol\varepsilon\),目标仍是干净的 \(\mathbf x\)。网络没法再“照抄输入”,只能学会把偏离数据流形的点推回流形上。下面两个网络结构完全相同(144→32→144,没有窄瓶颈),同时训练:一个用干净输入(普通 AE),一个用加噪输入(DAE),都在带同样噪声的测试图上评估。

    FIG 5普通自编码器 vs 去噪自编码器
    左:6 张测试图(窄屏上 4 张),自上而下为干净图、加噪输入 \(\tilde{\mathbf x}\)(噪声标准差 σ,超出 0 到 1 的值截断显示)、普通 AE 的输出、DAE 的输出;像素亮度画成青色的不透明度。右:在加噪测试图上、输出与干净图之间的每像素均方误差(对数坐标):琥珀色为普通 AE,蓝色为 DAE,紫色虚线是什么都不做(直接输出 \(\tilde{\mathbf x}\))的误差。改变 σ 会从头训练两个网络。
    • σ = 0.3 时训练 600 步以上:DAE 在加噪测试图上的误差降到普通 AE 的一半以下。再看读数里“干净输入”的误差:普通 AE 在干净图上反而更好。

    默认 σ = 0.3 时,什么都不做的误差是 0.091;1000 步后普通 AE 是 0.014,DAE 是 0.0043,约为前者的三分之一。普通 AE 也去掉了不少噪声,因为 32 维的隐层本身就是一个约束;但它从没见过噪声,噪声中“看起来像圆盘边缘”的部分被原样保留。代价是 DAE 在干净输入上略差(约 0.0012 对普通 AE 的 0.0003):它学的是“输入多半带噪,要往数据上收”,对干净图也会收一点。σ 越大,两者差距越大:σ = 0.5 时 2000 步后约 0.040 对 0.010。

    核心洞见

    去噪不需要窄瓶颈:“从破坏中恢复”这个任务本身就逼网络学到数据的结构。DAE 的输出减去输入,指向数据更密集的方向(第 5 节:它正比于加噪后数据密度的对数梯度,即 score)。把这个想法推到底,在很多个噪声水平上训练去噪器,再一步步去噪,就是扩散模型(19.6 节)。

    5数学

    提示:把鼠标悬停在公式中带底色的符号上,图中对应的元素会被高亮(FIG 1 的编码颜色、解码器曲线、编码圆环和重建点,FIG 3 的两条直线,FIG 5 的加噪输入行,FIG 6 的距离曲线)。

    目标函数与梯度

    给定数据 \(\mathbf x_1,\dots,\mathbf x_N\in\R^D\),编码器 \(f_\phi:\R^D\to\R^k\),解码器 \(g_\theta:\R^k\to\R^D\),训练最小化重建损失

    $$ \mathcal L(\phi,\theta)=\frac1N\sum_{i=1}^{N}\ell\big(\mathbf x_i,\ \hl{rec}{\hat{\mathbf x}_i}\big),\qquad \hat{\mathbf x}_i=\hl{dec}{g_\theta}\big(\hl{enc}{f_\phi}(\mathbf x_i)\big),\qquad \ell(\mathbf x,\hat{\mathbf x})=\frac1D\|\mathbf x-\hat{\mathbf x}\|^2 $$

    本页所有误差都是这个“每个分量的均方误差”。选平方误差等价于假设 \(\mathbf x=\hat{\mathbf x}+\)高斯噪声,再做最大似然(4.6 节);像素在 0 到 1 之间、接近二值的图像,也常用逐像素的二元交叉熵(伯努利似然)。梯度就是两段网络串起来的反向传播(16.3 节):先把 \(\nabla_{\hat{\mathbf x}}\ell\) 反传过解码器,得到参数梯度和对编码的梯度 \(\partial\ell/\partial\mathbf z\),再把 \(\partial\ell/\partial\mathbf z\) 反传过编码器:

    $$ \frac{\partial\ell}{\partial\theta}=\Big(\frac{\partial\hat{\mathbf x}}{\partial\theta}\Big)^{\!\top}\nabla_{\hat{\mathbf x}}\ell,\qquad \frac{\partial\ell}{\partial\mathbf z}=\Big(\frac{\partial\hat{\mathbf x}}{\partial\mathbf z}\Big)^{\!\top}\nabla_{\hat{\mathbf x}}\ell,\qquad \frac{\partial\ell}{\partial\phi}=\Big(\frac{\partial\mathbf z}{\partial\phi}\Big)^{\!\top}\frac{\partial\ell}{\partial\mathbf z} $$

    每一项都是 16.3 节的向量–雅可比积,代价约为一次前向传播的几倍。页面里的代码正是这样写的:解码器的 backward 返回 \(\partial\ell/\partial\mathbf z\),再交给编码器的 backward。

    线性自编码器 = PCA 子空间

    设数据已中心化(偏置的最优值恰好做这件事),排成 \(D\times N\) 的矩阵 \(X\),其 SVD 为 \(X=U\Sigma V^\top\)(1.12 节),\(U\) 的前 \(k\) 列 \(\hl{pc}{U_k}\) 就是前 \(k\) 个主方向。线性自编码器 \(\mathbf z=E\mathbf x\),\(\hat{\mathbf x}=\hl{W}{W}\mathbf z\),其中 \(E\in\R^{k\times D}\),\(W\in\R^{D\times k}\),总误差是

    $$ \big\|X-\hl{W}{W}EX\big\|_F^2\ \ \ge\ \min_{\operatorname{rank}(Y)\le k}\|X-Y\|_F^2=\sum_{i>k}\sigma_i^2,\qquad WEX=\hl{pc}{U_k}U_k^\top X\ \Longleftrightarrow\ \big\|X-WEX\big\|_F^2=\sum_{i>k}\sigma_i^2 $$

    不等号成立是因为 \(WEX\) 的秩不超过 \(k\),而右边是 Eckart–Young 定理(1.12 节)给出的最佳秩 \(k\) 近似误差;右边的等价关系在 \(\sigma_k>\sigma_{k+1}\) 时成立,因为这时最佳秩 \(k\) 近似唯一,就是 \(U_kU_k^\top X\)。所以全局最优处 \(W\) 的列空间就是 \(\operatorname{span}(U_k)\),误差等于 PCA-\(k\) 的误差。但具体的 \(W\) 不唯一:对任意可逆的 \(k\times k\) 矩阵 \(A\),

    $$ W=U_kA,\quad E=A^{-1}U_k^\top\ \ \Longrightarrow\ \ WE=U_kU_k^\top $$

    给出同一个重建。FIG 3 的“编码 ×2”就是 \(A=\tfrac12\)(\(k=1\)),所以编码的 \(k\) 个坐标一般是主成分的某种混合,而不是主成分本身。要找回主方向,可以在学到的 \(k\) 维编码上再做一次 PCA(只有 \(k\times k\),很便宜)。Baldi 与 Hornik(1989)还证明了更强的结论:这个损失没有坏的局部极小,除全局最优外的临界点都是鞍点,这就是 FIG 3 从任何初值都能收敛的原因。一旦有非线性,这个保证就没有了(FIG 1 的平台期、FIG 2 的折痕)。

    去噪自编码器学的是 score

    DAE 最小化 \(\mathbb E_{\mathbf x,\boldsymbol\varepsilon}\|\mathbf x-r(\hl{noise}{\tilde{\mathbf x}})\|^2\),\(r=g_\theta\circ f_\phi\),\(\tilde{\mathbf x}=\mathbf x+\sigma\boldsymbol\varepsilon\),\(\boldsymbol\varepsilon\sim\mathcal N(0,I)\)。对每个 \(\tilde{\mathbf x}\) 单独看,平方误差的最优解是条件均值(4.6 节的 MMSE 估计);对高斯破坏,Tweedie 公式把它写成:

    $$ r^\star(\tilde{\mathbf x})=\mathbb E[\mathbf x\mid\tilde{\mathbf x}]=\tilde{\mathbf x}+\sigma^2\,\nabla_{\tilde{\mathbf x}}\log p_\sigma(\tilde{\mathbf x}),\qquad p_\sigma=p*\mathcal N(0,\sigma^2I) $$

    其中 \(p\) 是数据的密度,\(p_\sigma\) 是它与噪声卷积后(加噪数据)的密度。所以足够大的 DAE 输出减去输入,是 \(\sigma^2\) 乘以加噪数据密度的 score:一个指向数据更密处的向量场。Vincent(2011)把这一点和 score matching 联系起来,Alain 与 Bengio(2014)分析了 \(\sigma\to0\) 的极限。这正是 19.6 节扩散模型训练的东西,只是那里同时在许多个 \(\sigma\) 上训练。

    稀疏与收缩自编码器

    除了把编码变窄,还可以给编码加别的约束,这时隐层甚至可以比输入更宽(过完备)。稀疏自编码器惩罚隐层激活 \(\mathbf h=f_\phi(\mathbf x)\),让每个输入只激活少数单元:

    $$ \mathcal L'=\mathcal L+\beta\,\frac1N\sum_i\|\mathbf h_i\|_1,\qquad \mathcal L''=\mathcal L+\beta\sum_j\operatorname{KL}\big(\rho\,\|\,\hat\rho_j\big),\ \ \hat\rho_j=\frac1N\sum_i h_{ij}\in(0,1) $$

    第一种是 L1 惩罚;第二种形式 \(\mathcal L''\)(sigmoid 隐层,把每个单元的平均激活 \(\hat\rho_j\) 拉向一个小目标 \(\rho\),如 0.05)来自 Ng 的讲义。在自然图像小块上训练,稀疏编码的单元往往变成局部的边缘检测器。收缩自编码器(Rifai 等,2011)惩罚编码器的雅可比 \(\lambda\|\partial f_\phi/\partial\mathbf x\|_F^2\),让编码对偏离流形的微小扰动不敏感,和 DAE 的效果相近。

    为什么普通自编码器不能生成

    要生成,需要一个能采样的分布 \(p(\mathbf z)\),并且解码器在它的大部分质量上都被训练过。普通 AE 的训练只碰到 \(N\) 个点 \(f_\phi(\mathbf x_i)\),“编码的分布”就是这些点的经验分布,形状由优化随意决定(FIG 4 的空隙、折痕、薄片)。损失里没有任何一项惩罚“空隙处解码成什么”。VAE 的两处改动正对着这两个问题:编码器输出一个分布 \(q_\phi(\mathbf z\mid\mathbf x)\) 而不是一个点,使解码器在每个编码附近的一整团区域上都被训练;再加一项 \(\operatorname{KL}(q_\phi(\mathbf z\mid\mathbf x)\,\|\,\mathcal N(0,I))\),让所有编码合起来铺满标准正态,于是可以从 \(\mathcal N(0,I)\) 采样(19.1 节推导 ELBO)。

    6在机器人中:用编码做控制

    自编码器在机器人里最直接的用途,是把相机图像变成控制器能用的低维状态。一个最简单的视觉伺服:给机器人一张“目标图像”,让它移动物体,直到当前图像和目标图像一致。用什么来衡量“一致”?最直接的是像素距离 \(\hl{dpix}{\|\mathbf x-\mathbf x_g\|^2}\);另一个选择是编码距离 \(\hl{dlat}{\|f_\phi(\mathbf x)-f_\phi(\mathbf x_g)\|^2}\)。

    下图是一个导轨上的圆盘(1 个自由度),相机图像 20×6 像素。机器人每次把圆盘左移或右移 0.1 像素,选能让距离变小的方向,两个方向都不能变小就停下(贪心下降)。我们同时训练两个 120→24→1→24→120 的自编码器:一个是普通的;另一个额外要求相邻两帧的编码相近,即损失再加 \(\lambda\,(z(\mathbf x_t)-z(\mathbf x_{t+1}))^2\),\(\lambda=0.5\),其中两帧的圆盘位置相差不到 0.3 像素,就像机器人录视频时连续的两帧。这就是 Jonschkowski 与 Brock 所说的“慢变”(slowness)机器人先验。

    FIG 6视觉伺服:像素距离、普通编码与慢变编码
    上:相机图像(像素亮度画成青色的不透明度),空心圆环是目标位置。中:编码 \(z\) 随圆盘位置变化的曲线(每条都缩放到 0 到 1),琥珀色为普通 AE,蓝色为加慢变项的 AE。下:当前目标下“到目标的距离”随圆盘位置的变化(各自缩放到 0 到 1):紫色为像素距离,琥珀色和蓝色为两种编码距离;选中的方法画得更粗,竖虚线是目标,实心点是圆盘当前位置。
    • 方法选“像素距离”,起点和目标相距至少 6 像素(默认 3 和 16 即可),按“运行伺服”:圆盘最多挪动零点几个像素就停下,离目标还很远。两个圆盘不重叠时,像素距离与它们相距多远无关,没有指向目标的下降方向。
    • 训练到两个自编码器的误差都低于 0.01(约 1500 步),方法选“普通 AE”,起点与目标相距至少 6 像素,运行伺服:圆盘停在离目标 1 像素以上的地方。看中间那条琥珀色曲线:编码在某处突然跳变,伺服卡在跳变处。
    • 同样的起点和目标,方法选“AE + 慢变”,运行伺服:圆盘到达目标 0.5 像素以内。

    像素距离的伺服从起点 3 出发一步也没动;我们从导轨上各处起步试过,它最多挪 0.3 像素,停在一个让圆盘自身图像的平方和最小的亚像素位置(见第 8 节第 5 题)。默认种子(3)训练 2000 步后,普通 AE 的编码在圆盘位置约 7.7 像素处跳变,从起点 3 出发的伺服停在约 7.7 处;慢变 AE 的编码是单调的,130 步走到目标 16。我们在 node 里试了种子 1 到 10:普通 AE 有 7 个种子出现了跳变或折返,慢变 AE 在所有 10 个种子上都没有跳变,对所有相距 6 像素以上的起点–目标组合都能到达。两者的重建误差都低于 0.01(默认种子下约 0.006 和 0.003),说明重建误差根本看不出编码能不能用来控制。按“新种子”可以自己看这种差异。

    真实系统

    从像素做强化学习:Lange 与 Riedmiller(2010)先用深度自编码器把原始图像压成很短的编码,再在编码上做批量强化学习,是这条路线的早期工作。Finn 等(2016)的 deep spatial autoencoder 在编码层用 spatial softmax 输出一组二维“特征点”坐标,让 PR2 机器人从图像学习视觉运动技能,特征点比一般的编码更像物体位置。SAC+AE(Yarats 等,2021)在 DeepMind Control 的像素任务上,把自编码器的重建损失作为辅助任务和 SAC 一起训练,明显提高了样本效率。世界模型:Dreamer 一类方法(24.3 节)在学到的隐空间里预测未来,其中一部分用重建损失训练表示,TD-MPC 一类则不重建图像。异常检测:只在正常数据上训练的自编码器,对没见过的情况重建误差会变大,常用作简单的失败或分布外检测器。预训练视觉编码器:如今机器人更常用的是对比学习或掩码重建(MAE)预训练的编码器(18.3、18.4 节),MAE 本身就是一种“遮住大部分再重建”的自编码器。

    7常见误区

    误区 1:重建误差低,编码就好用

    FIG 6 里两个自编码器的重建误差差不多,一个能伺服,一个卡在跳变处。重建误差只说明信息在编码里,不说明它以光滑、可比较的形式存在。还有一个机器人常见的坑:均方误差对每个像素一视同仁,图像里只占几个像素的小物体(夹爪尖、要抓的螺丝)对损失几乎没有贡献,自编码器可以把它们糊掉而误差几乎不变,可它们恰恰是任务关键。检查编码时,要用下游任务(伺服、回归位置、策略效果)来评价,而不只看重建。

    误区 2:瓶颈宽度随便选

    太窄(FIG 2 的 \(K=1\),或 FIG 1 用一个数编码一个圆)会迫使网络折叠或剪开数据;太宽且没有别的约束,网络可以学成近似恒等映射,连噪声一起照抄。FIG 2 还显示,恰好等于自由度的宽度(\(K=2\))不一定最好训:\(K=4\) 的误差低一个数量级。实践中先扫几个宽度,并配合去噪或稀疏这类正则,而不是只靠窄瓶颈。

    误区 3:把普通自编码器当生成模型

    “训练好之后随机取一个编码解码”看起来可行,FIG 4 说明它不可靠:\(K=8\) 时重建近乎完美,随机编码却只有三分之一多一点解码成圆盘。编码之间做线性插值也有同样的问题,插值路径可能穿过空隙或折痕。需要采样或插值时,用 VAE(19.1)、扩散模型(19.6)或流匹配(19.7)这类真正建模了分布的方法。

    误区 4:以为编码空间里的距离有意义

    FIG 1 的闭合圆上,剪口两侧相隔几厘米的点编码相差最大;FIG 6 的普通 AE 在某处跳变。自编码器的损失不包含任何关于“相近的输入应有相近的编码”的项,距离、方向、尺度都没有保证(FIG 3 连线性情形的尺度都是任意的)。需要可比较的编码时,要显式地加约束:慢变或时间相关的先验(FIG 6)、对比学习(18.3)的正负样本、或 VAE 的 KL 项。

    误区 5:跳过 PCA 基线,或把线性 AE 的权重当主成分

    PCA 一行代码、没有超参数、结果唯一,应该总是先算它:如果 PCA 用同样维数已经够好,就不需要自编码器(比如手部关节的协同几乎是线性的)。反过来,线性自编码器只学到子空间,它的 \(W\) 的列既不正交也不按方差排序(第 5 节的 \(A\)),不能直接当主成分来解读。另外别忘了输入归一化:不同单位的分量(米和弧度、像素和力)不缩放,平方误差就会被数值最大的那个分量主导,PCA 和 AE 都是如此。

    8小练习

    1. 在 \(\R^{10}\) 中已中心化、特征值互不相同的数据上,把 \(k=2\) 的线性自编码器训练到全局最优。解码器 \(W\) 的两列是什么?
    由 Eckart–Young,最优处 \(WE=U_2U_2^\top\),所以 \(W=U_2A\),\(A\) 是任意可逆的 2×2 矩阵:列空间唯一(排除选项 D),具体的基不唯一(排除选项 A)。选项 C 只有在主方向恰好与坐标轴对齐时才对。FIG 3 的“编码 ×2”演示的就是这种不唯一。
    2. 对 144 像素的图像训练一个普通自编码器,隐层有 200 个单元、没有任何正则,训练足够久。最可能发生什么?
    编码比输入还宽,“照抄”就是一个零误差的解,损失里没有任何东西阻止它。所以过完备的自编码器必须配合别的约束:去噪(FIG 5)、稀疏惩罚或收缩惩罚。选项 B 不成立:144 维数据最多只有 144 个主成分,而且非线性网络也不等价于 PCA。
    3. 一个容量足够的去噪自编码器用高斯噪声 \(\sigma\) 训练到最优。对加噪输入 \(\tilde{\mathbf x}\),向量 \(r(\tilde{\mathbf x})-\tilde{\mathbf x}\) 指向哪里?
    平方误差的最优解是 \(\mathbb E[\mathbf x\mid\tilde{\mathbf x}]\),Tweedie 公式给出 \(\mathbb E[\mathbf x\mid\tilde{\mathbf x}]-\tilde{\mathbf x}=\sigma^2\nabla\log p_\sigma(\tilde{\mathbf x})\)。它是所有可能的干净样本按后验加权的平均,而不是最近的那一个(选项 B);只有在噪声极大时才趋向数据均值(选项 C);恒等映射在加噪输入上误差为 \(\sigma^2\),不是最优(选项 D)。
    4. 一个重建几乎完美的普通自编码器,为什么解码随机编码时经常得到不像数据的东西?
    FIG 4:\(K=8\) 时编码只是 8 维空间里的一张二维薄片,从拟合的高斯里采样只有约 37% 解码成圆盘,而测试图的重建 100% 合格,所以问题不在解码器的容量(选项 A)或模糊(选项 C)。VAE 用编码分布和 KL 项解决的正是选项 D 的问题。
    5. FIG 6 的圆盘半径 \(R=1.8\) 像素,边缘还有 1 像素的线性过渡(亮度从圆心距离 \(R-0.5\) 处的 1 降到 \(R+0.5\) 处的 0)。两个圆盘的圆心相距超过多少时,像素距离就不再取决于它们相距多远?
    每个圆盘的非零区域半径是 \(R+0.5=2.3\) 像素,圆心相距超过 \(2\times2.3=4.6\) 像素后两者完全不重叠,交叉项 \(-2\,\mathbf x^\top\mathbf x_g\) 为零,\(\|\mathbf x-\mathbf x_g\|^2=\|\mathbf x\|^2+\|\mathbf x_g\|^2\)。\(\|\mathbf x\|^2\) 只随圆盘在像素格上的亚像素位置有几个百分点的周期性起伏,与目标在哪里无关。所以 FIG 6 的贪心伺服只挪到附近一个让 \(\|\mathbf x\|^2\) 最小的亚像素位置就停下。选项 B 是不算边缘过渡时的 \(2R\)。

    9延伸阅读

    • D. E. Rumelhart, G. E. Hinton & R. J. Williams, Learning Internal Representations by Error Propagation, in Parallel Distributed Processing, Vol. 1, MIT Press, 1986 — 反向传播,以及用“编码器问题”训练窄隐层还原输入的早期例子
    • H. Bourlard & Y. Kamp, Auto-Association by Multilayer Perceptrons and Singular Value Decomposition, Biological Cybernetics, 1988 — 线性自联想网络与 SVD 的关系
    • P. Baldi & K. Hornik, Neural Networks and Principal Component Analysis: Learning from Examples Without Local Minima, Neural Networks, 1989 — 线性自编码器的损失曲面:全局最优是 PCA 子空间,其余临界点都是鞍点
    • G. E. Hinton & R. R. Salakhutdinov, Reducing the Dimensionality of Data with Neural Networks, Science, 2006 — 深度自编码器在图像上明显优于 PCA
    • P. Vincent, H. Larochelle, Y. Bengio & P.-A. Manzagol, Extracting and Composing Robust Features with Denoising Autoencoders, ICML 2008 — 去噪自编码器
    • P. Vincent, A Connection Between Score Matching and Denoising Autoencoders, Neural Computation, 2011;G. Alain & Y. Bengio, What Regularized Auto-Encoders Learn from the Data-Generating Distribution, JMLR, 2014 — 去噪与 score 的联系
    • S. Rifai, P. Vincent, X. Muller, X. Glorot & Y. Bengio, Contractive Auto-Encoders: Explicit Invariance During Feature Extraction, ICML 2011 — 收缩自编码器
    • I. Goodfellow, Y. Bengio & A. Courville, Deep Learning, MIT Press, 2016, Ch. 14 — 自编码器一章:欠完备、正则化、稀疏、去噪、收缩
    • S. Lange & M. Riedmiller, Deep Auto-Encoder Neural Networks in Reinforcement Learning, IJCNN 2010 — 先压缩图像、再在编码上做强化学习
    • R. Jonschkowski & O. Brock, Learning State Representations with Robotic Priors, Autonomous Robots, 2015 — 慢变等物理先验用于学习状态表示
    • C. Finn, X. Y. Tan, Y. Duan, T. Darrell, S. Levine & P. Abbeel, Deep Spatial Autoencoders for Visuomotor Learning, ICRA 2016 — 特征点编码用于真实机器人的视觉运动学习
    • D. Yarats, A. Zhang, I. Kostrikov, B. Amos, J. Pineau & R. Fergus, Improving Sample Efficiency in Model-Free Reinforcement Learning from Images, AAAI 2021 — SAC+AE:重建作为辅助损失