Part V · 第 18 章 无监督与自监督学习 · 18.2Part V · Ch. 18 Unsupervised & Self-Supervised Learning · 18.2

自编码器 (Autoencoder)Autoencoders

机器人相机一帧有几十万个数,可场景真正在变的往往只有几个量:物块在哪、夹爪张开多少。自编码器让一个网络把输入压缩成很短的编码,再从编码把输入还原出来,训练目标就是输入本身,不需要任何标签。线性的自编码器恰好学到 PCA 的子空间;非线性的能沿着弯曲的数据流形压缩,用 2 个数做到 PCA 要十几个主成分才能做到的事。本节在浏览器里现场训练六个小网络,看它们怎样压缩、去噪、在哪里失败,以及为什么“编码好”不等于“能生成”,也不等于“能拿来控制”。 A frame from a robot camera holds hundreds of thousands of numbers, yet what actually changes in the scene is often a handful of quantities: where the block is, how far the gripper is open. An autoencoder trains a network to squeeze its input into a short code and to rebuild the input from that code; the training target is the input itself, so no labels are needed. A linear autoencoder learns exactly the PCA subspace; a nonlinear one can compress along a curved data manifold and do with 2 numbers what PCA needs a dozen or more components for. This lesson trains six small networks live in the browser to see how they compress, how they denoise, where they fail, and why a good code is neither a generator nor automatically a good state for control.

约 40 分钟~40 min 前置:18.1 聚类与 PCA · 16.3 反向传播 · 1.12 SVD · 4.6 MLEPrereqs: 18.1 Clustering & PCA · 16.3 Backpropagation · 1.12 SVD · 4.6 MLE 6 个交互6 interactives

    1为什么机器人需要它Why robots need this

    一台 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 节)。

    A 640×480 colour camera delivers 921 600 numbers per frame. Hand such a vector straight to a controller or a reinforcement-learning algorithm and it barely learns: the input is huge, neighbouring pixels are strongly correlated, and the quantities that matter for the task (object position, pose, gripper opening) are only a few. We would like to first squeeze the observation into a short vector \(\mathbf z\) that keeps "what state the scene is in" and drops the rest, and then plan, learn policies and detect anomalies on \(\mathbf z\).

    The PCA of Lesson 18.1 is already a compression: find the \(k\)-dimensional linear subspace onto which the data can be projected with the least lost variance. But PCA only knows flat subspaces. Slide a disc across a table and the images form a "surface" with only 2 degrees of freedom, yet that surface is badly curved in pixel space: move the disc by one diameter and the old and new images hardly overlap, so they are nearly orthogonal. Fitting such a surface with flat pieces takes many dimensions.

    An autoencoder (AE) is the nonlinear generalization of PCA: an encoder network \(f_\phi\) maps \(\mathbf x\) to a short code \(\mathbf z\), a decoder network \(g_\theta\) maps \(\mathbf z\) back to \(\hat{\mathbf x}\), and both are trained together by the backpropagation of Lesson 16.3 so that \(\hat{\mathbf x}\) comes as close to \(\mathbf x\) as possible. The label is the input itself, so it is self-supervised: video the robot records anyway is training data. It is also the starting point of several later methods: the VAE (Lesson 19.1) gives the code a probabilistic meaning so that it can generate; contrastive learning (Lesson 18.3) and masked modeling / JEPA (Lesson 18.4) replace the "rebuild every pixel" objective; and the denoising autoencoder leads straight to diffusion models (Lesson 19.6).

    2直觉:从一个窄口挤过去Intuition: squeeze through a narrow neck

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

    An autoencoder is shaped like an hourglass: a wide input, a narrow middle, a wide output.

    $$ \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}\) 把整条一维的“编码轴”弯成一条曲线,训练就是让这条曲线去贴合数据。

    The middle layer is the bottleneck, and its output \(\mathbf z\) is the code or latent. If \(k\ge D\) the network could drive the error to zero by just copying its input, having learned nothing; it is precisely because \(k\) is small that the network is forced to find the most economical description of the data. If all data points actually lie on one curve, a single number (how far along the curve) is enough.

    Here is the smallest example: a curved path traced by a robot's gripper on a table during a demonstration, 160 planar positions (in metres, with 3 cm of noise). The encoder is a small 2→24→1 network (tanh), the decoder 1→24→2. PCA can only represent one-dimensional structure by a straight line; the autoencoder's decoder \(\hl{dec}{g_\theta}\) bends the whole one-dimensional "code axis" into a curve, and training makes that curve hug the data.

    FIG 1一维瓶颈:把弯曲的夹爪路径压成一个数A one-number bottleneck: compressing a curved gripper path
    左:数据点按它的编码 \(z\) 着色(红 = 编码最小,蓝 = 编码最大);琥珀色曲线是解码器 \(g_\theta(z)\) 在整个编码范围上画出的曲线,琥珀色小点是每个点的重建 \(\hat{\mathbf x}\),细线连接点和它的重建;绿色虚线是 PCA 的第一主方向(最好的一维直线)。滑块“编码 z”在编码范围内移动,琥珀色圆环是 \(g_\theta(z)\)。右:每个坐标的均方重建误差(对数坐标),琥珀色为自编码器,绿色虚线为 PCA-1,灰色点线是 3 cm 噪声决定的下限 \(\sigma^2/2\)。 Left: each data point is coloured by its code \(z\) (red = smallest code, blue = largest); the amber curve is the decoder \(g_\theta(z)\) drawn over the whole code range, the small amber dots are the reconstructions \(\hat{\mathbf x}\), and thin lines join each point to its reconstruction; the green dashed line is PCA's first principal direction (the best one-dimensional line). The "code z" slider moves through the code range, and the amber ring is \(g_\theta(z)\). Right: per-coordinate mean squared reconstruction error (log scale), amber for the autoencoder, green dashed for PCA-1; the grey dotted line is the floor \(\sigma^2/2\) set by the 3 cm noise.
    试一试Try this
    • 在“弧线”数据上按“训练”:几百步之内,自编码器的误差降到 PCA-1 的十分之一以下(读数里的“AE / PCA”小于 0.1)。再拖“编码 z”滑块,看琥珀色圆环沿着路径从红端走到蓝端。On the "arc" data press "Train": within a few hundred steps the autoencoder's error drops below a tenth of PCA-1's ("AE / PCA" in the readout under 0.1). Then drag the "code z" slider and watch the amber ring travel along the path from the red end to the blue end.
    • 换成“闭合圆”并训练,直到“AE / PCA”低于 0.3(大约 2000 步,前一千多步会停在 1 附近)。颜色在圆上某处从红直接跳到蓝:一个连续的数无法不重不漏地给一个圆编号,网络只能在那里“剪开”。Switch to "closed circle" and train until "AE / PCA" falls below 0.3 (about 2000 steps; for the first thousand or so it sits near 1). Somewhere on the circle the colour jumps straight from red to blue: one continuous number cannot label a circle without overlaps or gaps, so the network has to cut it open there.

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

    On the arc, with the default seed, the error is about 11% of PCA's after 300 steps, about 5% after 1000, and settles around 3% to 4%, close to the noise floor (about 2% of PCA's): what remains is essentially noise perpendicular to the path, which no one-dimensional description can remove. The S-curve is more interesting: for roughly the first thousand steps the error stays at PCA's level (the decoder is still a straight line), then it suddenly drops to about 8%. This "plateau, then a sudden drop" is common when training autoencoders; do not conclude too early that it cannot learn.

    核心洞见Key insight

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

    The bottleneck forces the network to learn a "coordinate system" for the data: the encoder gives each point a coordinate on the data manifold and the decoder turns coordinates back into points. PCA's axes are straight; an autoencoder's can bend. But the coordinate is designed only for "rebuilds well", and nothing asks it to be smooth, even or meaningful: the cut on the circle is the first warning.

    3动手:压缩机器人相机的图像Play: compress images from a robot camera

    现在换成真正的高维输入。俯视相机看着桌上的一个圆盘(半径 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\) 个主成分再重建。两者的误差都是测试图上每个像素的均方误差。

    Now switch to genuinely high-dimensional input. A top-down camera looks at a disc on a table (radius 1.8 pixels with a 1-pixel soft edge), in images of only 12×12 = 144 pixels. The disc position \((p_x,p_y)\) is the only thing that changes, so the images form a two-dimensional surface inside pixel space \(\R^{144}\). The training set is 300 images at random positions; 60 more test images are used only for evaluation.

    The autoencoder is 144→32→\(K\)→32→144 (tanh hidden layers, a sigmoid output that keeps pixels between 0 and 1), trained by Adam on batches of 16. The baseline is PCA on the same training set: keep the first \(k\) principal components and reconstruct. Both errors are the per-pixel mean squared error on the test images.

    FIG 22 个数 vs 十几个主成分:圆盘图像的自编码器Two numbers vs a dozen components: an autoencoder for disc images
    左:6 张测试图(每列一张,窄屏上只显示 4 张)。第一行是输入,第二行是自编码器的重建(编码 \(K\) 个数),第三行是 PCA 保留 \(k\) 个主成分的重建;像素亮度画成青色的不透明度(越不透明越亮),PCA 重建里小于 0 的像素画成红色。右:测试误差(对数坐标),琥珀色为自编码器,绿色虚线为 PCA-\(k\)(它不需要训练,是一条水平线)。改变 \(K\) 会重新开始训练。 Left: 6 test images (one per column; 4 on narrow screens). Row one is the input, row two the autoencoder's reconstruction (a code of \(K\) numbers), row three PCA's reconstruction from \(k\) components; pixel intensity is drawn as cyan opacity (more opaque = brighter), and pixels of a PCA reconstruction that fall below 0 are drawn in red. Right: test error (log scale), amber for the autoencoder, green dashed for PCA-\(k\) (it needs no training, so it is a horizontal line). Changing \(K\) restarts training.
    • 保持 \(K=2\)、PCA \(k=2\),按“训练”:自编码器的测试误差降到 PCA-2 的三分之一以下(大约 1500 到 2000 步)。比较第二行和第三行:PCA-2 只能给出位置大致对的一团模糊,自编码器给出一个清晰的圆盘。Keep \(K=2\) and PCA \(k=2\) and press "Train": the autoencoder's test error falls below a third of PCA-2's (around 1500 to 2000 steps). Compare rows two and three: PCA-2 can only produce a blur at roughly the right place, the autoencoder a crisp disc.
    • 自编码器的测试误差低于 0.01 之后,把 PCA 的 \(k\) 往上拖,直到 PCA 的测试误差不高于自编码器的。PCA 需要多少个主成分才追上 2 个数?Once the autoencoder's test error is below 0.01, drag PCA's \(k\) up until PCA's test error is no higher than the autoencoder's. How many principal components does PCA need to match two numbers?

    按默认种子,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\) 的编码里确实有折痕。

    With the default seed, after 3000 steps \(K=2\) has a test error of about 0.0073, which PCA needs about 13 components to match (0.0068); PCA-2 sits at 0.0363 and explains only 31% of the training variance. The reason is the one from Section 1: images of the disc at different places barely overlap, so this surface in pixel space is tightly "curled up" and no flat subspace can hug it.

    There is also a counter-intuitive effect: try \(K=1\), \(4\) and \(8\). \(K=1\) is of course too few (test error still about 0.019 after 4000 steps), but \(K=4\) reaches about 0.0008 at 3000 steps, an order of magnitude below \(K=2\), even though the data have only 2 degrees of freedom. In theory 2 numbers suffice, but laying a two-dimensional surface flat onto a two-dimensional code without folds is hard for the optimizer to find; with a few spare dimensions the network can use a code that lies "bent" and avoid the difficulty. FIG 4 shows that the \(K=2\) code does contain creases.

    核心洞见Key insight

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

    PCA compresses by variance; an autoencoder compresses by degrees of freedom. When the data are a nonlinear function of a few physical quantities (camera images almost always are), the gap can be an order of magnitude. But the shortest code that is achievable and the code that is easy to train are different things: a bottleneck slightly wider than the true number of degrees of freedom often trains better.

    4另外三个视角:线性情形、隐空间、去噪Three more views: the linear case, the latent space, denoising

    线性自编码器学到的就是 PCA 子空间A linear autoencoder learns the PCA subspace

    去掉所有非线性,自编码器还剩什么?编码器变成一个矩阵 \(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 从随机初值开始训练。

    Strip out every nonlinearity and what is left of an autoencoder? The encoder becomes a matrix \(E\) (plus a bias), the decoder a matrix \(W\) (plus a bias), and the reconstruction \(\hat{\mathbf x}=W E\mathbf x+\mathbf c\) always lies in the column space of \(W\), shifted to some point. Section 5 proves that as long as the \(k\)-th and \((k+1)\)-th eigenvalues differ, at the optimum of the squared error the column space of \(W\) is the subspace spanned by the first \(k\) principal directions, and the error equals PCA-\(k\)'s exactly. The example below is two finger-joint angles (in rad): they tend to flex together, so the data spread along a slanted line, like the "synergies" of Lesson 18.1. A linear 2→1→2 autoencoder is trained by Adam from a random start.

    FIG 3线性自编码器收敛到 PCA 的子空间,但基不唯一A linear autoencoder converges to the PCA subspace, but not to a unique basis
    横轴、纵轴是两个关节角(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\)。 The axes are the two joint angles (rad). Purple dots are 200 data points; drag the purple ring to change the data's main direction and long axis (the ring sits 2 standard deviations out along it); the slider sets the short axis's standard deviation. The green dashed line is PCA's first principal direction, the amber line is the set of all outputs the decoder can produce, \(W z+\mathbf c\) (\(W\) is a 2-vector column), and the small amber dots are reconstructions; the red arrow is the encoder's row vector \(E\) (\(z=E\mathbf x+b\)). The readout gives the angle between the two lines, the error relative to PCA-1, \(E W\) and \(\|W\|\); below it, \(W E\) is compared with PCA's projection matrix \(\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\) 一致。Press "Train": the amber line swings onto the green dashed line, the angle drops below 1° and the error ratio to PCA-1 is within 1.00 ± 0.01 (a hundred or two steps). Then \(E W\approx1\) and \(W E\) matches \(\mathbf u_1\mathbf u_1^\top\).
    • 收敛之后(夹角小于 1°)按“编码 ×2”:编码器乘 2、解码器除以 2,\(\|W\|\) 减半,误差一点都不变。再按“重置”换一个随机初值重新训练:收敛后的 \(\|W\|\) 也不同。线性自编码器只确定子空间,不确定子空间里的坐标。After convergence (angle below 1°) press "code ×2": the encoder is multiplied by 2 and the decoder divided by 2, \(\|W\|\) halves and the error does not change at all. Then press "Reset" to retrain from another random start: the converged \(\|W\|\) is different too. A linear autoencoder pins down the subspace, not the coordinates inside it.

    隐空间:编码之间的空隙与折痕The latent space: gaps and creases between codes

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

    Since the decoder turns codes back into images, can we pick any code and "generate" an image never seen before? The figure below draws the latent space of the model trained in FIG 2 (both figures share one model, so you can train it in either). For \(K=2\) each training image's code is a point in the plane; for \(K>2\) the plot shows the first two code dimensions with the others held at the mean of the training codes. Drag the amber handle to choose a code; the side panel shows the image it decodes to and how far that image is from "some real disc image": search all disc positions for the closest one and take the per-pixel mean squared error; below 0.01 counts as "looks like a disc".

    FIG 4隐空间:编码不是一个可以随手采样的分布The latent space: the codes are not a distribution you can sample from
    左:每个小点是一张训练图的编码,按圆盘的 \(p_x\) 着色(紫 = 圆盘在左,青 = 在右),或切换成按 \(p_y\) 着色(琥珀 = 在上,蓝 = 在下)。“画出解码器地图”把可见区域分成小格,逐格解码并上色:绿色格解码成圆盘,红色格不是(地图只对当前模型有效,继续训练后会隐藏)。右:琥珀色手柄处编码的解码图像,像素亮度画成青色的不透明度。下:从按每一维拟合到训练编码上的高斯分布里采样 16 个编码并解码,绿框 = 像一个圆盘,红框 = 不像。 Left: each small dot is the code of one training image, coloured by the disc's \(p_x\) (purple = disc on the left, cyan = on the right), or switched to \(p_y\) (amber = top, blue = bottom). "Map the decoder" splits the visible area into small cells, decodes each and colours it: green cells decode to a disc, red cells do not (the map is valid only for the current model and hides once training continues). Right: the image decoded from the code under the amber handle, pixel intensity as cyan opacity. Bottom: 16 codes sampled from a Gaussian fitted to the training codes dimension by dimension, decoded; a green frame = looks like a disc, a red frame = does not.
    • 在 \(K=2\)、测试误差低于 0.015 的模型上,按“画出解码器地图”,再把琥珀色手柄拖进一个远离所有训练编码的红色区域(离最近训练编码的距离超过编码范围的 8%),使解码图不像圆盘(误差大于 0.01)。On a \(K=2\) model with test error below 0.015, press "Map the decoder", then drag the amber handle into a red region far from every training code (more than 8% of the code range from the nearest one) so that the decoded image does not look like a disc (error above 0.01).
    • 在 FIG 2 里选 \(K=8\) 并训练到测试误差低于 0.003(重建几乎完美),然后在这里按“采样 16 个编码”至少两次:累计下来像圆盘的不到一半。In FIG 2 choose \(K=8\) and train until the test error is below 0.003 (near-perfect reconstructions), then press "Sample 16 codes" here at least twice: in total fewer than half look like a disc.

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

    After 3000 steps at the default settings we sampled 200 codes each in node with the same code: for \(K=2\) about 86% decode to a disc, for \(K=8\) only about 37%, whereas reconstructions of the test images are 100% valid in both cases. \(K=8\) reconstructs better and samples worse: the training codes occupy only a thin two-dimensional "sheet" inside the 8-dimensional space, and a per-dimension Gaussian almost always lands off the sheet, where the decoder was never trained. Even for \(K=2\) the decoder map shows large red areas away from the data and thin red creases inside the data region.

    核心洞见Key insight

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

    A plain autoencoder only asks that codes can be decoded; it says nothing about how the codes are spread over the latent space: no prior, no idea where to sample, no guarantee about what the gaps decode to. To generate, training must also shape the distribution of codes, which is exactly what the VAE of Lesson 19.1 does: the encoder outputs a distribution, and a KL term pulls it toward a standard normal.

    去噪自编码器:学会回到数据上Denoising autoencoders: learning to step back onto the data

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

    Real cameras are noisy. The denoising autoencoder (DAE) changes one thing: the input is replaced by a corrupted version \(\hl{noise}{\tilde{\mathbf x}}=\mathbf x+\sigma\boldsymbol\varepsilon\) while the target stays the clean \(\mathbf x\). The network can no longer "copy the input"; it has to learn to push points that stray from the data manifold back onto it. The two networks below have identical architectures (144→32→144, no narrow bottleneck) and train side by side: one on clean inputs (a plain AE), one on noisy inputs (the DAE); both are evaluated on test images carrying the same noise.

    FIG 5普通自编码器 vs 去噪自编码器Plain vs denoising autoencoder
    左:6 张测试图(窄屏上 4 张),自上而下为干净图、加噪输入 \(\tilde{\mathbf x}\)(噪声标准差 σ,超出 0 到 1 的值截断显示)、普通 AE 的输出、DAE 的输出;像素亮度画成青色的不透明度。右:在加噪测试图上、输出与干净图之间的每像素均方误差(对数坐标):琥珀色为普通 AE,蓝色为 DAE,紫色虚线是什么都不做(直接输出 \(\tilde{\mathbf x}\))的误差。改变 σ 会从头训练两个网络。 Left: 6 test images (4 on narrow screens); from top to bottom the clean image, the noisy input \(\tilde{\mathbf x}\) (noise standard deviation σ; values outside 0 to 1 are clipped for display), the plain AE's output and the DAE's output; pixel intensity as cyan opacity. Right: per-pixel mean squared error between output and clean image on the noisy test images (log scale): amber for the plain AE, blue for the DAE; the purple dashed line is the error of doing nothing (outputting \(\tilde{\mathbf x}\) itself). Changing σ retrains both networks from scratch.
    • σ = 0.3 时训练 600 步以上:DAE 在加噪测试图上的误差降到普通 AE 的一半以下。再看读数里“干净输入”的误差:普通 AE 在干净图上反而更好。With σ = 0.3 train for 600 steps or more: the DAE's error on the noisy test images drops below half of the plain AE's. Then look at the "clean input" errors in the readout: on clean images the plain AE is the better one.

    默认 σ = 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。

    At the default σ = 0.3, doing nothing costs 0.091; after 1000 steps the plain AE is at 0.014 and the DAE at 0.0043, about a third of it. The plain AE removes plenty of noise too, because a 32-unit hidden layer is a constraint in itself; but it has never seen noise, and the parts of the noise that "look like a disc edge" pass straight through. The price is that the DAE is slightly worse on clean inputs (about 0.0012 against the plain AE's 0.0003): what it learned is "the input is probably noisy, pull it toward the data", and it pulls a clean image a little too. The larger σ, the larger the gap: at σ = 0.5, after 2000 steps, about 0.040 against 0.010.

    核心洞见Key insight

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

    Denoising needs no narrow bottleneck: the task "recover from corruption" itself forces the network to learn the structure of the data. The DAE's output minus its input points toward denser data (Section 5: it is proportional to the gradient of the log density of the noised data, the score). Push the idea all the way, training a denoiser at many noise levels and then denoising step by step, and you have a diffusion model (Lesson 19.6).

    5数学The math

    提示:把鼠标悬停在公式中带底色的符号上,图中对应的元素会被高亮(FIG 1 的编码颜色、解码器曲线、编码圆环和重建点,FIG 3 的两条直线,FIG 5 的加噪输入行,FIG 6 的距离曲线)。Tip: hover the highlighted symbols in the formulas; the matching element lights up (FIG 1's code colours, decoder curve, code ring and reconstructions; FIG 3's two lines; FIG 5's noisy-input row; FIG 6's distance curves).

    目标函数与梯度Objective and gradient

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

    Given data \(\mathbf x_1,\dots,\mathbf x_N\in\R^D\), an encoder \(f_\phi:\R^D\to\R^k\) and a decoder \(g_\theta:\R^k\to\R^D\), training minimizes the reconstruction loss

    $$ \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\) 反传过编码器:

    Every error on this page is this "mean squared error per component". Choosing the squared error amounts to assuming \(\mathbf x=\hat{\mathbf x}+\) Gaussian noise and doing maximum likelihood (Lesson 4.6); for images with pixels in 0 to 1 that are nearly binary, a per-pixel binary cross-entropy (a Bernoulli likelihood) is also common. The gradient is backpropagation through the two networks chained together (Lesson 16.3): first push \(\nabla_{\hat{\mathbf x}}\ell\) back through the decoder, which gives its parameter gradients and the gradient with respect to the code, \(\partial\ell/\partial\mathbf z\); then push \(\partial\ell/\partial\mathbf z\) back through the encoder:

    $$ \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。

    Each term is a vector–Jacobian product of Lesson 16.3 and costs a small multiple of a forward pass. That is literally how the page's code is written: the decoder's backward returns \(\partial\ell/\partial\mathbf z\), which is handed to the encoder's backward.

    线性自编码器 = PCA 子空间Linear autoencoder = PCA subspace

    设数据已中心化(偏置的最优值恰好做这件事),排成 \(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}\),总误差是

    Let the data be centred (the optimal biases do exactly that) and stacked into a \(D\times N\) matrix \(X\) with SVD \(X=U\Sigma V^\top\) (Lesson 1.12); the first \(k\) columns of \(U\), \(\hl{pc}{U_k}\), are the first \(k\) principal directions. A linear autoencoder has \(\mathbf z=E\mathbf x\) and \(\hat{\mathbf x}=\hl{W}{W}\mathbf z\) with \(E\in\R^{k\times D}\) and \(W\in\R^{D\times k}\), and its total error is

    $$ \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\),

    The inequality holds because \(WEX\) has rank at most \(k\), and the right side is the best rank-\(k\) approximation error of the Eckart–Young theorem (Lesson 1.12); the equivalence on the right holds when \(\sigma_k>\sigma_{k+1}\), because then the best rank-\(k\) approximation is unique, namely \(U_kU_k^\top X\). So at the global optimum the column space of \(W\) is \(\operatorname{span}(U_k)\) and the error equals PCA-\(k\)'s. But the particular \(W\) is not unique: for any invertible \(k\times k\) matrix \(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 的折痕)。

    gives the same reconstruction. FIG 3's "code ×2" is \(A=\tfrac12\) (with \(k=1\)), so the \(k\) coordinates of the code are in general some mixture of principal components rather than the components themselves. To recover the principal directions, run PCA once more on the learned \(k\)-dimensional codes (only \(k\times k\), cheap). Baldi and Hornik (1989) proved even more: this loss has no bad local minima, and every critical point other than the global optimum is a saddle, which is why FIG 3 converges from any start. With nonlinearities this guarantee is gone (FIG 1's plateaus, FIG 2's creases).

    去噪自编码器学的是 scoreA denoising autoencoder learns the 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 公式把它写成:

    The DAE minimizes \(\mathbb E_{\mathbf x,\boldsymbol\varepsilon}\|\mathbf x-r(\hl{noise}{\tilde{\mathbf x}})\|^2\) with \(r=g_\theta\circ f_\phi\), \(\tilde{\mathbf x}=\mathbf x+\sigma\boldsymbol\varepsilon\) and \(\boldsymbol\varepsilon\sim\mathcal N(0,I)\). Taken one \(\tilde{\mathbf x}\) at a time, the minimizer of a squared error is the conditional mean (the MMSE estimate); for Gaussian corruption Tweedie's formula writes it as

    $$ 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\) 上训练。

    Here \(p\) is the data density and \(p_\sigma\) its convolution with the noise (the density of the noised data). So for a large enough DAE, output minus input is \(\sigma^2\) times the score of the noised data density: a vector field pointing toward denser data. Vincent (2011) connected this to score matching, and Alain and Bengio (2014) analysed the \(\sigma\to0\) limit. It is exactly what the diffusion models of Lesson 19.6 train, only there at many values of \(\sigma\) at once.

    稀疏与收缩自编码器Sparse and contractive autoencoders

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

    Instead of narrowing the code one can constrain it in other ways, and then the hidden layer may even be wider than the input (overcomplete). A sparse autoencoder penalizes the hidden activations \(\mathbf h=f_\phi(\mathbf x)\) so that each input switches on only a few units:

    $$ \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 的效果相近。

    The first is an L1 penalty; the second form, \(\mathcal L''\) (sigmoid hidden units, pulling each unit's mean activation \(\hat\rho_j\) toward a small target \(\rho\) such as 0.05), comes from Ng's lecture notes. Trained on natural image patches, the units of a sparse code tend to become localized edge detectors. A contractive autoencoder (Rifai et al., 2011) penalizes the encoder's Jacobian, \(\lambda\|\partial f_\phi/\partial\mathbf x\|_F^2\), making the code insensitive to small perturbations off the manifold, with an effect similar to the DAE's.

    为什么普通自编码器不能生成Why a plain autoencoder cannot generate

    要生成,需要一个能采样的分布 \(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)。

    Generating requires a distribution \(p(\mathbf z)\) we can sample from, with the decoder trained on most of its mass. A plain AE only ever touches the \(N\) points \(f_\phi(\mathbf x_i)\); "the code distribution" is their empirical distribution, with a shape the optimizer chose arbitrarily (FIG 4's gaps, creases and sheets). Nothing in the loss penalizes what the gaps decode to. The VAE's two changes address exactly these problems: the encoder outputs a distribution \(q_\phi(\mathbf z\mid\mathbf x)\) instead of a point, so the decoder is trained on a whole blob around each code; and a term \(\operatorname{KL}(q_\phi(\mathbf z\mid\mathbf x)\,\|\,\mathcal N(0,I))\) makes all codes together fill a standard normal, so that one can sample from \(\mathcal N(0,I)\) (Lesson 19.1 derives the ELBO).

    6在机器人中:用编码做控制In robotics: control with a learned code

    自编码器在机器人里最直接的用途,是把相机图像变成控制器能用的低维状态。一个最简单的视觉伺服:给机器人一张“目标图像”,让它移动物体,直到当前图像和目标图像一致。用什么来衡量“一致”?最直接的是像素距离 \(\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)机器人先验。

    The most direct use of autoencoders in robotics is turning camera images into a low-dimensional state a controller can use. Take the simplest visual servoing: give the robot a "goal image" and let it move the object until the current image matches the goal image. How do we measure "matches"? The obvious choice is the pixel distance \(\hl{dpix}{\|\mathbf x-\mathbf x_g\|^2}\); another is the code distance \(\hl{dlat}{\|f_\phi(\mathbf x)-f_\phi(\mathbf x_g)\|^2}\).

    The figure shows a disc on a rail (1 degree of freedom) in 20×6-pixel camera images. Each tick the robot moves the disc 0.1 pixel left or right, choosing the direction that lowers the distance, and stops when neither does (greedy descent). Two 120→24→1→24→120 autoencoders train side by side: a plain one, and one that also asks that the codes of neighbouring frames be close, adding \(\lambda\,(z(\mathbf x_t)-z(\mathbf x_{t+1}))^2\) with \(\lambda=0.5\) to the loss, where the two frames' disc positions differ by less than 0.3 pixel, like consecutive frames of a video the robot records. This is the "slowness" robotic prior of Jonschkowski and Brock.

    FIG 6视觉伺服:像素距离、普通编码与慢变编码Visual servoing: pixel distance, a plain code and a slow code
    上:相机图像(像素亮度画成青色的不透明度),空心圆环是目标位置。中:编码 \(z\) 随圆盘位置变化的曲线(每条都缩放到 0 到 1),琥珀色为普通 AE,蓝色为加慢变项的 AE。下:当前目标下“到目标的距离”随圆盘位置的变化(各自缩放到 0 到 1):紫色为像素距离,琥珀色和蓝色为两种编码距离;选中的方法画得更粗,竖虚线是目标,实心点是圆盘当前位置。 Top: the camera image (pixel intensity as cyan opacity); the hollow ring is the goal position. Middle: the code \(z\) as a function of disc position (each curve rescaled to 0 to 1), amber for the plain AE, blue for the AE with the slowness term. Bottom: "distance to the goal" against disc position for the current goal (each rescaled to 0 to 1): purple for the pixel distance, amber and blue for the two code distances; the selected method is drawn thicker, the dashed vertical line is the goal and the filled dot is the disc's current position.
    • 方法选“像素距离”,起点和目标相距至少 6 像素(默认 3 和 16 即可),按“运行伺服”:圆盘最多挪动零点几个像素就停下,离目标还很远。两个圆盘不重叠时,像素距离与它们相距多远无关,没有指向目标的下降方向。Choose "pixel distance", keep start and goal at least 6 pixels apart (the defaults 3 and 16 do), and press "Run servo": the disc moves a few tenths of a pixel at most and stops, still far from the goal. When the two discs do not overlap the pixel distance does not depend on how far apart they are, so there is no descent direction toward the goal.
    • 训练到两个自编码器的误差都低于 0.01(约 1500 步),方法选“普通 AE”,起点与目标相距至少 6 像素,运行伺服:圆盘停在离目标 1 像素以上的地方。看中间那条琥珀色曲线:编码在某处突然跳变,伺服卡在跳变处。Train until both autoencoders are below 0.01 error (about 1500 steps), choose "plain AE", keep start and goal at least 6 pixels apart and run the servo: the disc stops more than 1 pixel from the goal. Look at the amber curve in the middle panel: the code jumps somewhere, and the servo gets stuck at the jump.
    • 同样的起点和目标,方法选“AE + 慢变”,运行伺服:圆盘到达目标 0.5 像素以内。With the same start and goal choose "AE + slowness" and run the servo: the disc ends within 0.5 pixel of the goal.

    像素距离的伺服从起点 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),说明重建误差根本看不出编码能不能用来控制。按“新种子”可以自己看这种差异。

    The pixel-distance servo does not move at all from start 3; trying starts all along the rail, it moves 0.3 pixel at most and stops at a sub-pixel position where the disc's own image has the smallest sum of squares (see question 5 of Section 8). With the default seed (3), after 2000 steps the plain AE's code jumps at a disc position of about 7.7 pixels, and the servo from start 3 stops at about 7.7; the slow AE's code is monotone and the servo reaches the goal at 16 in 130 ticks. We tried seeds 1 to 10 in node: the plain AE's code jumped or turned back for 7 of them, while the slow AE's code never jumped for any of the 10 and reached the goal from every start–goal pair at least 6 pixels apart. Both reconstruct well (errors below 0.01; about 0.006 and 0.003 with the default seed), so reconstruction error simply does not tell whether a code is usable for control. Press "New seed" to see the variation yourself.

    真实系统Real systems

    从像素做强化学习: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 本身就是一种“遮住大部分再重建”的自编码器。

    RL from pixels: Lange and Riedmiller (2010) first compressed raw images into a very short code with a deep autoencoder and then ran batch reinforcement learning on the code, an early example of this route. The deep spatial autoencoder of Finn et al. (2016) uses a spatial softmax at the code layer to output a set of 2D "feature point" coordinates, with which a PR2 robot learned visuomotor skills from images; feature points behave more like object positions than an ordinary code does. SAC+AE (Yarats et al., 2021) trains an autoencoder's reconstruction loss as an auxiliary task together with SAC on DeepMind Control tasks from pixels and clearly improves sample efficiency. World models: methods of the Dreamer family (Lesson 24.3) predict the future in a learned latent space, partly trained with a reconstruction loss, while the TD-MPC family does not reconstruct images. Anomaly detection: an autoencoder trained only on normal data reconstructs unseen situations worse, and its reconstruction error is a common simple failure or out-of-distribution detector. Pretrained visual encoders: today robots more often use encoders pretrained by contrastive learning or masked reconstruction (MAE) (Lessons 18.3 and 18.4); MAE is itself an autoencoder that hides most of the input and rebuilds it.

    7常见误区Common pitfalls

    误区 1:重建误差低,编码就好用Pitfall 1: low reconstruction error means a useful code

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

    In FIG 6 the two autoencoders reconstruct about equally well; one servoes, the other gets stuck at a jump. Reconstruction error only says the information is in the code, not that it is there in a smooth, comparable form. Another common trap on robots: the mean squared error treats every pixel alike, so a small object covering a few pixels (the gripper tip, the screw to grasp) barely contributes to the loss, and the autoencoder can blur it away at almost no cost, although it is exactly what the task needs. Judge a code by the downstream task (servoing, regressing positions, policy performance), not by reconstruction alone.

    误区 2:瓶颈宽度随便选Pitfall 2: picking the bottleneck width carelessly

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

    Too narrow (\(K=1\) in FIG 2, or one number for a circle in FIG 1) forces the network to fold or cut the data; too wide with no other constraint and the network can learn something close to the identity, copying the noise along. FIG 2 also shows that a width exactly equal to the number of degrees of freedom (\(K=2\)) is not necessarily the easiest to train: \(K=4\) is an order of magnitude lower. In practice sweep a few widths and combine them with regularizers such as denoising or sparsity rather than relying on a narrow bottleneck alone.

    误区 3:把普通自编码器当生成模型Pitfall 3: using a plain autoencoder as a generative model

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

    "Train it, then decode a random code" looks plausible, and FIG 4 shows it is unreliable: with \(K=8\) reconstructions are near perfect, yet only a little over a third of random codes decode to a disc. Linear interpolation between codes has the same problem, since the path can cross gaps or creases. When you need sampling or interpolation, use a method that actually models the distribution, such as a VAE (19.1), a diffusion model (19.6) or flow matching (19.7).

    误区 4:以为编码空间里的距离有意义Pitfall 4: assuming distances in the code space mean something

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

    On FIG 1's closed circle, points a few centimetres apart on either side of the cut get the most different codes; FIG 6's plain AE jumps somewhere. The autoencoder's loss has no term saying "nearby inputs should get nearby codes", so distances, directions and scales are not guaranteed (in FIG 3 even the linear case has an arbitrary scale). When codes must be comparable, add the constraint explicitly: a slowness or temporal prior (FIG 6), the positive and negative pairs of contrastive learning (18.3), or the VAE's KL term.

    误区 5:跳过 PCA 基线,或把线性 AE 的权重当主成分Pitfall 5: skipping the PCA baseline, or reading a linear AE's weights as principal components

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

    PCA is one line of code, has no hyperparameters and a unique answer, so always compute it first: if PCA at the same dimension is already good enough you do not need an autoencoder (hand joint synergies, for instance, are nearly linear). Conversely, a linear autoencoder learns only the subspace; the columns of its \(W\) are neither orthogonal nor ordered by variance (the \(A\) of Section 5), so do not read them as principal components. And do not forget to normalize the inputs: if components in different units (metres and radians, pixels and forces) are not rescaled, the squared error is dominated by whichever is numerically largest, for PCA and AE alike.

    8小练习Check yourself

    1. 在 \(\R^{10}\) 中已中心化、特征值互不相同的数据上,把 \(k=2\) 的线性自编码器训练到全局最优。解码器 \(W\) 的两列是什么?1. A linear autoencoder with \(k=2\) is trained to its global optimum on centred data in \(\R^{10}\) whose eigenvalues are all distinct. What are the two columns of the decoder \(W\)?
    由 Eckart–Young,最优处 \(WE=U_2U_2^\top\),所以 \(W=U_2A\),\(A\) 是任意可逆的 2×2 矩阵:列空间唯一(排除选项 D),具体的基不唯一(排除选项 A)。选项 C 只有在主方向恰好与坐标轴对齐时才对。FIG 3 的“编码 ×2”演示的就是这种不唯一。By Eckart–Young the optimum has \(WE=U_2U_2^\top\), so \(W=U_2A\) for an arbitrary invertible 2×2 matrix \(A\): the column space is unique (ruling out option D) but the particular basis is not (ruling out option A). Option C holds only if the principal directions happen to align with the coordinate axes. FIG 3's "code ×2" demonstrates this non-uniqueness.
    2. 对 144 像素的图像训练一个普通自编码器,隐层有 200 个单元、没有任何正则,训练足够久。最可能发生什么?2. A plain autoencoder with a 200-unit hidden layer and no regularization is trained long enough on 144-pixel images. What is most likely to happen?
    编码比输入还宽,“照抄”就是一个零误差的解,损失里没有任何东西阻止它。所以过完备的自编码器必须配合别的约束:去噪(FIG 5)、稀疏惩罚或收缩惩罚。选项 B 不成立:144 维数据最多只有 144 个主成分,而且非线性网络也不等价于 PCA。With a code wider than the input, "copy" is a zero-error solution and nothing in the loss rules it out. So an overcomplete autoencoder needs another constraint: denoising (FIG 5), a sparsity penalty or a contractive penalty. Option B fails: 144-dimensional data have at most 144 principal components, and a nonlinear network is not equivalent to PCA anyway.
    3. 一个容量足够的去噪自编码器用高斯噪声 \(\sigma\) 训练到最优。对加噪输入 \(\tilde{\mathbf x}\),向量 \(r(\tilde{\mathbf x})-\tilde{\mathbf x}\) 指向哪里?3. A denoising autoencoder with enough capacity is trained to optimality with Gaussian noise \(\sigma\). For a noisy input \(\tilde{\mathbf x}\), where does the vector \(r(\tilde{\mathbf x})-\tilde{\mathbf x}\) point?
    平方误差的最优解是 \(\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)。The minimizer of a squared error is \(\mathbb E[\mathbf x\mid\tilde{\mathbf x}]\), and Tweedie's formula gives \(\mathbb E[\mathbf x\mid\tilde{\mathbf x}]-\tilde{\mathbf x}=\sigma^2\nabla\log p_\sigma(\tilde{\mathbf x})\). It is a posterior-weighted average over all possible clean samples, not the single nearest one (option B); it approaches the data mean only for very large noise (option C); and the identity has error \(\sigma^2\) per component on noisy inputs, so it is not optimal (option D).
    4. 一个重建几乎完美的普通自编码器,为什么解码随机编码时经常得到不像数据的东西?4. Why does a plain autoencoder with near-perfect reconstructions often decode random codes into things that do not look like data?
    FIG 4:\(K=8\) 时编码只是 8 维空间里的一张二维薄片,从拟合的高斯里采样只有约 37% 解码成圆盘,而测试图的重建 100% 合格,所以问题不在解码器的容量(选项 A)或模糊(选项 C)。VAE 用编码分布和 KL 项解决的正是选项 D 的问题。FIG 4: with \(K=8\) the codes form a thin two-dimensional sheet in 8-dimensional space, and only about 37% of samples from the fitted Gaussian decode to a disc while 100% of the test reconstructions are valid, so the problem is neither decoder capacity (option A) nor blur (option C). What the VAE fixes with its code distribution and KL term is exactly option D's problem.
    5. FIG 6 的圆盘半径 \(R=1.8\) 像素,边缘还有 1 像素的线性过渡(亮度从圆心距离 \(R-0.5\) 处的 1 降到 \(R+0.5\) 处的 0)。两个圆盘的圆心相距超过多少时,像素距离就不再取决于它们相距多远?5. FIG 6's disc has radius \(R=1.8\) pixels plus a 1-pixel linear edge (intensity falls from 1 at distance \(R-0.5\) from the centre to 0 at \(R+0.5\)). Beyond what centre separation does the pixel distance between two discs no longer depend on how far apart they are?
    每个圆盘的非零区域半径是 \(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\)。Each disc's nonzero region has radius \(R+0.5=2.3\) pixels; once the centres are more than \(2\times2.3=4.6\) pixels apart the discs do not overlap at all, the cross term \(-2\,\mathbf x^\top\mathbf x_g\) vanishes and \(\|\mathbf x-\mathbf x_g\|^2=\|\mathbf x\|^2+\|\mathbf x_g\|^2\). \(\|\mathbf x\|^2\) only ripples by a few percent with the disc's sub-pixel position on the pixel grid and has nothing to do with where the goal is. So FIG 6's greedy servo only shifts to a nearby sub-pixel position where \(\|\mathbf x\|^2\) is smallest and stops. Option B is \(2R\), ignoring the soft edge.

    9延伸阅读Further reading

    • D. E. Rumelhart, G. E. Hinton & R. J. Williams, Learning Internal Representations by Error Propagation, in Parallel Distributed Processing, Vol. 1, MIT Press, 1986 — 反向传播,以及用“编码器问题”训练窄隐层还原输入的早期例子backpropagation, with the "encoder problem" as an early example of a narrow hidden layer trained to reproduce its input
    • H. Bourlard & Y. Kamp, Auto-Association by Multilayer Perceptrons and Singular Value Decomposition, Biological Cybernetics, 1988 — 线性自联想网络与 SVD 的关系linear auto-association and its relation to the SVD
    • P. Baldi & K. Hornik, Neural Networks and Principal Component Analysis: Learning from Examples Without Local Minima, Neural Networks, 1989 — 线性自编码器的损失曲面:全局最优是 PCA 子空间,其余临界点都是鞍点the loss landscape of the linear autoencoder: the global optimum is the PCA subspace and all other critical points are saddles
    • G. E. Hinton & R. R. Salakhutdinov, Reducing the Dimensionality of Data with Neural Networks, Science, 2006 — 深度自编码器在图像上明显优于 PCAdeep autoencoders clearly beating PCA on images
    • P. Vincent, H. Larochelle, Y. Bengio & P.-A. Manzagol, Extracting and Composing Robust Features with Denoising Autoencoders, ICML 2008 — 去噪自编码器the denoising autoencoder
    • 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 的联系the link between denoising and the score
    • S. Rifai, P. Vincent, X. Muller, X. Glorot & Y. Bengio, Contractive Auto-Encoders: Explicit Invariance During Feature Extraction, ICML 2011 — 收缩自编码器the contractive autoencoder
    • I. Goodfellow, Y. Bengio & A. Courville, Deep Learning, MIT Press, 2016, Ch. 14 — 自编码器一章:欠完备、正则化、稀疏、去噪、收缩the autoencoder chapter: undercomplete, regularized, sparse, denoising, contractive
    • S. Lange & M. Riedmiller, Deep Auto-Encoder Neural Networks in Reinforcement Learning, IJCNN 2010 — 先压缩图像、再在编码上做强化学习compress images first, then do reinforcement learning on the code
    • R. Jonschkowski & O. Brock, Learning State Representations with Robotic Priors, Autonomous Robots, 2015 — 慢变等物理先验用于学习状态表示slowness and other physical priors for learning state representations
    • C. Finn, X. Y. Tan, Y. Duan, T. Darrell, S. Levine & P. Abbeel, Deep Spatial Autoencoders for Visuomotor Learning, ICRA 2016 — 特征点编码用于真实机器人的视觉运动学习feature-point codes for visuomotor learning on a real robot
    • 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:重建作为辅助损失SAC+AE: reconstruction as an auxiliary loss