news 2026/4/24 23:34:07

用 Excel 逐步展示 MLP 的前向传播、反向传播和参数更新

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用 Excel 逐步展示 MLP 的前向传播、反向传播和参数更新

用 Excel 逐步展示 MLP 的前向传播、反向传播和参数更新

配套 Excel 文件:MLP计算过程.xlsx

这篇文章配合 Excel 阅读,不写成纯理论推导。

为避免公式在不同博客平台、Windows 编辑器或 Markdown 预览器中出现乱码,本文的公式全部使用 ASCII 写法。例如:

eta 表示学习率 alpha 表示 Leaky ReLU 负半轴斜率 delta_out 表示输出层误差信号 delta_h 表示隐藏层误差信号 sum(...) 表示求和 * 表示乘法

1. 这个 Excel 展示了什么

目标是用 Excel 把一个很小的 MLP,也就是多层感知机,完整拆开。

它展示的不是训练很多轮之后的模型,而是展示“一次样本输入之后,模型如何完成一次前向传播、如何计算损失、如何反向传播得到梯度、如何根据梯度更新参数”。

简单说,这份 Excel 展示了下面这条链路:

输入样本 -> 隐藏层线性组合 -> 隐藏层激活输出 -> 输出层线性组合 -> 最终预测 -> 损失 -> 输出层梯度 -> 隐藏层梯度 -> 参数更新前后对比

2. 先理解网络结构

本例中的 MLP 非常小,结构如下:

1 个输入特征 6 个隐藏层神经元 1 个输出层神经元

也可以写成:

x -> h1, h2, h3, h4, h5, h6 -> y_hat

其中:

  • x是输入样本。
  • h1h6是隐藏层的 6 个神经元。
  • y_hat是模型最终预测值。
  • y是真实目标值。

本例使用的激活函数是 Leaky ReLU。为了避免公式乱码,本文用alpha表示 Leaky ReLU 在负半轴的斜率。

Leaky ReLU 的定义如下:

leaky_relu(z) = z, if z > 0 leaky_relu(z) = alpha * z, if z <= 0

本例中:

alpha = 0.05

所以,如果某个神经元的线性组合结果是正数,激活输出就是它本身;如果是负数,就乘以0.05,保留一个较小的负值。

3.参数与样本

3.1 样本和超参数

本例的输入、目标和学习率如下:

项目数值
输入样本x5
真实目标y208
学习率eta0.01
Leaky ReLU 负半轴斜率alpha0.05

这里的学习率eta会在参数更新时使用:

new_parameter = old_parameter - eta * gradient

3.2 隐藏层参数

每个隐藏层神经元都有两个参数:

W_xh_j 输入 x 到第 j 个隐藏神经元的权重 b_h_j 第 j 个隐藏神经元的偏置

Excel 中整理出的初始参数如下:

隐藏神经元W_xhb_h
h11010
h22010
h33010
h42010
h51010
h62010

3.3 输出层参数

每个隐藏层神经元到输出层都有一个权重:

W_ho_j 第 j 个隐藏神经元到输出层的权重

对应数值如下:

隐藏神经元W_ho
h110
h220
h310
h410
h530
h620

输出层还有一个偏置:

b_out = 20

4.前向传播

前向传播的作用是:把输入x一步一步算成预测值y_hat,再用预测值和真实值计算损失。

4.1 第一步:隐藏层线性组合

对每个隐藏层神经元,都先计算一个线性组合:

z_h_j = x * W_xh_j + b_h_j

这里:

  • z_h_j表示第j个隐藏神经元的线性组合结果。
  • x是输入样本。
  • W_xh_j是输入到该隐藏神经元的权重。
  • b_h_j是该隐藏神经元的偏置。

h1为例:

z_h_1 = x * W_xh_1 + b_h_1 z_h_1 = 5 * 10 + 10 z_h_1 = 60

6 个隐藏层神经元的线性组合结果如下:

隐藏神经元计算过程z_h
h15 * 10 + 1060
h25 * 20 + 10110
h35 * 30 + 10160
h45 * 20 + 10110
h55 * 10 + 1060
h65 * 20 + 10110

4.2 第二步:隐藏层激活

隐藏层线性组合之后,要经过 Leaky ReLU 激活函数:

a_h_j = leaky_relu(z_h_j)

也就是:

a_h_j = z_h_j, if z_h_j > 0 a_h_j = alpha * z_h_j, if z_h_j <= 0

本例中所有z_h_j都是正数,所以激活函数不会改变数值:

隐藏神经元z_ha_h
h16060
h2110110
h3160160
h4110110
h56060
h6110110

这里的a_h是隐藏层输出,它会作为输出层的输入。

4.3 第三步:输出层线性组合

输出层把 6 个隐藏层输出加权求和,然后加上输出层偏置。

公式如下:

z_out = sum(a_h_j * W_ho_j) + b_out

把本例的数值代入:

z_out = 60 * 10 + 110 * 20 + 160 * 10 + 110 * 10 + 60 * 30 + 110 * 20 + 20

逐项计算:

60 * 10 = 600 110 * 20 = 2200 160 * 10 = 1600 110 * 10 = 1100 60 * 30 = 1800 110 * 20 = 2200 b_out = 20

所以:

z_out = 600 + 2200 + 1600 + 1100 + 1800 + 2200 + 20 z_out = 9520
```excel =SUMPRODUCT(hidden_activation_range, output_weight_range) + output_bias

4.4 第四步:最终预测

输出层线性组合之后,仍然经过 Leaky ReLU:

y_hat = leaky_relu(z_out)

因为本例中:

z_out = 9520

它是正数,所以:

y_hat = 9520

这就是当前模型对样本x = 5的预测值。

4.5 第五步:计算损失

真实目标值是:

y = 208

预测值是:

y_hat = 9520

本 Excel 使用平方损失:

Loss = (y_hat - y)^2

代入数值:

Loss = (9520 - 208)^2 Loss = 9312^2 Loss = 86713344

这个损失非常大,说明当前初始参数让模型预测得过大。

4.6 前向传播小结

前向传播最终得到:

项目数值
z_out9520
y_hat9520
y208
Loss86713344

到这里,模型已经知道“自己预测错了多少”。下一步反向传播要解决的是:每个参数应该为这个错误承担多少责任。

5.反向传播

反向传播的目标是计算梯度。

梯度可以理解为:

如果某个参数变大一点,损失会怎样变化。

如果梯度是正数,说明这个参数继续变大会让损失变大,所以更新时要把它减小。

如果梯度是负数,说明这个参数继续变大会让损失变小,所以更新时会把它增大。

本例中大多数梯度是正数,因为预测值9520远大于真实值208,模型需要把很多参数往减小输出的方向调整。

6. 先计算输出层误差信号delta_out

损失函数是:

Loss = (y_hat - y)^2

先求损失对预测值的导数:

dLoss_dy_hat = 2 * (y_hat - y)

代入数值:

dLoss_dy_hat = 2 * (9520 - 208) dLoss_dy_hat = 2 * 9312 dLoss_dy_hat = 18624

然后考虑输出层激活函数的导数。

输出层有:

y_hat = leaky_relu(z_out)

因为:

z_out = 9520 > 0

所以:

dy_hat_dz_out = 1

输出层误差信号定义为:

delta_out = dLoss_dy_hat * dy_hat_dz_out

代入数值:

delta_out = 18624 * 1 delta_out = 18624

7. 输出层权重梯度

输出层的公式是:

z_out = sum(a_h_j * W_ho_j) + b_out

对于某个输出层权重W_ho_j,它的梯度是:

dLoss_dW_ho_j = a_h_j * delta_out

为什么是这样?

因为W_ho_j只通过这一项影响输出层:

a_h_j * W_ho_j

所以W_ho_jz_out的影响大小就是a_h_j。再乘上输出层误差信号delta_out,就得到损失对这个权重的梯度。

输出层 6 个权重的梯度如下:

权重a_hdelta_out梯度 dLoss_dW_ho
W_ho_160186241117440
W_ho_2110186242048640
W_ho_3160186242979840
W_ho_4110186242048640
W_ho_560186241117440
W_ho_6110186242048640

W_ho_1为例:

dLoss_dW_ho_1 = a_h_1 * delta_out dLoss_dW_ho_1 = 60 * 18624 dLoss_dW_ho_1 = 1117440

8. 输出层偏置梯度

输出层线性组合中,偏置是直接加上的:

z_out = sum(a_h_j * W_ho_j) + b_out

b_out每增加 1,z_out就增加 1,所以:

dz_out_db_out = 1

因此输出层偏置梯度就是:

dLoss_db_out = delta_out dLoss_db_out = 18624

9. 隐藏层误差信号delta_h

隐藏层梯度要比输出层多一步,因为隐藏层不是直接产生最终预测,而是先影响输出层,再影响损失。

隐藏层误差信号的公式是:

delta_h_j = delta_out * W_ho_j * f_prime_z_h_j

其中:

  • delta_out表示输出层错了多少。
  • W_ho_j表示第j个隐藏神经元对输出层影响有多大。
  • f_prime_z_h_j表示隐藏层激活函数在当前位置的导数。

本例中所有隐藏层的z_h都是正数,所以 Leaky ReLU 的导数都是:

f_prime_z_h_j = 1

因此隐藏层误差信号变成:

delta_h_j = delta_out * W_ho_j

逐个计算:

隐藏神经元delta_outW_hof_prime_z_hdelta_h
h118624101186240
h218624201372480
h318624101186240
h418624101186240
h518624301558720
h618624201372480

h5为例:

delta_h_5 = delta_out * W_ho_5 * f_prime_z_h_5 delta_h_5 = 18624 * 30 * 1 delta_h_5 = 558720

这说明h5这条路径对输出影响很大,因为它连接到输出层的权重W_ho_5 = 30,所以它分到的误差信号也更大。

10. 隐藏层输入权重梯度

隐藏层线性组合是:

z_h_j = x * W_xh_j + b_h_j

对于隐藏层输入权重W_xh_j,梯度公式是:

dLoss_dW_xh_j = x * delta_h_j

因为本例中:

x = 5

所以每个隐藏层输入权重梯度就是:

dLoss_dW_xh_j = 5 * delta_h_j

逐个计算:

权重xdelta_h梯度 dLoss_dW_xh
W_xh_15186240931200
W_xh_253724801862400
W_xh_35186240931200
W_xh_45186240931200
W_xh_555587202793600
W_xh_653724801862400

W_xh_2为例:

dLoss_dW_xh_2 = x * delta_h_2 dLoss_dW_xh_2 = 5 * 372480 dLoss_dW_xh_2 = 1862400

11. 隐藏层偏置梯度

隐藏层线性组合中,偏置也是直接加上的:

z_h_j = x * W_xh_j + b_h_j

所以:

dz_h_j_db_h_j = 1

因此隐藏层偏置梯度就是:

dLoss_db_h_j = delta_h_j

逐个结果如下:

偏置梯度 dLoss_db_h
b_h_1186240
b_h_2372480
b_h_3186240
b_h_4186240
b_h_5558720
b_h_6372480

12.参数更新

参数更新使用同一个规则:

new_parameter = old_parameter - eta * gradient

本例中:

eta = 0.01

所以更新幅度是:

adjustment = eta * gradient

再从旧参数中减去这个调整幅度。

12.1 输出层权重更新

W_ho_1为例:

old W_ho_1 = 10 gradient = 1117440 eta = 0.01 adjustment = 0.01 * 1117440 adjustment = 11174.4 new W_ho_1 = 10 - 11174.4 new W_ho_1 = -11164.4

输出层权重更新结果如下:

参数旧值梯度调整幅度更新后
W_ho_110111744011174.4-11164.4
W_ho_220204864020486.4-20466.4
W_ho_310297984029798.4-29788.4
W_ho_410204864020486.4-20476.4
W_ho_530111744011174.4-11144.4
W_ho_620204864020486.4-20466.4

12.2 输出层偏置更新

输出层偏置更新如下:

old b_out = 20 gradient = 18624 eta = 0.01 adjustment = 0.01 * 18624 adjustment = 186.24 new b_out = 20 - 186.24 new b_out = -166.24

12.3 隐藏层输入权重更新

隐藏层输入权重也使用同一个规则:

new W_xh_j = old W_xh_j - eta * dLoss_dW_xh_j

更新结果如下:

参数旧值梯度调整幅度更新后
W_xh_1109312009312-9302
W_xh_220186240018624-18604
W_xh_3309312009312-9282
W_xh_4209312009312-9292
W_xh_510279360027936-27926
W_xh_620186240018624-18604

12.4 隐藏层偏置更新

隐藏层偏置更新公式:

new b_h_j = old b_h_j - eta * dLoss_db_h_j

更新结果如下:

参数旧值梯度调整幅度更新后
b_h_1101862401862.4-1852.4
b_h_2103724803724.8-3714.8
b_h_3101862401862.4-1852.4
b_h_4101862401862.4-1852.4
b_h_5105587205587.2-5577.2
b_h_6103724803724.8-3714.8

13. 为什么这里的参数会变成很大的负数

有同学可能会疑惑:为什么更新后很多参数一下变成很大的负数?

原因有两个:

第一,本例预测值远大于真实值:

y_hat = 9520 y = 208

误差很大:

y_hat - y = 9312

第二,本例没有做归一化,也没有把损失写成0.5 * error^2,所以导数比较大:

dLoss_dy_hat = 2 * 9312 = 18624

隐藏层和输出层权重又会继续放大梯度。例如:

dLoss_dW_ho_3 = a_h_3 * delta_out dLoss_dW_ho_3 = 160 * 18624 dLoss_dW_ho_3 = 2979840

学习率虽然只有0.01,但乘上几百万级别的梯度后,调整幅度仍然很大:

adjustment = 0.01 * 2979840 adjustment = 29798.4

所以更新后参数会发生大幅变化。

这也是 Excel 教学展示的价值:它能让我们直接看到梯度为什么大、更新为什么大,而不是只记住一个抽象公式。

14. 一句话总结

这份 Excel 展示的是 MLP 的一次完整计算:

前向传播:用当前参数算出预测值和损失。 反向传播:从损失开始,计算每个参数的梯度。 参数更新:用 new = old - eta * gradient 更新参数。

如果只记住一个核心逻辑,可以记成:

先算模型错了多少,再算每个参数对错误负多少责任,最后按责任大小调整参数。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/24 23:31:56

Windows多显示器DPI缩放终极指南:SetDPI命令行工具实战详解

Windows多显示器DPI缩放终极指南&#xff1a;SetDPI命令行工具实战详解 【免费下载链接】SetDPI 项目地址: https://gitcode.com/gh_mirrors/se/SetDPI 还在为Windows多显示器DPI缩放不一致而烦恼吗&#xff1f;你是否曾经遇到过主显示器文字清晰&#xff0c;而副显示器…

作者头像 李华
网站建设 2026/4/24 23:31:56

从Element Plus到Iconfont:在Vue3项目中优雅混用两套图标库的实战指南

从Element Plus到Iconfont&#xff1a;在Vue3项目中优雅混用两套图标库的实战指南 当你在Vue3项目中同时使用Element Plus和Iconfont时&#xff0c;是否遇到过这样的困扰&#xff1a;两套图标风格不统一、引入方式各异、打包体积难以控制&#xff1f;本文将带你解决这些痛点&am…

作者头像 李华
网站建设 2026/4/24 23:30:50

PostgreSQL实战进阶:从核心原理到高效运维

1. PostgreSQL架构设计与核心原理剖析 1.1 MVCC机制深度解析 PostgreSQL的多版本并发控制&#xff08;MVCC&#xff09;是其事务处理的核心引擎。与传统的锁机制不同&#xff0c;MVCC通过创建数据行的多个版本来实现并发控制。每个事务看到的是特定时间点的数据快照&#xff0c…

作者头像 李华
网站建设 2026/4/24 23:25:30

大模型应用开发核心技术栈深度解析:从知识增强到模型定制,再到模型压缩与部署,带你高效低成本落地大模型!

本文深入探讨了大模型应用开发的核心技术栈&#xff0c;分析了当前大模型应用面临的挑战&#xff0c;如知识滞后、幻觉问题、部署成本高、数据隐私等。文章重点介绍了三大核心技术方向&#xff1a;知识增强与检索&#xff08;RAG&#xff09;、模型定制与微调、模型压缩与部署。…

作者头像 李华
网站建设 2026/4/24 23:22:19

Chroma 向量数据库详解

一、Chroma 是什么&#xff1f; 轻量级 向量数据库&#xff08;专门存文本、图片、音频的向量&#xff09;主打&#xff1a;简单、开箱即用、本地优先不需要复杂配置&#xff0c;Python 几行就能跑自动做 embedding&#xff08;文本转向量&#xff09;&#xff0c;不用自己写模…

作者头像 李华