<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>深度学习 on Lumenth</title>
        <link>https://blog.lumenth.me/tags/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0/</link>
        <description>Recent content in 深度学习 on Lumenth</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-cn</language>
        <copyright>Lumenth</copyright>
        <lastBuildDate>Fri, 25 Sep 2026 16:21:31 +0800</lastBuildDate><atom:link href="https://blog.lumenth.me/tags/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>深度学习笔记3-反向传播</title>
        <link>https://blog.lumenth.me/p/backpropagation/</link>
        <pubDate>Sat, 19 Sep 2026 00:00:00 +0000</pubDate>
        
        <guid>https://blog.lumenth.me/p/backpropagation/</guid>
        <description>&lt;img src="https://blog.lumenth.me/p/backpropagation/wallpaper.png" alt="Featured image of post 深度学习笔记3-反向传播" /&gt;&lt;h1 id=&#34;反向传播&#34;&gt;反向传播
&lt;/h1&gt;&lt;p&gt;我在&lt;a class=&#34;link&#34; href=&#34;../MLP/&#34; &gt;多层感知机笔记&lt;/a&gt;中提到，感知机的学习规则只适用于单层网络，一旦引入隐藏层，隐藏层神经元的参数该调整多少就无从得知。反向传播（Backpropagation）就是解决这个问题的方法。&lt;a class=&#34;link&#34; href=&#34;https://www.bilibili.com/video/BV1Lg5T6SEmP?spm_id_from=333.788.videopod.sections&amp;amp;vd_source=89a95dedd08ac36719901ea65feaa34b&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;谦行AIing&lt;/a&gt;老师的视频讲解非常好，这里十分推荐。&lt;/p&gt;
&lt;p&gt;在学习反向传播前建议先理清几个后面会反复出现的&lt;a class=&#34;link&#34; href=&#34;../conception/&#34; &gt;关键概念&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&#34;一次训练的总体流程&#34;&gt;一次训练的总体流程
&lt;/h2&gt;&lt;p&gt;&lt;img src=&#34;https://blog.lumenth.me/p/backpropagation/workflow.png&#34;
	width=&#34;1567&#34;
	height=&#34;1004&#34;
	srcset=&#34;https://blog.lumenth.me/p/backpropagation/workflow_hu_fd59a157e167f8b9.png 480w, https://blog.lumenth.me/p/backpropagation/workflow_hu_7077decdf916b89d.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;156&#34;
		data-flex-basis=&#34;374px&#34;
	
&gt;&lt;/p&gt;
&lt;h3 id=&#34;初始化参数&#34;&gt;初始化参数
&lt;/h3&gt;&lt;p&gt;首先随机初始化所有权重 W 和偏置 b。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;权重不能全部取 0，也不能全部取成同一个值：那样同一层的每个神经元接收到的输入、算出的输出、得到的梯度都完全一样，无论训练多久都学不出不同的特征（对称性问题）。&lt;/li&gt;
&lt;li&gt;常见做法是取接近 0 的小随机数，并按该层的输入维度做缩放（如 Xavier 初始化、配合 ReLU 的 He 初始化），避免信号在一开始就被放大或衰减得太厉害。&lt;/li&gt;
&lt;li&gt;偏置通常直接初始化为 0 即可。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;同时还要定好学习率 η、迭代轮数等超参数。&lt;/p&gt;
&lt;h3 id=&#34;前向传播&#34;&gt;前向传播
&lt;/h3&gt;&lt;p&gt;从输入层开始，沿着 l = 1, 2, …, L 逐层往后算：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;第 l 层的净输入：z&lt;sup&gt;(l)&lt;/sup&gt; = W&lt;sup&gt;(l)&lt;/sup&gt;a&lt;sup&gt;(l−1)&lt;/sup&gt; + b&lt;sup&gt;(l)&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;第 l 层的输出：a&lt;sup&gt;(l)&lt;/sup&gt; = σ(z&lt;sup&gt;(l)&lt;/sup&gt;)&lt;/li&gt;
&lt;li&gt;输入层 a&lt;sup&gt;(0)&lt;/sup&gt; = x，最后一层的输出就是预测值 ŷ = a&lt;sup&gt;(L)&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这一步不更新任何参数，只是把输入一路算到预测值。&lt;strong&gt;每一层的 z 和 a 都要先存下来&lt;/strong&gt;，反向计算梯度时会直接复用这些数。&lt;/p&gt;
&lt;h3 id=&#34;计算损失函数&#34;&gt;计算损失函数
&lt;/h3&gt;&lt;p&gt;把预测值 ŷ 和真实标签 y 代入损失函数，得到一个标量 L，用来衡量这次预测有多差：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;回归任务：均方误差 &lt;code&gt;L = ½ ‖ŷ − y‖²&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;二分类任务：Sigmoid 输出 + 交叉熵 &lt;code&gt;L = −[y·log ŷ + (1−y)·log(1−ŷ)]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;多分类任务：Softmax 输出 + 交叉熵 &lt;code&gt;L = −Σᵢ yᵢ·log ŷᵢ&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;反向传播求的是&amp;quot;L 对每个参数的变化率&amp;quot;，所以损失函数必须可导。这也是为什么要用 Sigmoid、ReLU 这类激活函数，而不是&lt;a class=&#34;link&#34; href=&#34;../Perceptron/&#34; &gt;感知机&lt;/a&gt;里的阶跃函数——后者处处导数为 0、在 0 处还不可导，梯度根本传不下去。&lt;/p&gt;
&lt;h3 id=&#34;反向传播-1&#34;&gt;反向传播
&lt;/h3&gt;&lt;p&gt;这一步的目标是求出所有参数的梯度 ∂L/∂W&lt;sup&gt;(l)&lt;/sup&gt; 和 ∂L/∂b&lt;sup&gt;(l)&lt;/sup&gt;。&lt;/p&gt;
&lt;p&gt;做法是&lt;strong&gt;从输出层开始，把误差往输入层方向逐层回传&lt;/strong&gt;：先算输出层该为误差负多少责任，再把这个责任按权重大小分摊给前一层，如此一直推到第一层。每到一层，就顺手记下该层参数的梯度。&lt;/p&gt;
&lt;h3 id=&#34;更新参数&#34;&gt;更新参数
&lt;/h3&gt;&lt;p&gt;拿到梯度后，让每个参数沿梯度的&lt;strong&gt;反方向&lt;/strong&gt;走一小步：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;W^(l) ← W^(l) − η · ∂L/∂W^(l)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;b^(l) ← b^(l) − η · ∂L/∂b^(l)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;η 是学习率，控制每一步走多大：太小收敛慢，太大容易在最优附近来回震荡甚至发散。&lt;/p&gt;
&lt;p&gt;到了这里，一次完整的训练迭代就走完了。之后回到前向传播反复循环，直到损失降到足够低或达到设定的轮数。实际的训练通常还会把训练数据切成小批量（mini-batch）分批送入，用批内样本梯度的平均值来更新。&lt;/p&gt;
&lt;h2 id=&#34;总结与引入反向传播&#34;&gt;总结与引入反向传播
&lt;/h2&gt;&lt;p&gt;回头看这一轮：&lt;strong&gt;初始化参数 → 前向传播 → 计算损失 → 反向传播 → 更新参数&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;这几步里，除了反向传播，其余四步都是直观的计算：初始化只是给一组初值，前向传播是一层层代入公式，损失函数是把预测值和真实值套进一个公式得到一个数，更新参数则是把梯度乘上学习率减掉。它们都不需要额外的技巧。&lt;/p&gt;
&lt;p&gt;现在仅缺少每个参数需要调整的梯度的计算方法，反向传播就是用来解决这个问题的。&lt;/p&gt;
&lt;p&gt;误差虽然只在输出层显现，但它正是沿着刚才前向传播那条路一层层传过来才形成的。既然如此，只要&lt;strong&gt;沿着同一条路倒着走回去&lt;/strong&gt;，就能把误差再传回去，从而得到每个参数的梯度。&lt;/p&gt;
&lt;h2 id=&#34;反向传播的原理&#34;&gt;反向传播的原理
&lt;/h2&gt;&lt;p&gt;反向传播就是通过计算每个权重对结果的影响大小来进行权重更新的，也就是权重对错误结果的贡献越大，调整幅度就要越大。这个&amp;quot;影响大小&amp;quot;在数学上就是&lt;strong&gt;损失函数对每个参数的偏导数（梯度）&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;具体做法仍是从输出层开始往输入层回传：先算出损失对最后一层输出的梯度，再逐层往前推，每到一层就把该层参数的梯度 ∂L/∂W&lt;sup&gt;(l)&lt;/sup&gt; 和 ∂L/∂b&lt;sup&gt;(l)&lt;/sup&gt; 记下来。&lt;/p&gt;
&lt;h3 id=&#34;链式法则&#34;&gt;链式法则
&lt;/h3&gt;&lt;p&gt;反向传播能成立，靠的就是链式求导法则。&lt;/p&gt;
&lt;p&gt;对一条标量链 L ← a ← z ← w，想知道 w 变一点会让 L 变多少，就把三段的导数连乘起来：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;∂L/∂w = ∂L/∂a · ∂a/∂z · ∂z/∂w
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;代入该神经元：z = wx + b，a = σ(z)，L = ½(y − a)&lt;sup&gt;2&lt;/sup&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;∂L/∂a = (a − y)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;∂a/∂z = σ&amp;#39;(z)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;∂z/∂w = x
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;∂L/∂w = (a − y) · σ&amp;#39;(z) · x
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;三层连乘正好对应&amp;quot;损失函数 → 激活函数 → 加权求和&amp;quot;这条路径，网络更深时这条链只是更长，本质不变。&lt;/p&gt;
&lt;p&gt;把网络看成计算图时，每个节点在反向时只做两件事：接收上游传回来的梯度，乘上自己这个运算的&lt;strong&gt;局部导数&lt;/strong&gt;，再往下传：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;加法节点（z = wx + b）：上游梯度原样分给各条支路；&lt;/li&gt;
&lt;li&gt;乘法节点（w 乘 x）：对 w 的梯度 = 上游梯度 × x，对 x 的梯度 = 上游梯度 × w，两者只是交换乘数；&lt;/li&gt;
&lt;li&gt;激活节点（a = σ(z)）：上游梯度 × σ&amp;rsquo;(z)。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;对于多层网络，损失L需要对每一层的每一个权重参数 w 进行求导，看似计算冗杂，但大部分导数属于局部导数，可以并行计算：如每个神经元的∂a/∂z，∂z/∂w，∂z/∂x(x为前层某个神经元传入的值)等均不依赖损失L，仅有权重参数梯度∂L/∂w需要最后一层的梯度信号∂L/∂a沿计算图逐层反向传导计算得到。&lt;/p&gt;
&lt;h3 id=&#34;举例计算&#34;&gt;举例计算
&lt;/h3&gt;&lt;p&gt;下面举例计算倒数第三层的权重梯度：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.lumenth.me/p/backpropagation/backpropagation.png&#34;
	width=&#34;634&#34;
	height=&#34;308&#34;
	srcset=&#34;https://blog.lumenth.me/p/backpropagation/backpropagation_hu_5a66a77fef02cd76.png 480w, https://blog.lumenth.me/p/backpropagation/backpropagation_hu_b0131a48b2d19ee7.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;205&#34;
		data-flex-basis=&#34;494px&#34;
	
&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;1.前向传播：算出每一层每个神经元的线性预激活 z 、神经元输出 (j/k/l/m/n/v/u)，缓存所有中间值。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;2.预计算（可并行）算出所有神经元的局部导数：
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;∂a/∂z（激活函数导数）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;∂z/∂w（预激活对权重的偏导）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;∂z/∂x（预激活对输入的偏导）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;3.反向传播开始，先算出L对最后一层输出的梯度，即把输出代入损失函数的导数：
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;∂L/∂u（如均方误差下 ∂L/∂u = u − y）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;4.再算出L对倒数第二层输出的梯度：
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;如：∂L/∂j（L对j神经元输出的偏导）= ∂L/∂u · ∂u/∂z · ∂z/∂j（这里的z是对应u神经元的预激活）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;同理算出：∂L/∂k、∂L/∂l、∂L/∂m、∂L/∂n
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;5.再算出L对倒数第三层输出的梯度：
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;∂L/∂v = ∂L/∂j · ∂j/∂z · ∂z/∂v
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        + ∂L/∂k · ∂k/∂z · ∂z/∂v
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        + ∂L/∂l · ∂l/∂z · ∂z/∂v
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        + ∂L/∂m · ∂m/∂z · ∂z/∂v
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        + ∂L/∂n · ∂n/∂z · ∂z/∂v
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;（这里的z是对应j、k、l、m、n神经元的预激活）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;6.这时就能算出L对倒数第三层权重w的梯度：
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;∂L/∂w = ∂L/∂v · ∂v/∂z · ∂z/∂w
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;（这里的z是对应v神经元的预激活）
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;小结&#34;&gt;小结
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;反向传播求的是损失对每个参数的梯度，贡献越大的参数调整幅度越大；&lt;/li&gt;
&lt;li&gt;一轮完整的流程是：初始化参数 → 前向传播 → 计算损失 → 反向传播 → 更新参数，然后反复循环；&lt;/li&gt;
&lt;li&gt;反向传播的数学基础是链式法则，梯度沿计算图从后往前传，每个节点只需乘上自己的局部导数；&lt;/li&gt;
&lt;li&gt;反向传播只负责算出梯度，真正改变参数的是梯度下降那一步。&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>深度学习笔记-关键概念</title>
        <link>https://blog.lumenth.me/p/conception/</link>
        <pubDate>Fri, 18 Sep 2026 00:00:00 +0000</pubDate>
        
        <guid>https://blog.lumenth.me/p/conception/</guid>
        <description>&lt;img src="https://blog.lumenth.me/p/conception/wallpaper.png" alt="Featured image of post 深度学习笔记-关键概念" /&gt;&lt;h1 id=&#34;关键概念&#34;&gt;关键概念
&lt;/h1&gt;&lt;p&gt;这篇整理几个后面会反复出现的名词：前向传播、激活函数、损失函数、梯度下降、学习率。它们不是某个具体模型，而是所有神经网络训练时都要用到的共同零件。&lt;/p&gt;
&lt;p&gt;一个神经网络的训练过程，本质上就是这五样东西的配合：先&lt;strong&gt;前向传播&lt;/strong&gt;算出预测值，用&lt;strong&gt;损失函数&lt;/strong&gt;衡量它和正确答案差多少，再靠&lt;strong&gt;梯度下降&lt;/strong&gt;把参数往误差减小的方向挪一点，每次挪多大由&lt;strong&gt;学习率&lt;/strong&gt;决定；而&lt;strong&gt;激活函数&lt;/strong&gt;决定了每一层的输出长什么样，也决定了整个网络能不能表达非线性。&lt;/p&gt;
&lt;h2 id=&#34;前向传播&#34;&gt;前向传播
&lt;/h2&gt;&lt;p&gt;数据从输入层进入，沿着网络逐层往后算，直到输出层给出预测值，这个过程就叫前向传播（Forward Propagation）。(&lt;strong&gt;简单理解就是将上一层的输出作为下一层的输入，并计算下一层的输出，一直到运算到输出层为止。&lt;/strong&gt;)&lt;/p&gt;
&lt;p&gt;沿用&lt;a class=&#34;link&#34; href=&#34;../MLP/&#34; &gt;多层感知机笔记&lt;/a&gt;的记号，&lt;code&gt;i&lt;/code&gt; 表示层号：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;第 i 层的净输入：z&lt;sub&gt;(i)&lt;/sub&gt; = W&lt;sub&gt;(i)&lt;/sub&gt;a&lt;sub&gt;(i−1)&lt;/sub&gt; + b&lt;sub&gt;(i)&lt;/sub&gt;&lt;/li&gt;
&lt;li&gt;第 i 层的输出：a&lt;sub&gt;(i)&lt;/sub&gt; = σ(z&lt;sub&gt;(i)&lt;/sub&gt;)&lt;/li&gt;
&lt;li&gt;输入层 a&lt;sub&gt;(0)&lt;/sub&gt; = x，最后一层的输出就是预测值 ŷ&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;需要强调两点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;前向传播&lt;strong&gt;不更新任何参数&lt;/strong&gt;，它只是拿着当前这组参数做一次预测，看结果怎么样；&lt;/li&gt;
&lt;li&gt;但每一层的 z 和 a &lt;strong&gt;必须保存下来&lt;/strong&gt;，因为反向传播算梯度时要直接复用这些中间结果，重算一遍代价太大。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;激活函数&#34;&gt;激活函数
&lt;/h2&gt;&lt;p&gt;激活函数套在每一层&amp;quot;加权求和之后、往下传递之前&amp;quot;，负责把 z&lt;sub&gt;(i)&lt;/sub&gt; 变成该层的输出 a&lt;sub&gt;(i)&lt;/sub&gt;。&lt;/p&gt;
&lt;p&gt;它最重要的作用是引入非线性。如果去掉激活函数、每层只做线性变换，那么无论堆多少层，最终都等价于一层线性模型（推导见&lt;a class=&#34;link&#34; href=&#34;../MLP/&#34; &gt;多层感知机笔记&lt;/a&gt;），网络就失去了拟合复杂函数的能力。&lt;/p&gt;
&lt;p&gt;常见选择：&lt;/p&gt;
&lt;h3 id=&#34;&#34;&gt;
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;阶跃函数&lt;/strong&gt;：最朴素的激活函数，&lt;a class=&#34;link&#34; href=&#34;../Perceptron/&#34; &gt;感知机&lt;/a&gt;用的就是它；但处处导数为 0、在 0 处不可导，梯度传不下去，因此只能用于单层模型。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.lumenth.me/p/conception/STEP.png&#34;
	width=&#34;474&#34;
	height=&#34;306&#34;
	srcset=&#34;https://blog.lumenth.me/p/conception/STEP_hu_e571fbeca0cc2201.png 480w, https://blog.lumenth.me/p/conception/STEP_hu_9706fefe7fd06e24.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;154&#34;
		data-flex-basis=&#34;371px&#34;
	
&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ReLU&lt;/strong&gt;：正区间导数为 1、负区间为 0，计算极快且不饱和，是目前隐藏层的默认选择；缺点是可能出现&amp;quot;死亡 ReLU&amp;quot;（神经元永久输出 0）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.lumenth.me/p/conception/RELU.png&#34;
	width=&#34;585&#34;
	height=&#34;322&#34;
	srcset=&#34;https://blog.lumenth.me/p/conception/RELU_hu_a563401ea52b802c.png 480w, https://blog.lumenth.me/p/conception/RELU_hu_6cc69ccf0417586a.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;181&#34;
		data-flex-basis=&#34;436px&#34;
	
&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Sigmoid&lt;/strong&gt;：把输出压到 (0,1)，适合二分类的输出层；缺点是两端饱和后梯度趋近 0，容易梯度消失，且输出非零均值。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.lumenth.me/p/conception/SIGMOID.png&#34;
	width=&#34;607&#34;
	height=&#34;312&#34;
	srcset=&#34;https://blog.lumenth.me/p/conception/SIGMOID_hu_40b792ba9341ee17.png 480w, https://blog.lumenth.me/p/conception/SIGMOID_hu_8a0eb3343be0ea7f.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;194&#34;
		data-flex-basis=&#34;466px&#34;
	
&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Tanh&lt;/strong&gt;：把输出压到 (−1,1)，零均值，隐藏层比 Sigmoid 好用一些；同样存在梯度消失。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.lumenth.me/p/conception/TANH.png&#34;
	width=&#34;636&#34;
	height=&#34;322&#34;
	srcset=&#34;https://blog.lumenth.me/p/conception/TANH_hu_3b4a0b9a5dcbb64a.png 480w, https://blog.lumenth.me/p/conception/TANH_hu_3383d8862e7dca89.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;197&#34;
		data-flex-basis=&#34;474px&#34;
	
&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Softmax&lt;/strong&gt;：不属于单个神经元的激活函数，而是作用在输出层的一整组神经元上，把它们的输出归一化成总和为 1 的概率，专用于多分类的输出层。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.lumenth.me/p/conception/SOFTMAX.png&#34;
	width=&#34;161&#34;
	height=&#34;76&#34;
	srcset=&#34;https://blog.lumenth.me/p/conception/SOFTMAX_hu_8b0057dc6437b877.png 480w, https://blog.lumenth.me/p/conception/SOFTMAX_hu_da93cc849c0257d7.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;211&#34;
		data-flex-basis=&#34;508px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;一句话总结：隐藏层默认用 ReLU，二分类输出用 Sigmoid，多分类输出用 Softmax。&lt;/p&gt;
&lt;h2 id=&#34;损失函数&#34;&gt;损失函数
&lt;/h2&gt;&lt;p&gt;损失函数（Loss Function）用来衡量预测值 ŷ 和真实标签 y 之间的差距，输出一个标量 L 代表损失。&lt;/p&gt;
&lt;p&gt;它是训练的&lt;strong&gt;目标&lt;/strong&gt;：模型训练得好不好，就看损失能不能降下来。常见形式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;回归任务：&lt;strong&gt;均方误差&lt;/strong&gt; &lt;code&gt;L = ½ ‖ŷ − y‖&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;二分类任务：&lt;strong&gt;交叉熵&lt;/strong&gt;，配合 Sigmoid 输出使用&lt;/li&gt;
&lt;li&gt;多分类任务：&lt;strong&gt;交叉熵&lt;/strong&gt;，配合 Softmax 输出使用&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;损失函数有两个要求：一是能真实反映&amp;quot;错得多离谱&amp;quot;，二是&lt;strong&gt;必须可导&lt;/strong&gt;——因为后面要根据它对每个参数求偏导，参数才知道该往哪调。这也是为什么要选用 Sigmoid、ReLU 而不是阶跃函数的原因之一。&lt;/p&gt;
&lt;p&gt;在整个训练流程里，损失函数正好卡在中间：前向传播算出 ŷ，损失函数把它变成一个可以求导的标量 L，反向传播再由这个 L 出发往回算梯度（反向传播）。&lt;/p&gt;
&lt;h2 id=&#34;梯度下降&#34;&gt;梯度下降
&lt;/h2&gt;&lt;p&gt;有了损失，接下来要让损失 L 变小。梯度（偏导数组成的向量）指向的是 L &lt;strong&gt;上升最快&lt;/strong&gt;的方向，那么每个参数的更新方向就很自然了——沿着梯度的反方向走：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;W ← W − η · ∂L/∂W
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;b ← b − η · ∂L/∂b
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这就是梯度下降（Gradient Descent），可以想象成站在山坡上蒙着眼往下山走：每次用脚探一下周围哪个方向最陡（求梯度），然后朝最陡的下坡方向迈一小步（更新参数），重复若干次就到了山谷附近。&lt;/p&gt;
&lt;p&gt;按每次用多少样本来算梯度，分成三种：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;批量梯度下降&lt;/strong&gt;：用全部训练样本算一次梯度再更新，方向稳但慢；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;随机梯度下降（SGD）&lt;/strong&gt;：每次只用一个样本，更新快但抖动大；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;小批量梯度下降&lt;/strong&gt;：每次用一小批样本（如 32、64 个），兼顾稳定与速度，实际最常用。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;需要注意的是，梯度下降拿到的是当前点的&lt;strong&gt;局部信息&lt;/strong&gt;，它不保证走到全局最低点：遇到局部极小值或鞍点都可能卡住或减速。&lt;/p&gt;
&lt;h2 id=&#34;学习率&#34;&gt;学习率
&lt;/h2&gt;&lt;p&gt;学习率（Learning Rate）η 就是上面公式里那个&amp;quot;步长&amp;quot;，控制每次参数更新的幅度。&lt;/p&gt;
&lt;p&gt;它是最重要也最容易调错的超参数：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.lumenth.me/p/conception/xuexilv.png&#34;
	width=&#34;1250&#34;
	height=&#34;449&#34;
	srcset=&#34;https://blog.lumenth.me/p/conception/xuexilv_hu_ba85e924b4d4e647.png 480w, https://blog.lumenth.me/p/conception/xuexilv_hu_f445074ba4fd8560.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;278&#34;
		data-flex-basis=&#34;668px&#34;
	
&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;太大&lt;/strong&gt;：一步跨过头，损失在最低点附近来回震荡，甚至越更新越大直接发散；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;太小&lt;/strong&gt;：每步都几乎没有进展，收敛极慢，还容易停在半路上；&lt;/li&gt;
&lt;li&gt;比较稳妥的做法是&lt;strong&gt;让学习率随训练衰减&lt;/strong&gt;：前期大步靠近，后期小步微调。也可以交给 Adam 这类自适应优化器，让每个参数各自拥有动态调整的步长。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;小结&#34;&gt;小结
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;前向传播&lt;/strong&gt;：拿着当前参数算出预测值，并把每层的中间结果存下来备用；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;激活函数&lt;/strong&gt;：给线性变换加非线性，否则多层网络等价于单层；隐藏层默认 ReLU，输出层按任务选 Sigmoid 或 Softmax；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;损失函数&lt;/strong&gt;：量化预测与真实的差距，必须可导，是前向与反向之间的分界点；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;梯度下降&lt;/strong&gt;：沿梯度反方向更新参数来减小损失，实践中多用小批量；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;学习率&lt;/strong&gt;：控制每一步走多大，太大发散、太慢卡住，通常随训练衰减。&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>深度学习笔记2-多层感知机</title>
        <link>https://blog.lumenth.me/p/mlp/</link>
        <pubDate>Thu, 17 Sep 2026 00:00:00 +0000</pubDate>
        
        <guid>https://blog.lumenth.me/p/mlp/</guid>
        <description>&lt;img src="https://blog.lumenth.me/p/mlp/MLP.png" alt="Featured image of post 深度学习笔记2-多层感知机" /&gt;&lt;h1 id=&#34;多层感知机&#34;&gt;多层感知机
&lt;/h1&gt;&lt;p&gt;我在&lt;a class=&#34;link&#34; href=&#34;../Perceptron/&#34; &gt;感知机笔记&lt;/a&gt;中，记录了单层感知机，它是二分类的线性分类模型，在数据线性可分时，由 Novikoff 定理能够保证在有限步中能做到完全收敛。但无法解决 XOR 等线性不可分问题，这些问题需要多层感知机。&lt;/p&gt;
&lt;h2 id=&#34;引入隐藏层&#34;&gt;引入隐藏层
&lt;/h2&gt;&lt;p&gt;异或电路如下图所示：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.lumenth.me/p/mlp/XOR.png&#34;
	width=&#34;944&#34;
	height=&#34;491&#34;
	srcset=&#34;https://blog.lumenth.me/p/mlp/XOR_hu_66a8ecd74e76e2a7.png 480w, https://blog.lumenth.me/p/mlp/XOR_hu_52e9acaaebc0a309.png 1024w&#34;
	loading=&#34;lazy&#34;
	
		alt=&#34;异或电路&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;192&#34;
		data-flex-basis=&#34;461px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;可以看到异或是由两次任务来完成：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在第一部分输入后，输入信号输入到第二部分进行与非和或运算。&lt;/li&gt;
&lt;li&gt;完成两个运算后，同时输入到第三部分完成与的运算从而做到异或。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;把它转换成感知机表示如下：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.lumenth.me/p/mlp/MLPXOR.png&#34;
	width=&#34;1268&#34;
	height=&#34;746&#34;
	srcset=&#34;https://blog.lumenth.me/p/mlp/MLPXOR_hu_b0277f29e28476bd.png 480w, https://blog.lumenth.me/p/mlp/MLPXOR_hu_bfe22332c86173fd.png 1024w&#34;
	loading=&#34;lazy&#34;
	
		alt=&#34;感知机异或&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;169&#34;
		data-flex-basis=&#34;407px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;可以分析出任务的完成方式:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在输入层接收两个输入x&lt;sub&gt;1&lt;/sub&gt;，x&lt;sub&gt;2&lt;/sub&gt;。&lt;/li&gt;
&lt;li&gt;在隐藏层可以做两个并行的感知机，一个做OR运算，一个做NAND运算。&lt;/li&gt;
&lt;li&gt;在输出层将两个隐藏层的运算输出的结果做AND运算，从而实现异或逻辑。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;通过引入隐藏层，大量感知机的组合可以完成各种各样的复杂任务&lt;/p&gt;
&lt;h2 id=&#34;多层感知机-1&#34;&gt;多层感知机
&lt;/h2&gt;&lt;p&gt;MLP是层级化、全连接的神经网络结构，层与层之间无跳过、无循环，相邻层神经元之间全连接（相邻层的任意两个神经元都有连接），整体分为3类核心层（输入层-&amp;gt;隐藏层-&amp;gt;输出层），结构如下：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.lumenth.me/p/mlp/BASICMLP.png&#34;
	width=&#34;463&#34;
	height=&#34;205&#34;
	srcset=&#34;https://blog.lumenth.me/p/mlp/BASICMLP_hu_12d7c990d6c4951d.png 480w, https://blog.lumenth.me/p/mlp/BASICMLP_hu_855ae50e5a6cbf7.png 1024w&#34;
	loading=&#34;lazy&#34;
	
		alt=&#34;多层感知机的一般结构&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;225&#34;
		data-flex-basis=&#34;542px&#34;
	
&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;输入层：&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;仅负责接收原始数据/特征，不做任何计算，神经元数量 = 数据的特征维度（如输入是 28×28 的图片，展平后神经元数为784）。&lt;/li&gt;
&lt;li&gt;无激活函数，仅传递数据。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;隐藏层&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;MLP 的核心层，可设置1层或多层（多层时称为深度多层感知机），层数/神经元数是关键超参数。&lt;/li&gt;
&lt;li&gt;同一层神经元并行提取不同的特征或规则。&lt;/li&gt;
&lt;li&gt;后续层的输入为前一层的输出，逐层进行抽象构造出更有效的特征。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;输出层（最终预测结果，神经元数量由任务类型决定）&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;二分类任务：1个神经元（输出0/1）&lt;/li&gt;
&lt;li&gt;多分类任务：神经元数 = 类别数（如MNIST手写数字分类，设10个神经元）；&lt;/li&gt;
&lt;li&gt;回归任务：1个神经元（输出连续值）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;多层线性变换&#34;&gt;多层线性变换
&lt;/h2&gt;&lt;p&gt;多层感知机如果在每一层只做线性变换，那么无论多少层隐藏层，MLP 最终等价于单层线性模型。&lt;/p&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;第一层输出h = W&lt;sub&gt;1&lt;/sub&gt;x + b&lt;sub&gt;1&lt;/sub&gt;。&lt;/li&gt;
&lt;li&gt;第二层输出y = W&lt;sub&gt;2&lt;/sub&gt;h + b&lt;sub&gt;2&lt;/sub&gt;。代入第一层输出得到y = W&lt;sub&gt;2&lt;/sub&gt;(W&lt;sub&gt;1&lt;/sub&gt;x + b&lt;sub&gt;1&lt;/sub&gt;) + b&lt;sub&gt;2&lt;/sub&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可以看出来仍然是一个一阶线性函数，所以无论堆叠多少层感知机仍然是线性模型。&lt;/p&gt;
&lt;h2 id=&#34;引入激活函数&#34;&gt;引入激活函数
&lt;/h2&gt;&lt;p&gt;在每一层神经元加权求和的输出后，套一个非线性函数再输出，该非线性函数称为激活函数（Activation Function）。&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;../Perceptron/&#34; &gt;单层感知机&lt;/a&gt;中，激活函数为&lt;strong&gt;阶跃函数&lt;/strong&gt;(Step Function)如下图。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.lumenth.me/p/mlp/STEP.png&#34;
	width=&#34;474&#34;
	height=&#34;306&#34;
	srcset=&#34;https://blog.lumenth.me/p/mlp/STEP_hu_e571fbeca0cc2201.png 480w, https://blog.lumenth.me/p/mlp/STEP_hu_9706fefe7fd06e24.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;154&#34;
		data-flex-basis=&#34;371px&#34;
	
&gt;&lt;/p&gt;
&lt;h3 id=&#34;一些常用的激活函数&#34;&gt;一些常用的激活函数
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;ReLU（Rectified Linear Unit） ✅ 最常用 ：优点：计算快、缓解梯度消失，适合隐藏层；缺点：存在“死亡ReLU”问题。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.lumenth.me/p/mlp/RELU.png&#34;
	width=&#34;585&#34;
	height=&#34;322&#34;
	srcset=&#34;https://blog.lumenth.me/p/mlp/RELU_hu_a563401ea52b802c.png 480w, https://blog.lumenth.me/p/mlp/RELU_hu_6cc69ccf0417586a.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;181&#34;
		data-flex-basis=&#34;436px&#34;
	
&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sigmoid：优点：输出映射到(0,1)，适合二分类输出层；缺点：梯度消失、输出非零均值。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.lumenth.me/p/mlp/SIGMOID.png&#34;
	width=&#34;607&#34;
	height=&#34;312&#34;
	srcset=&#34;https://blog.lumenth.me/p/mlp/SIGMOID_hu_40b792ba9341ee17.png 480w, https://blog.lumenth.me/p/mlp/SIGMOID_hu_8a0eb3343be0ea7f.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;194&#34;
		data-flex-basis=&#34;466px&#34;
	
&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Tanh：优点：输出映射到(-1,1)，零均值；缺点：仍存在梯度消失。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.lumenth.me/p/mlp/TANH.png&#34;
	width=&#34;636&#34;
	height=&#34;322&#34;
	srcset=&#34;https://blog.lumenth.me/p/mlp/TANH_hu_3b4a0b9a5dcbb64a.png 480w, https://blog.lumenth.me/p/mlp/TANH_hu_3383d8862e7dca89.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;197&#34;
		data-flex-basis=&#34;474px&#34;
	
&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Softmax ✅ 多分类输出层专用，将多个神经元的输出归一化到(0,1)，且总和为1，代表样本属于各类别的概率。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.lumenth.me/p/mlp/SOFTMAX.png&#34;
	width=&#34;161&#34;
	height=&#34;76&#34;
	srcset=&#34;https://blog.lumenth.me/p/mlp/SOFTMAX_hu_8b0057dc6437b877.png 480w, https://blog.lumenth.me/p/mlp/SOFTMAX_hu_da93cc849c0257d7.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;211&#34;
		data-flex-basis=&#34;508px&#34;
	
&gt;&lt;/p&gt;
&lt;h3 id=&#34;万能逼近定理&#34;&gt;万能逼近定理
&lt;/h3&gt;&lt;p&gt;万能逼近定理（Universal Approximation Theorem, UAT）：一个含有足够多神经元的单隐藏层MLP，可以以任意精度逼近任意连续函数。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;意味着MLP在理论上具备表达任意连续函数的能力&lt;/li&gt;
&lt;li&gt;但实际中，定理只保证存在这样一组参数，不保证梯度下降能学到；且所需神经元数可能随精度指数级增长。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;多层感知机的数学表达&#34;&gt;多层感知机的数学表达
&lt;/h2&gt;&lt;p&gt;由于每一层感知机神经元的输出结果都是上一层输入的组合运算，所以最终结果在数学计算上可以用函数的嵌套来进行表示，即：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;层函数：&lt;strong&gt;h&lt;sub&gt;i&lt;/sub&gt;(u)= σ&lt;sub&gt;i&lt;/sub&gt;(W&lt;sub&gt;i&lt;/sub&gt;u + b&lt;sub&gt;i&lt;/sub&gt;)&lt;/strong&gt; （u 为上一层的输出，i 为层号）&lt;/li&gt;
&lt;li&gt;输出函数：&lt;strong&gt;output = h&lt;sub&gt;n&lt;/sub&gt;(h&lt;sub&gt;n-1&lt;/sub&gt;(&amp;hellip;h&lt;sub&gt;2&lt;/sub&gt;(h&lt;sub&gt;1&lt;/sub&gt;(X))))&lt;/strong&gt;，其中 h&lt;sub&gt;1&lt;/sub&gt;(X) 即输入层到第一层的结果，逐层向后传递。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;多层感知机遇到的问题&#34;&gt;多层感知机遇到的问题
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;感知机的学习规则只适用于单层网络&lt;/li&gt;
&lt;li&gt;隐藏层神经元需要调整的梯度无从得知&lt;/li&gt;
&lt;li&gt;下一次会写反向传播算法的笔记，反向传播算法的作用是得到各个神经元参数需要修改的梯度&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>深度学习笔记1-感知机</title>
        <link>https://blog.lumenth.me/p/perceptron/</link>
        <pubDate>Thu, 10 Sep 2026 00:00:00 +0000</pubDate>
        
        <guid>https://blog.lumenth.me/p/perceptron/</guid>
        <description>&lt;img src="https://blog.lumenth.me/p/perceptron/Perceptron.png" alt="Featured image of post 深度学习笔记1-感知机" /&gt;&lt;h1 id=&#34;深度学习基础-感知机&#34;&gt;深度学习基础-感知机
&lt;/h1&gt;&lt;p&gt;感知机（perceptron）是二分类的线性分类模型，属于监督学习算法，也是神经网络与支持向量机的共同前身。&lt;/p&gt;
&lt;p&gt;感知机起源于对生物神经元细胞的抽象建模，其工作原理与生物神经元细胞类似。（如下图）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;生物神经元通过&lt;strong&gt;树突&lt;/strong&gt;接收其他神经元&lt;strong&gt;轴突&lt;/strong&gt;传递过来的信号；当累积信号强度超过激发阈值时，神经元经由自身轴突向外输出神经脉冲。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;感知机仿照生物神经元机制，对多路输入信号做&lt;strong&gt;加权求和&lt;/strong&gt;，再与阈值进行比较，最终输出 0 或 1。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.lumenth.me/p/perceptron/cell.png&#34;
	width=&#34;2205&#34;
	height=&#34;915&#34;
	srcset=&#34;https://blog.lumenth.me/p/perceptron/cell_hu_f30fdb2f25c39b62.png 480w, https://blog.lumenth.me/p/perceptron/cell_hu_ba983eb879951e8a.png 1024w&#34;
	loading=&#34;lazy&#34;
	
		alt=&#34;神经元与感知机&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;240&#34;
		data-flex-basis=&#34;578px&#34;
	
&gt;&lt;/p&gt;
&lt;h2 id=&#34;感知机模型&#34;&gt;感知机模型
&lt;/h2&gt;&lt;p&gt;感知机计算模型如图：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.lumenth.me/p/perceptron/model.png&#34;
	width=&#34;881&#34;
	height=&#34;371&#34;
	srcset=&#34;https://blog.lumenth.me/p/perceptron/model_hu_e9a5a4592086438c.png 480w, https://blog.lumenth.me/p/perceptron/model_hu_b59fe3d1a257588e.png 1024w&#34;
	loading=&#34;lazy&#34;
	
		alt=&#34;感知机模型&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;237&#34;
		data-flex-basis=&#34;569px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;工作原理：&lt;/p&gt;
&lt;p&gt;对输入进行加权求和，与阈值进行比较并输出；得到输出后与真实标签比较，若预测错误则按误差修正权重与偏置，反复迭代，直到所有训练样本都被正确分类（数据线性可分时）。&lt;/p&gt;
&lt;h3 id=&#34;第一步输入加权求和&#34;&gt;第一步：输入加权求和
&lt;/h3&gt;&lt;p&gt;接收一组信号 x&lt;sub&gt;1&lt;/sub&gt;, x&lt;sub&gt;2&lt;/sub&gt;, …, x&lt;sub&gt;m&lt;/sub&gt;，每一个 x&lt;sub&gt;i&lt;/sub&gt; 代表数据的一个特征。&lt;/p&gt;
&lt;p&gt;每一个输入对应一个权重 w&lt;sub&gt;i&lt;/sub&gt;，代表该特征对最终结果的影响程度；图中还有一个恒为 1 的输入，其权重记为 w&lt;sub&gt;0&lt;/sub&gt;，也就是偏置 b(第二步介绍)。&lt;/p&gt;
&lt;p&gt;将输入 x&lt;sub&gt;i&lt;/sub&gt; 与对应权重 w&lt;sub&gt;i&lt;/sub&gt; 相乘后求和，得到加权求和结果（净输入）：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;z = Σ xi · wi
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id=&#34;第二步判断并输出&#34;&gt;第二步：判断并输出
&lt;/h3&gt;&lt;p&gt;设定一个阈值 θ，该阈值用于划定分类的界限：加权求和的结果大于阈值时输出 1，否则输出 0。&lt;/p&gt;
&lt;p&gt;令偏置 b = −θ，这样处理过后、与阈值的比较就变成了加入偏置和0进行比较，遮掩就能采用阶跃函数进行输出。判据就统一成了&amp;quot;加权求和加偏置后送入阶跃函数&amp;quot;的形式（即判断净输入 z 是否大于等于 0），如下图公式：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.lumenth.me/p/perceptron/judgement.png&#34;
	width=&#34;485&#34;
	height=&#34;274&#34;
	srcset=&#34;https://blog.lumenth.me/p/perceptron/judgement_hu_e3a9c451813988d.png 480w, https://blog.lumenth.me/p/perceptron/judgement_hu_83926a5578750b41.png 1024w&#34;
	loading=&#34;lazy&#34;
	
		alt=&#34;感知机计算流程&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;177&#34;
		data-flex-basis=&#34;424px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;其中 z = Σ x&lt;sub&gt;i&lt;/sub&gt; · w&lt;sub&gt;i&lt;/sub&gt; + b，z = 0 落在边界上，约定输出 1。&lt;/p&gt;
&lt;h3 id=&#34;第三步错误修正&#34;&gt;第三步：错误修正
&lt;/h3&gt;&lt;p&gt;每做出一次预测，感知机就与正确答案进行对比：若预测正确则不做任何修改；&lt;strong&gt;若预测错误&lt;/strong&gt;，则按下面规律进行权重调整：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.lumenth.me/p/perceptron/update.png&#34;
	width=&#34;475&#34;
	height=&#34;77&#34;
	srcset=&#34;https://blog.lumenth.me/p/perceptron/update_hu_4ab08c661a291a90.png 480w, https://blog.lumenth.me/p/perceptron/update_hu_ac367e829d118ec3.png 1024w&#34;
	loading=&#34;lazy&#34;
	
		alt=&#34;权重更新公式&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;616&#34;
		data-flex-basis=&#34;1480px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;符号释义：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;w&lt;sub&gt;i&lt;/sub&gt;：第 i 个权重（w&lt;sub&gt;0&lt;/sub&gt; 即偏置 b，对应恒为 1 的输入）；&lt;/li&gt;
&lt;li&gt;η：学习率，控制每次修正的步长；&lt;/li&gt;
&lt;li&gt;y：真实标签（0 或 1）；&lt;/li&gt;
&lt;li&gt;ŷ：感知机预测输出（0 或 1）；&lt;/li&gt;
&lt;li&gt;x&lt;sub&gt;i&lt;/sub&gt;：第 i 路输入。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;因为 (y − ŷ) 只在预测错误时才非零，取值为 +1（漏报）或 −1（误报），所以该式只在误分类样本上生效：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;y = 1、ŷ = 0 时，w&lt;sub&gt;i&lt;/sub&gt; ← w&lt;sub&gt;i&lt;/sub&gt; + η·x&lt;sub&gt;i&lt;/sub&gt;，把权重往&amp;quot;更容易输出 1&amp;quot;的方向推；&lt;/li&gt;
&lt;li&gt;y = 0、ŷ = 1 时，w&lt;sub&gt;i&lt;/sub&gt; ← w&lt;sub&gt;i&lt;/sub&gt; − η·x&lt;sub&gt;i&lt;/sub&gt;，把权重往&amp;quot;更容易输出 0&amp;quot;的方向推。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;若把偏置看作权重 w&lt;sub&gt;0&lt;/sub&gt;、把恒为 1 的输入看作 x&lt;sub&gt;0&lt;/sub&gt; = 1，则上式同时覆盖了偏置更新 b ← b + η(y − ŷ)。&lt;/p&gt;
&lt;h3 id=&#34;几何意义与收敛性&#34;&gt;几何意义与收敛性
&lt;/h3&gt;&lt;p&gt;把权重与偏置看作一组参数，z = 0（即 w·x + b = 0）在特征空间中是一条直线，在高维下则是超平面，它把空间分成两侧，分别对应输出 0 与输出 1。所谓&amp;quot;训练&amp;quot;，就是不断旋转、平移这条分界线，直到所有训练样本都落在正确的一侧。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Novikoff 定理&lt;/strong&gt;：若训练集&lt;strong&gt;线性可分&lt;/strong&gt;且学习率 η &amp;gt; 0，感知机学习算法一定能在&lt;strong&gt;有限步&lt;/strong&gt;内收敛，得到一个能把所有样本正确划分的超平面。&lt;/p&gt;
&lt;p&gt;反之，如果数据线性不可分，权重会被反复修正而始终无法稳定下来，此时算法不保证收敛。&lt;/p&gt;
&lt;p&gt;以与门（AND）为例：取 w&lt;sub&gt;1&lt;/sub&gt; = w&lt;sub&gt;2&lt;/sub&gt; = 1、b = −1.5，则只有输入 (1, 1) 时 z = 0.5 ≥ 0 输出 1，其余组合 z 均小于 0 输出 0，正好实现了与逻辑。&lt;/p&gt;
&lt;h2 id=&#34;感知机的劣势&#34;&gt;感知机的劣势
&lt;/h2&gt;&lt;p&gt;感知机只能解决&lt;strong&gt;线性可分&lt;/strong&gt;的任务。以逻辑门为例：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;与（AND）、或（OR）：样本线性可分，感知机可以学会（见上例）；&lt;/li&gt;
&lt;li&gt;异或（XOR）：同一类别的点交错分布在直线两侧，无法用单个超平面分开，感知机无法解决。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;XOR 问题的本质是它不属于线性可分函数，这正是单层感知机的根本局限。解决思路是引入&lt;strong&gt;隐藏层&lt;/strong&gt;，把单层感知机堆叠为&lt;strong&gt;多层感知机（MLP）&lt;/strong&gt;——借助多层的非线性变换去逼近任意复杂的决策边界，这也是后续深度神经网络的基本思路。&lt;/p&gt;
&lt;h2 id=&#34;小结&#34;&gt;小结
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;感知机是二分类的线性模型：对输入加权求和并加上偏置，经阶跃函数输出 0 或 1；&lt;/li&gt;
&lt;li&gt;学习规则是&amp;quot;误分类驱动&amp;quot;的误差修正：w&lt;sub&gt;i&lt;/sub&gt; ← w&lt;sub&gt;i&lt;/sub&gt; + η(y − ŷ)x&lt;sub&gt;i&lt;/sub&gt;，偏置同步更新；&lt;/li&gt;
&lt;li&gt;只对误分类样本更新权值，预测正确时不做任何修改；&lt;/li&gt;
&lt;li&gt;数据线性可分时，由 Novikoff 定理保证有限步收敛；&lt;/li&gt;
&lt;li&gt;无法解决 XOR 等线性不可分问题，需要多层感知机。&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        
    </channel>
</rss>
