主动推理-反向传播 2026年07月04日 00:24发言人 00:00从JPG没journey到alphago以及各种大脑模型几乎所有的机器学习系统有什么共同点尽管它们被设计用来解决不同的问题拥有截然不同的架构并在不同数据上进行训练但他们都有一个共同点这是在所有这些情况下所有训练过程中隐藏的单一算法。这个名为反向传播的算法是整个机器学习领域的基石尽管它的细节经常被忽视。令人惊讶的是使人工网络学习的能力也正是他们本质上与大脑不同并与生物学相悖的地方。发言人 00:44这是系列视频的第一期。今天我们将深入探讨人工系统中的反向传播概念建立对它的直观理解理解其运作原理以及如何从头开始构建它。在下一段视频中我们将关注生物大脑中的突触可塑性探讨反向传播是否具有生物学相关性如果不相关大脑可能会使用哪种类型的算法。如果你感兴趣敬请期待。发言人 01:24尽管它带来了革命性的影响但很难追溯到底是谁最先发明了反向传播因为某些原理可以追溯到17世纪的莱布尼茨。然而人们普遍认为现代反向传播算法的首次完整表述是由sample linemen在他1970年的硕士论文中发表的尽管他并未明确提及神经网络。1986年roman heart j hinton和rao的威廉热门发表了一篇名为通过反向传播误差学习表示的论文。这是一个重要的里程碑他们将反向传播算法应用于多层感知机首次展示了通过反向传播训练能够使网络成功解决问题在隐藏神经元层形成有意义的表示捕捉任务中的重要规律。随着领域的发展研究人员大幅度扩展了这些模型并引入了多种架构但训练的基本原则保持了高度相似。发言人 02:33为了全面理解网络训练的含义让我们从基础出发尝试构建反向传播的概念。思考以下问题假设你收集了一组平面点你想描述他们的关系。为了做到这一点你需要找到一个曲线来最好的描述数据。考虑到可能存在的无限函数我们不得不做出一些假设。例如假设我们想找到一个使用五次多项式对数据进行平滑近似的假设这意味着我们想要找到的曲线将会是常数项零次多项式的组合、极值线、抛物线以及一直到五次幂的所有组合每一个都有特定的系数来确定。换句话说这个曲线的方程为其中每个K都是任意的实数。我们的任务就是找到K0到K5的配置使得曲线能最好地适应数据。发言人 03:42为了使问题明确无误我们需要商定什么是最佳曲线的定义。虽然你可以直接通过可视化的数据点判断某个曲线是否捕捉到了模式但这种方法在处理大量数据时非常主观且不切实际。相反我们需要一个客观的度量标准一个能量化曲线拟和质量的数值。一种流行的方法是测量数据点到拟合曲线的平方距离。数值高表示数据点与曲线之间的距离大表明拟合较差。相反数值低表示较好的拟合因为曲线紧密的与数据点吻合这种测量通常被称为损失目标是尽可能的减小它。现在请注意对于固定的数据显示这种距离及损失的值仅仅取决于曲线的定义特征。发言人 04:44在我们的例子中就是从K0到K5的系数因此它实质上是参数的函数人们通常称之为损失函数。重要的是不要混淆我们在处理中暗含的两个不同的函数。第一个是函数埋它有一个输入数和一个输出数决定了曲线本身。它具有多项式形式由K的值给出。这样的函数有无穷多个我们希望找到最好的一个。为了做到这一点我们引入了一个损失函数它有六个输入从K0到K5的数值对于每个配置它构建对应的曲线来计算观察到的数据点和曲线之间的距离然后输出一个单一的数值即特定的损失值。接下来我们的任务就是找到使损失最小的K值配置或者说尽量使损失函数相对于这些系数最小化然后将这些最优的K值代入曲线的一般方程就将得到能最好描述数据的最佳曲线。发言人 05:59好的太棒了。但是我们如何找到那些能够最小化损失的神奇K值配置呢可能我们需要一些帮助。发言人 06:07我们来构建一个名为curve fitter 6000的机器其设计目的是简化手动计算。它配备了六个可调节的旋钮用于K0到K5。我们可以自由调整。首先我们将数据点初始化到机器中然后对于每个旋钮的设置它会评估曲线来计算它与数据点之间的距离并输出损失函数的值。现在我们可以开始旋转旋钮以找到最小的损失值。比如我们先从某个初始设置开始然后稍微将旋钮移向右调整相应的曲线也发生了变化。我们可以看到损失函数的值稍微降低了太好了这意味着我们在正确的方向上让我们再次向同一个方向转动旋钮一。这次拟合变差了损失函数反而增大了看来刚才那一波稍微过了头那么让我们把旋钮恢复到先前的位置试试旋钮2我们可以不断迭代的做很多次这种操作一次调整一个旋钮看看这样得到的曲线是否更合适这是所谓的随机扰动方法因为我们本质上是在黑暗中摸索事先不知道每一次调整会对损失函数产生什么影响这当然可以但效率不高。发言人 07:38有没有方法可以让我们在调整旋钮时更智能一些呢在最一般的情况下当机器完全是一个黑盒时确保存在比随机扰动更优的方法并不能保证。然而在很多计算中包括我们曲线拟合器背后的处理他们有一个特殊属性称为可微性这使得我们能够更高效地计算出最佳旋钮设定。我们稍后会深入探讨什么是可微性但目前我们先快速了解我们将要前往的大致概况。发言人 08:16我们的目标是改进机器让每个旋钮旁边都有一个小屏幕对于任何配置这些屏幕都应该显示。为了降低损失函数你需要将每个旋钮往哪个方向推动以及需要推动多少请花点时间思考一下。我们本质上是在请求机器预测未来估算旋钮调整对损失函数的影响而无需实际进行调整计算损失。然后像之前那样来回滚轮这种窥探未来是否违反了某种原则呢毕竟我们是在跳到未经执行的计算结果这听起来像是作弊对吧实际上这个理念建立在非常简单的数学基础上所以让我们花点时间从头开始构建它。发言人 09:16好的我们先考虑一个简单的情况即固定五个旋钮中的六个。例如假设有人告诉你其他旋钮已经在最优位置了所以你只需要找到剩下的一个旋钮的最佳值。本质上机器现在只有一个可调整的参数K1因此损失函数也是一个更简单的函数。它接受一个数字即旋钮设置然后输出另一个数字即损失值。作为单变量函数它可以方便的在二维平面上以图形表示这捕捉了输入和输出之间的关系。比如它可能呈现出这样的形状我们的目标是找到K一的值它对应于损失函数的最低点但我们无法访问到真实的底层形状。发言人 10:08我们能做的只是将旋钮设置在选定的位置并间接询问机器关于损失的值。换句话说我们只能沿试图最小化的函数采样个别点。在我们采样之前我们实际上对这些已知点之间的函数行为一无所知。但是如果我们想知道关于函数的更多信息而不仅仅是每个点的值比如想知道在这个点上函数是上升还是下降这些信息将最终指导我们的调整。因为如果你知道随着输入增加函数是在下降的那么向右转动旋钮是一个安全的选择因为你可以确保通过这个操作来减少损失。发言人 10:55让我们将这个关于点周围上升或下降的概念放在更坚实的数学基础上。假设我们已经在图形上采样了一个点我们可以稍微增加输入每次都用增量delt x新的调整输入会导致麦值的改变急呆的麦这个变化值取决于调整幅度的大小。比如如果我们采取比原来小十倍的增量delt x那么delta my也将大约是原来的10分之1。这就是为什么计算输出变化量data y除以输入变化量data x的比率是有意义的。即每单位输入变化对应的输出变化量。在图形上这个比率对应于通过点和两点的直线的斜率。发言人 11:53注意当我们采取越来越小的步长时这条直线将越来越准确的雨点附近图形对齐。让我们取随着dealt x趋近于无穷小时这个比率的极限。当det x趋近于无穷小时这个比率收敛的极限值即为函数的导数黑。并用ddx表示直观来说函数在某一点的导数是与图形相切的直线的斜率它反映了该函数在这一点处的瞬时变化率或陡峭程度。然而图谱上的不同点可能具有不同的陡峭程度所以整个函数的导数不是一个单一的数字。实际上DDX导数本身是一个关于X的函数它接受任意的X值并输出埋在其处的局部陡峭程度。这个定义为每个函数赋予了它的导数对应物。另一个在相同输入范围内操作的函数它包含了关于原始函数陡峭性的信息。发言人 13:14有一点微妙之处严格来说如果函数在某点没有陡峭性那么导数可能不存在。例如如果它有锋利的拐角或中断点但在视频的剩余部分我们将假设我们处理的所有函数都是光滑的因此导数总是存在。这是一条合理的假设因为在构建模型时我们可以控制输入到我们模型中的函数类型人们通常会限制所有内容到光滑或可微分的函数以便于所有数学运算顺利进行。发言人 13:51好的太棒了。现在除了我们无法看见的作为KE函数的底层损失外我们还可以推断其导数。另一个关于K1的函数我们同样不知道它对应于该点损失函数的陡峭程度。假设我们像查询损失函数那样通过运行机器并获取个别样本也有一个机制可以让我们样本化导数函数。因此对于K一的每个输入值机器将输出损失的值以及该点处的损失函数的局部陡峭程度。发言人 14:32请注意这个导数信息正是我们想要洞察未来以便更智能的调整旋钮的关键信息。例如我们可以用它有效的找到K一的最优值。我们能做的如下首先从某个随机位置开始询问机器在该位置的损失值和损失函数的导数值。沿着相反与导数的方向迈出一小步如果导数为负这意味着函数在下降。因此如果我们想到达最小值我们需要朝K一直增大的方向移动重复此过程直到你到达导数为零的点。这实际上对应于最小值那里切线是平直的。本质上这种有引导的每次调整就像一个小球沿着图表的斜坡向下滚动直到到达一个山谷。发言人 15:37尽管最初为了简化我们冻结了六个旋钮中的五个但这个过程可以很容易的扩展到更高维度。例如现在我们有自由调整两个不同的旋钮K1和K2损失将变成两个变量的函数可以视为一个表面。但是导数回想一下根据定义每个点的导数告诉我们输出如何随输入的一个单位变化而变化。但现在我们有两个不同的输入我们只调整K1K2还是两者都调整。实质上我们的函数会有两个不同的导数通常称为偏导数。发言人 16:23因为这种情况下存在输入选择的模糊性即当我们有两个旋钮时损失函数对参数K一的导数会这样表示。它是当K2保持不变时输出如何随着K一的单位变化而变化的量相反。这个表达式告诉你如果保持K一不变并稍微调整K2时输出的变化率几何上你可以想象用平行于坐标轴的平面切过这个表面这些平面在我们感兴趣去的点K1和K2处相交。这样每一个截面就像一个二维图形损失作为其中一个变量的函数而另一个变量保持恒定然后每个截面切线的斜率将给出相应于该点的损失的偏导数。发言人 17:23尽管将偏导数视为两个单独的表面每一个对应一个变量是一个完全有效的思考方式但人们通常会将两个不同的值输入到称为梯度向量的矢量中。实质上这是一张映射从两个输入值到另外两个数字。其中第一个表示输出随第一个输入微小变化时的改变量。类似的对于第二个输入几何上这个向量指向斜率最大的方向。因此如果我们想要最小化一个函数如我们的损失函数就需要沿着这个梯度的相反方向进行步骤沿着梯度向量反方向调整参数的这种迭代过程称为梯度下降这可能你已经听说过了。发言人 18:19在二维情况下这类似于小球沿山坡滚动偏导数本质上告诉你哪个方向是下坡。超过二维就无法直接可视化但数学原理保持不变。例如如果我们现在可以调整所有六个旋钮那么损失函数就在六个维度的超曲面上。这时梯度向量将包含六个数值但它仍然指向陡峭上升的方向。所以如果我们迭代的朝相反方向走小步就像在六维空间滚动小球下坡最终会找到损失函数的最小值。好让我们稍微回溯一下你还记得我们寻找如何在每个旋钮旁边添加屏幕以给出最佳调整方向的方法吗它本质上不过是梯度向量的分量而已。发言人 19:22如果某配置下损失对K一的偏导数为正这意味着增加K一会导致损失增加。所以我们需要通过向左拧转旋钮来降低其值。其他所有参数也是如此。这就是如何通过提供关于函数局部行为的信息导数作为洞察未来的窗口。有了获取导数的方法我们就可以进行梯度下降有效的找到损失函数的最小值从而解决优化问题。然而有一个显而易见的问题到目前为止我们一直假设导数信息已经提供给我们或者我们可以在给定点上采样导数就像读取损失函数的值一样通过运行机器的计算。但实际上你是如何找到导数的呢正如我们后面会看到的这就是反向传播算法的主要目标。本质上我们找到任意复杂函数的导数的方法如下。发言人 20:34首先我们有一些基本的构建作为起始点。简单的函数其导数是微积分学中已知的这些都是你常说在大学里可能会记住的导数公式。例如如果函数是线性的显然它的导数在任何地方都将是一个常数等于那条直线的斜率与自身的切线相符。抛物线X2随着X的增加而变得更陡峭其导数实际上是2X实际上X的N次方的导数有一个更一般的公式。类似的指数和对数的导数也可以写出具体的表达式但这些都是简单且众所周知函数的个别例证。为了计算任意导数我们需要一种方法来组合这些基本的构建模块。有一些规则可以指导我们进行。例如两个函数之和的导数就是两个函数导数之和对两个函数乘积的导数也有一个公式这时我们能够计算像3X2减去X这样的东西的导数。发言人 21:53为了完整理解并能够找到几乎所有函数的导数我们需要另一个规则叫做链式规则。它推动了整个机器学习领域的发展。他告诉你如何计算当其中一个函数是另一个函数的输入时两个函数组合的导数这是理解他的一个方法。假设你有这样一个简单的机器它接收单个输入X你可以通过旋钮调整然后输出J。接下来你有一个类似的第二种机器它执行不同的函数F。如果将它们顺序连接起来使得第一个机器的输出作为第二个机器的输入会发生什么注意这样的构造可以看作是一个单一的函数它也接收一个输入数字并通过计算两个简单函数的复合生成输出。实际上如果你在它周围加上一个黑盒来隐藏两个机器依次运行的事实你就可以将它视为一个单一的机器。发言人 23:11然后问如果我轻微调整输入它会如何影响另一端的输出换句话说复合函数的导数是多少假设我们知道两个机器F和J的各自导数当旋钮设在某个GX时我们计算第一个函数在X处的局部陡峭度。然而输入第二个机器的数值并不是X因为它已经被第一个函数处理过了因此输入第二个函数的是J因此第二个机器的局部变化率就是F在J处的导数。现在想想你稍微调整旋钮X微小的变化从第一个机器出来的这个输入微调会乘以G的导数。因为导数是输入单位变化时输出的微小变化率因此经过第一个函数后输出会增加delt乘以J的导数。这个表达式实质上是对第二个机器输入的微小推动其在该点的导数即为这个表达式所给出的值。这意味着对于输入的每一个微小增加我们将输出增加这么多。因此当你将这个除以呆子后倒梳会看起来像这样。发言人 24:46你可以将其想象成一组三个相互连接的齿轮。第一个代表输入旋钮X而其余两个齿轮分别代表函数J和F。当你推动第一个齿轮时它会在中间齿轮引起一个推动这个变化的幅度由J的导数决定进而导致第三个齿轮旋转。这个最终推动的幅度通过将导数串联起来计算得出。发言人 25:19好了太棒了。现在我们得到了一个获取任意复杂函数导数的直接方法。只要这个函数可以分解为基本单元拥有明确导数公式的简单函数比如求和、乘法、指数对数等。但是我们如何使用它来找到最佳曲线通过我们的曲线拟合器我们追求的大图景是这样的。对于每个参数旋钮我们将用简单的可微分的操作来描述它对损失的影响。一旦我们有了这样的基本组件序列不管多长长我们都可以依次应用链式规则来计算每个输入旋钮对损失函数导数的值并通过迭代梯度下降来最小化损失。发言人 26:16让我们看一个实际的例子。首先我们会为损失函数可能依赖的每个数字创建一个旋钮。这显然包括参数但也包括数据本身。我们最初要拟合曲线的点的坐标。现在在优化过程中数据点一旦设定就无法更改。因此为了降低损失而改变他们是没有意义的。但从概念上讲我们可以把这些值视为固定在某个位置的旋钮无法移动。发言人 26:55一旦我们输入了所有的现有数值就可以开始分析损失的计算过程。记住定义上来说它就是每个点到UK参数化的曲线的垂直距离平方和。以第一个数据点X1Y1为例将X坐标乘以K1将这个与X1的平方乘以K2的结果相加和其他K值类似。这个X一的加权和雨密是当前曲线F预测的Y值。我们称它为Y一的估计值。接着我们需要计算实际值和预测值之间的平方差这是第一个数据点对最终损失函数值的贡献。对所有剩余数据点重复同样的过程将得到的平方距离相加就得到了我们试图最小化的总损失。发言人 28:10我们刚刚完成的计算即根据给定的参数和数据旋钮配置求得损失值这一过程被称为前向传播。整个计算序列可以通过这种计算图表示其中每个节点代表诸如加法或乘法等简单运算。前向传播则对应着从左到右的计算流程。发言人 28:41然而为了进行优化我们还需要知道梯度信息即每个旋钮如何影响损失。现在我们要做所谓的反向步骤逆向展开计算序列找到偏导数。反向步骤之所以成为可能是因为计算图中的每个节点都是可微分的运算。把单个节点想象成那些执行加法、乘法或曲密的微小机器。我们知道它们的导数因为它们的输出是顺序连接的我们可以应用链式规则。这意味着对于每个节点我们可以找出它的梯度即输出损失对该节点的偏导数。发言人 29:34现在我们来看看怎么做设想计算图中有一个区域两个数字节点A和B被输入一个执行加法的单元该单元的结果A加B在进一步被系统处理以计算总数出售。假设我们之前已经计算了A加B的梯度因此我们知道稍微调整和值对输出的影响。问题在于A和B的单独梯度各是多少呢直觉上对应的任何微小移动都将导致加B的同样程度的移动因此损失函数对应的梯度就是和的梯度。B的情况类似更严谨的说通过写出链式规则注意到A加上B对的导数就是一。换句话说当你在计算途中遇到这种情况时和的梯度会直接传递给那个相加运算单元的输入节点的梯度。发言人 30:48另一种可能的情况是何必相乘就像之前一样。假设我们知道他们的成绩的梯度因为我们之前已经计算过了。在这种情况下对A的单独微调会乘以B的因子因此乘积会被移动低倍这会传递到输出中。因此对于B乘积的输出导数其对应的输出导数会乘以B的因子而B的梯度也反过来以相同的原则。再次通过考察链式规则来更直观的看到这一点。换句话说在计算图中乘法节点通过将下游梯度乘以输入节点的值进行扩散以此分配梯度。对于其他构建块计算如数值的幂次运算或取对数也可以轻松地制定类似的规则。发言人 31:52最后当一个节点参与计算图的多个分支时对应分支的梯度直接相加。确实假设图中有这样的结构同一个节点也连接到两个不同的操作这两个操作都对整体损失有贡献。那么如果你对A座微调delta输出会同时受到第一个分支和第二个分支的梯度调整的影响因此对于进行微调的整体效果将是两个梯度的和好的。太棒了。发言人 32:28现在我们已经构建了计算图并理解了如何处理其中的独立部分。我们就按照顺序从输出开始逆向应用这些规则。例如图中右侧的节点是损失函数结果的值这个节点的微小变化如何影响输出它是输出所以其梯度按照定义等于一。接下来损失函数就是好多delt的平方和。我们了解求和节点的处理方式它只是把右边的梯度值复制到所有输入节点因此所有平方delta的梯度也将等于一。每个这样的节点对应的是相应delta y的平方值。我们了解如何对这个平方操作求导损失函数对delt买一的导数将是2乘以delta买1这正是我们从前向计算中找到的数值。发言人 33:34我们可以继续沿计算图像后反向传播逐个的导数计算直至抵达最左侧的节点。这些是数据和参数调整旋钮。对于输入数据的损失导数并不重要但对于参数的导数正是我们所关注的。一旦找到这些参数梯度我们就可以进行一次梯度下降迭代。具体来说我们将微调这些旋钮使其朝相反于梯度的方向调整。每个调整的精确幅度是梯度与一个被称为学习率的小数字的负乘积比如0.01。发言人 34:17请注意调整之后机器的配置及其产生的损失都已改变因此我们之前的就梯度值不再适用。因此我们需要再次运行前项和后项计算以获得更新的梯度和降低的损失。这一轮前向传播、后向传播、微调并重复正是训练所有现代机器学习系统的核心。发言人 34:50实际上相同的基本算法今日依然被用于最复杂的模型中。只要你试图解决的问题可以分解为可微分的独立操作并且采用给定模型架构你就可以依次应用链式法则多次最终找到参数的最佳设置。例如前馈神经网络本质上是一系列的乘法和求和运算其中夹杂着几层非线性激活函数每一个原子计算都是可微分的所以你可以构建计算图通过反向传播找出每个参数如神经元之间的连接权重如何影响损失函数。发言人 35:36由于神经网络理论上给定足够多的神经元能够理论上逼近任何可想象的函数所以我们可以通过构建足够大的这些数学模块、机器序列号来解决如图像分类甚至生成新文本等问题。这似乎是一个非常优雅且高效的解决方案毕竟如果你想解决优化问题导数会精确的告诉你需要做哪些调整。但这与大脑实际运作有多相似呢当我们学习走路、说话和阅读时大脑是否也在最小化某种损失函数他计算导数吗或者他是否在做完全不同的事情。在下一集中我们会深入探讨突触可塑性事件讨论生物神经网络是如何学习的。发言人 36:28考虑到生物学习的主题我想借此机会提一下short form这是本频道长期的合作伙伴。Shart form是一个能帮你提升阅读体验的平台他们提供书籍摘要内容精炼且富含深度你不仅能获得所有关键点的精炼版还会得到来自相关资源如其他书籍和研究论文的补充想法。我非常喜欢这个功能因为它能让你快速把握全局促进思想间的关联。现有的资源库涵盖了多种类型包括科学教育和技术等方面的书籍并且每周都有新书不断加入。就我个人而言我发现short form在选择书籍阅读和高效做笔记方面非常有价值。通过描述中的链接试一试吧你会享受到五天无限制访问和年度会员20%的优惠赶快去体验。发言人 37:29如果你喜欢这个视频请点个赞分享给你的朋友和同事。并且如果你还没有记得订阅我们的频道敬请期待更多有趣话题的到来再见。感谢你们对大脑的热爱与关注。