======Back Propagation Neural Network====== BP(BackPropagation)神经网络是1986年由Rumelhart和McClelland为首的科学家提出的概念,是一种按照误差逆向传播算法训l练的多层前馈神经网络,是应用最广泛的神经网络。 =====感知器===== 感知器(Perceptron)就是神经网络中最基本、最标准的“一个节点”(即一个人工神经元)。一个感知器由输入项、权重、偏置、激活函数、输出组成,如下图所示: {{ :zh:artificial_intelligence:neural_networks:back_propagation_neural_network:感知器.png?400 |}} 各个组件的功能如下: * 输入项$X_1, X_2, X_3 ...$,表示外界传来的信号。比如预测房价时,面积100$m^2$、房龄5年就是输入。 * 权重$W₁, W₂, W₃ ...$,表示重要性系数。权重越大,说明这个输入对结果影响越大(比如面积权重0.8,房龄权重0.1,说明面积重要得多)。 * 偏置$b (Bias)$,表示阈值/容错。相当于给神经元一个“基础兴奋度”。即使所有输入都是0,偏置也能让神经元有输出(比如让模型在没有阳光时也默认开一点灯)。 * 求和$\sum$(累加和),把 (输入X权重) 全部加起来,再加偏置,得出一个总分。 * 激活函数 f (如Sigmoid/ReLU) “门卫”。把刚才的“总分”压扁或转化一下(比如限制在0到1之间),让它变成最终的输出。如果没有它,多层网络就退化成一次线性方程,毫无学习能力。 * 输出$Y$最终传给下一层的结果。 =====局限:"自由度"与"样本数"的对抗===== 假设我们要预测房价,收集到3条真实数据: ^样本^面积(㎡)^房龄(年)^真实房价(万)^ |1|80|5|200| |2|100|10|230| |3|120|15|250| 从数学上来看,感知器是一个由激活函数包裹的线性函数: \begin{equation} y = 激活函数( w_1x_1 + w_2x_2 + ... + b ) \end{equation} 我们可以计算它的输出,输出 = 激活函数( $w_1×面积 + w_2×房龄 + b$ ),设初始参数:$w_1=2.0, w_2=0.5, b=10$,激活函数用线性激活(直接输出不加压)。那么, 对于样本1: 80×2.0 + 5×0.5 + 10 = 160 + 2.5 + 10 = 172.5(万) 真实值是200万,误差 = 200 - 172.5 = +27.5万(低了) 对于样本2: 100×2.0 + 10×0.5 + 10 = 200 + 5 + 10 = 215(万) 真实值230万,误差 = 230 - 215 = +15万(低了) 对于样本3计算: 120×2.0 + 15×0.5 + 10 = 240 + 7.5 + 10 = 257.5(万) 真实值250万,误差 = 250 - 257.5 = -7.5万(高了) 那个根据上面的计算结果,我们需要调整权重,看上面三个误差: * 样本1:低了27.5万 → 需要增大$w_1$或$w_2$ * 样本2:低了15万 → 也需要增大参数 * 样本3:高了7.5万 → 需要减小参数 因此,矛盾出现了,同一个$w_1$,增大它会让样本1和2变准,但会让样本3更不准;减小它会让样本3变准,但会让样本1和2更不准。 再来看一个例子。假设现在房价预测加入第三个特征:距离地铁站的距离(公里),权重记为$w_3$。 ^样本^面积(㎡)^房龄(年)^距地铁(km)^真实房价(万)^ |1|80|5|0.5|200| |2|100|10|1.0|230| |3|120|15|1.5|250| |4||90|8|2.0|210| 单个感知器(无激活函数)要解方程组: * 对样本1:$80w_1 + 5w_2 + 0.5w_3 + b = 200$ * 对样本2:$100w_1 + 10w_2 + 1.0w_3 + b = 230$ * 对样本3:$120w_1 + 15w_2 + 1.5w_3 + b = 250$ * 对样本4:$90w_1 + 8w_2 + 2.0w_3 + b = 210$ 这是 4个方程,4个未知数$(w_1, w_2, w_3, b)$。4个方程4个未知数确实有可能有唯一解,但前提是这4个方程彼此独立且一致,否则: 当样本数 > 权重数 + 1 时,单个感知器(线性模型)必然存在无法消除的误差 通过上面两个例子,我们可以看出,单个神经网络存在局限性 =====网络结构===== 为了解决单传感器的局限,一个有效的办法就是将它们连接起来。因为: - 1个感知器(2个权重)对3个样本: * 自由度 = 2(权重)+ 1(偏置)= 3个参数,要满足3个样本完全精确 → 需要3个方程完全精确成立,但3个点几乎不共线 → 方程组不相容 → 必然有矛盾 - 放大到3个感知器: * 每个感知器有2个权重+1个偏置 = 3个参数,3个感知器 = 9个参数 那么多个感知器是如何连接在一起?在宏观上,BP神经网络由输入层、隐含层(也称中间层)和输出层构成,其中隐含层有一层或者多层。每一层可以有若干个节点。层与层之间节点的连接状态通过权重来体现,如下图所示: {{ :zh:artificial_intelligence:neural_networks:back_propagation_neural_network:bp神经网络结构.png?400 |}} 其中数据在网络中的传播路径如下: {{ :zh:artificial_intelligence:neural_networks:back_propagation_neural_network:bp神经网络的数据传播.png?600 |}} 上中,实线代表正向传播,虚线代表反向传播。可以看到,整个网络宏观上了,和[[zh:cybernetics:closed_loop_control_system:start|闭环控制系统]]类似:信号通过计算,得到实际值,与预期值比较获得差值,根据差值来调整系统的参数。 =====反向传播===== 既然BP神经网络和闭环控制系统如此相似,为什么BP在1986年才被发明,而控制论在1940年代就有了?因为: * 控制论(线性/简单系统):物理世界中的系统(如温度、电压)通常具有明确的因果链。水温高了,我就减少加热,因果关系简单直接,不需要微积分中的链式法则。 * BP神经网络(多层嵌套):误差在输出层,但产生误差的“责任”却分散在第一层、第二层、第三层的成千上万个权重上。误差和权重之间隔了无数层数学函数(层与层之间的嵌套),以至于不能定位究竟该调整哪个权重来获得更优的结果。 BP的突破性在于:它借用了微积分的链式求导法则,把“输出端的误差”一层层地“反推”回输入端,精确计算出每一个权重该负多大责任,即“梯度反向传播”。 ====算例==== 比如,在水文预测中,我们$\hat{y} = w_1 × x_1 + w_2 × x_2 + b$预测未来的水位,其中: * $x_1$ = 上游降雨量(毫米) * $x_2$ = 上游水位(米) * $\hat{y}$ = 预测的下游水位(米) 现在有一组样本: * 降雨量 $x_1$ = 5.0(毫米) * 上游水位 $x_2$ = 2.8(米) * 真实下游水位 $\hat{y}$ = 3.5(米) 模型初始参数(随机初始化): * $w_1$ = 0.40 * $w_2$ = 0.60 * $b$ = 0.10 有了上面的数据,就通过前向传播,计算预测值:$\hat{y}= w_1 × x_1 + w_2 × x_2 + b=0.40 × 5.0 + 0.60 × 2.8 + 0.10=3.78(米)$,因此,模型预测下游水位为 3.78 米,而真实值是 3.50 米,差了 0.28 米。 接下来是计算损失(误差)。我们用均方误差(MSE)作为损失函数,则损失$ L = (\hat{y} - y)² / 2=(3.78 - 3.50)² / 2=0.0392$ 除以2是为了后面求导时消去系数,让公式更整洁,不影响学习方向。 0.0392 就是当前模型在这个样本上的损失值。我们的目标是通过调整$ w_1、w_2、b$,让这个损失值降下来。 ===计算梯度——分配责任=== 反向传播的核心是链式法则:损失$L$先对预测值$\hat{y}求导,再分别对每个参数求导,从而知道每个参数对最终损失负有多大责任。 第一步是计算损失$L$对预测值 $\hat{y}$ 的导数 \begin{equation} \frac{dL}{d \hat{y}} = \hat{y} - y \end{equation} 带入数据$\frac{dL}{d \hat{y}} = 3.78 - 3.50=0.28$ 这个 0.28 的含义是:预测值每增加 1 米,损失增加 0.28。 第二步,计算$L$对参数$w_1$ 的梯度(链式法则) \begin{equation} \frac{dL}{dw₁} = \frac{dL}{d \hat{y}} \frac{d \hat{y}}{d w_1} \end{equation} 其中$ \hat{y} = w_1 × x_1 + w_2 × x_2 + b$,对 $w_1$ 求偏导,则有$d \hat{y}/dw_1 = x_1 = 5.0$,所以,$dL/dw₁ = 0.28 × 5.0 = 1.4$.这里,梯度的含义是$w_1$ 每增加 1,损失 $L$ 大约增加 1.4。梯度为正,说明损失随 $w_1$ 增大而增大,所以要让损失下降,应该减小 $w_1$。 同理,计算 $L$对参数$w_2$的梯度$dL/dw_2 = (dL/d \hat{y}) × (d \hat{y}/dw_2)= x_2 = 2.8= 0.28 × 2.8= 0.784$,这里梯度的含义是$w_2$ 每增加 1,损失 L 增加 0.784。梯度为正,同样应该减小 w₂,只是调整幅度比 w₁ 小一些。最后,计算$ L $对参数 $b$的梯度dL/db = (dL/d\hat{y}) × (d\hat{y}/db)= 0.28 × 1= 0.28$ 简单汇总梯度: ^参数^梯度值^含义^ |$w_1$|+1.4|降雨量权重偏大,导致预测偏高,需要调低| |$w_2$|+0.784|上游水位权重偏大,导致预测偏高,需要调低| |b|+0.28|偏置项偏大,导致预测偏高,需要调低| ===更新参数(学习)=== 梯度下降的更新规则是: 新参数 = 旧参数 - 学习率 × 梯度 学习率η 我们设为 0.01(一个常用的保守值,保证每次只走一小步): * 更新 $w_1$:$w₁_{new} = 0.40 - 0.01 × 1.4= 0.386$ * 更新 $w_2$:$w₂_{new} = 0.60 - 0.01 × 0.784= 0.59216$ * 更新 $b$:$b_{new} = 0.10 - 0.01 × 0.28= 0.0972$ ===验证——更新后参数是否真的让损失下降了?=== 用更新后的参数重新做一次前向传播$\hat{y}_{new} = 0.386 × 5.0 + 0.59216 × 2.8 + 0.0972= 3.685248(米)$ 新损失:$L_{new} = (3.685248 - 3.50)² / 2 ≈ 0.01716$ 对比: ^项目^更新前^更新后^ |预测值ŷ|3.78|3.685| |损失L|0.0392|0.0172| |误差(ŷ - y)|+0.28|+0.185| 损失从 0.0392 降到了 0.0172,下降了约 56%。仅仅一轮迭代,模型就朝着正确的方向迈进了一大步。