没有定义,没有凭空抛下的公式。你先拧动一个旋钮,直到输出的数字正好——并发现这件事(猜一个、量出误差、轻轻一推)就是学习的全部。你倾斜一条线把两种小虫分开;你遇到一种单凭一条线永远分不开的排布;你看一个细胞决定该放多大的电。你把几个细胞连成一张网,找到一次算完所有乘加的网格,把信号一路推到另一端。然后你把它倒着跑——把责任分摊到每根连线、在看不见的谷里摸索谷底、踏出最小而诚实的下坡一步——只有到这时,亲手搭出来之后,它才配得上“反向传播”这个名字。每一章都遵循同一条准则:把所有文字静音,单凭画面也照样讲清。取材自 Rashid《Python 神经网络编程》第 1 章,秉承 Petzold《编码》的精神。为从未见过神经元的人而建;也足够一位工程师的严谨。
一个只有一个旋钮的盒子,把公里换算成英里——可没人拨过这个旋钮。拨动它,看看与答案之间的差距,让差距的大小告诉你该往哪边、推多远。
两种花园里的虫子,按宽度和长度散落开来。拿一条直线横放上去,倾斜它的斜率——落在错误一侧的虫子会亮起来——直到每只宽的都在线下、每只长的都在线上。
一条线得同时穿过两个样本,可它办不到。把它贴上其中一个,另一边的差距就炸开;让两边的差距都全力拉扯,它就来回猛甩、永不停歇。每次只取一小片修正量,看它慢慢稳定下来。
正方形四个角上的四个点,按某条规则上色。放一条直线并倾斜它,把两种颜色分到两侧。有两条规则,一条线就够;可对第三条,无论怎么转,总有一个角被落在错误一侧。
一个细胞把输入加在一起,必须作答:是暗,还是亮?一道硬阈值从 0 猛地跳到 1,中间什么都没有。把这个拐角磨圆,同样地滑动输入,输出便缓缓抬起——却始终触不到两端。
一个个细胞,用线连起来。每根线传一股信号,每根线又有自己的强度,按这个强度去缩放它所传的信号。把一根线加粗,它喂的细胞就升高;把它细到没有,那股信号就再也到不了。拖动这些线,看每个数随之变化。
一个单元把两路信号相加,每路都被自己那根线缩放——一个和,手算出来。再加一个单元,算式就堆起来了。把强度排成一张网格,把信号排成一列,拿一行去扫过另一列,所有的和就一次落了出来。
一张三层的网,用的是书里的权重,输入是 (0.9, 0.1, 0.8)。把信号推进去,看它一列列填满:每个细胞先得到一个加权总和,然后放电——放电后的那一列又成了下一层的输入,一路推到最远端。
一个输出节点差了一截,喂养它的是两根粗细不同的线。这个误差,该怪谁?把它沿着线分摊回去——越粗的线担得越多——再把落到每个上游节点上的份额加起来。拖动一根线,看责任如何重新分摊。
一个小球停在暗谷的半坡上,谷底看不见。摸一摸球脚下的地往哪边倾斜,顺着坡往下走,让每一步越走越短,把球带到谷底安歇。
一个权重,一只光滑的误差碗。小球停在碗壁上。看清它正下方的那道倾斜——其实是三样朴素的东西相乘——然后顺着下坡挪动一小片,一次又一次,直到碗变平。
只有在那条柔和的 S 形曲线还有斜度的地方,一次轻推才教得动它。把总和推到很远的平坦端,斜率就死了——没什么可推的。把它拉回陡峭的中段,只去要曲线真正够得到的答案,再让每根连线起步都又小又分散,这样学习从第一步起就有斜度可用。