ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

从零实现反向传播:AI工程学习的正确起点

从零实现反向传播:AI工程学习的正确起点 1. 先搞清楚from scratch的边界你到底要从哪里开始最近带团队招人、带实习生我反复遇到同一个场景候选人简历上写着精通PyTorch/TensorFlow能流畅地说出model.fit()的用法但当我问一句你清楚反向传播时链式法则具体作用在哪个张量上吗对面往往是沉默。这种状态不能叫会AI工程只能叫会用工具。所以当ai-engineering-from-scratch这个标题第一次出现在我面前时我反而觉得它戳破了一个行业里长期存在的幻觉大多数人以为从零开始是一个技术动作其实它是一个认知动作。你要先定义清楚——你到底要从哪个零开始是数学理论的零是代码实现能力的零还是工程架构的零这三个起点完全不同对应的学习路径也天差地别。这篇文章我想站在一个真正带队做过项目、带过新人、踩过无数坑的从业者角度聊聊我对从零开始做AI工程的理解和实操路径。内容不限定某个具体框架也不搞三个月速成大法而是帮你把AI工程这四个字拆开揉碎讲清楚哪些东西必须亲手做一遍哪些东西你只需要知道存在即可以及为什么大部分人的学习顺序是错的。先说结论from scratch最合理的边界不是从零发明一切而是从零理解并亲手重建关键环节。你不需要从晶体管开始造GPU不需要从汇编开始写Python解释器但你需要亲手实现过一次神经网络的前向传播、反向传播和参数更新——哪怕是个极简版本。因为你只有亲手写过一次框架API对你来说才不是魔法而是可拆解的工程组件。这条边界听起来简单但实际执行起来极其考验定力。因为市面上90%的教程都在教你快而真正值钱的学习路径恰恰是慢的那一段。1.1 多数人理解的从零开始是错的我见过两类极端的从零主义者。第一类是速成派他们的从零是从pip install torch开始的。这类人的典型路径是装好环境→跑通一个MNIST官方示例→换个数据集、改个网络层数→开始刷题面试。他们确实在用人工智能但这个用建立在一个巨大的黑盒之上。模型不收敛时他们只能加learning rate、改batch size、换optimizer瞎试完全无法定位问题在数据、在梯度还是在网络结构。这类人撞到真实业务场景中分布式训练、模型量化、推理时延优化这些硬骨头基本毫无还手之力。第二类是理论死磕派他们的从零是从数学证明开始的。买了一堆砖头书花三个月学矩阵论、凸优化、统计学试图先把所有推导都弄明白再动手写代码。结果是——三个月后前面的章节忘光了代码一行没写过信心也没了。这类人犯的错误是把自己当成研究者而不是工程师。真正的AI工程是工程不是科学。工程的核心是在真实约束下交付可用的系统不是证明某个定理。所以我个人建议的学习顺序非常明确先动手写一个能训练起来的极简系统让前向→反向→更新这个循环在脑子里转起来然后再回过头补理论——这时候你会发现线性代数和概率论不是抽象符号而是工具你学起来会快十倍。1.2 我给这个从零划的三条边界线如果你决定按ai-engineering-from-scratch来规划自己的学习或团队培养路径我建议你把从零拆成三条清晰的边界线层级内容建议投入时间目标第一层从零实现手写线性回归、感知机、两层神经网络含反向传播2-3周彻底理解训练循环的内部机制第二层从零工程化不依赖框架实现数据切分、特征处理、模型评估与实验记录2-3周建立工程化思维理解数据与模型的边界第三层从零集成用成熟框架PyTorch等复刻第一层的模型再叠加部署、推理优化3-4周打通从训练到上线的完整闭环第一条线是最容易被跳过的但恰恰是最重要的。第二条线是最容易被忽视的因为大多数人觉得数据切分和评估太基础但实际工程里80%的错误都出在这个环节。第三条线是大多数人唯一在做的但它应该在前两条之后顺理成章地发生而不是作为起点。我见过一个很典型的反例一个数学系背景的同学直接跳到第三层用PyTorch搭了一个Transformer做文本分类训练时loss一路下降到0.01看起来完美。但测试集上的指标却只有62%。他花了整整两周排查最后发现是数据预处理时把标签信息泄漏进了训练集。如果这个同学先经历第二层自己在第一层代码里写数据切分他就绝不会犯这个低级错误——因为你会亲手为泄漏付出代价而不只是看别人的警告。2. 打地基数学与工程基础只学用得到的部分我知道说到从零开始很多人第一反应是恐惧——是不是要把本科数学全学一遍我明确告诉你不需要。从零这件事最被高估的地方就是对数学基础的需求量。但也不要说数学没用。数学在AI工程里扮演的角色是诊断工具模型不收敛时你是靠直觉猜还是靠公式推导定位数据分布异常时你是靠经验试错还是靠统计检验确认在真实项目里后者往往能帮你省下几天的排查时间。我的建议是把数学学习压缩到够用为止而且要以用带学不要系统性地从头啃。下面是我梳理的三条主线每一条都指向工程中真正会用到的部分。2.1 线性代数不需要会证明但要有直觉线性代数对你来说只有三个真正重要的点第一矩阵乘法就是批量计算的抽象。神经网络的前向传播本质就是一系列矩阵乘法叠加非线性。你可能听说过一个32x32的RGB图像展开后有3072个维度一个全连接层要处理这个输入这就是一个3072到1024的矩阵乘法。你要的直觉是这一层可以同时计算1024个特征每个特征都是输入的加权组合。仅此而已。第二特征值/奇异值分解代表了信息压缩的方向。PCA主成分分析、矩阵低秩分解、词向量的SVD初始化都建立在这个直觉上。你不需要会手算特征值但你要理解大特征值对应数据的主要变化方向这个物理含义。第三范数是对距离和误差的度量。L1、L2正则化为什么有效因为它们在损失函数里惩罚了权重的大小。L2倾向让权重均匀变小L1会让权重变得稀疏。这个直觉在调试过拟合时极其有用。我见过太多人卡在特征值怎么算上其实工程中你几乎不会手算。你应该把精力放在这个数学对象的直觉含义是什么上等到真正需要用的时候再深入公式推导。2.2 机器学习理论先手工推导一遍线性回归再调包机器学习理论的核心动作是拟合。拟合的意思很简单给定一堆点找到一条线/曲线让预测值和真实值之间的误差最小。线性回归就是最基础的拟合模型代价函数是均方误差求解方法是闭式解或梯度下降。问题的关键是你要亲手把线性回归从数据集到损失函数到梯度更新完整写一遍而不是直接sklearn.linear_model.LinearRegression。为什么不是因为调包不香而是因为线性回归里包含了机器学习的所有核心概念特征矩阵、标注、损失函数、梯度、学习率、收敛。你亲手写完一遍你就理解了fit()这个API背后到底发生了什么。之后你再去学逻辑回归、SVM、神经网络会发现它们都是在同一个骨架上的变体——换损失函数、换模型结构、换优化方法。我不夸张地说亲手实现一遍线性回归是从零工程这条路线上性价比最高的一步。花费大概一个下午但它给你建立的训练循环心智模型之后十几年都用得到。如果你是程序员出身python基本功大概率没问题。但如果你的主业不是编程我建议你先补上Python的数据科学生态NumPy的向量化思维、Pandas的数据表操作、Matplotlib的可视化。这三个库是AI工程的数据地基。不用精通但你要能流畅地完成加载数据→清理→变换→可视化这一套流程。2.3 概率统计服务不确定性和评估概率统计在AI工程里有两个作用第一个是理解模型的不确定性第二个是正确评估模型的效果。理解不确定性说的是模型的输出本质上是概率分布。召回率、精确率、ROC曲线、AUC、置信区间、P值——这些评估指标全部建立在概率统计之上。你不需要背公式但你要知道95%置信区间意味着什么AUC0.85好还是0.9好样本量小的时候指标波动有多大正确评估模型几乎决定了你能不能做好AI工程。我见过一个团队把一个垃圾模型评估成了优秀模型原因是他们的验证集只有200个样本而且做了多次实验后只报最好的一次结果。这就是典型的统计素养缺失——没有意识到样本量和实验次数对结果可信度的影响。所以我的建议是概率统计部分你至少要理解条件概率、贝叶斯公式、正态分布、假设检验的基本思想。再往深了学等你实际工作中碰到再去查也来得及。3. 亲手实现核心算法组件从零构建感知机到两层网络的完整过程如果你只从这篇文章里带走一个技术动作我强烈建议你亲手实现一次感知机和两层神经网络用纯粹的NumPy不碰任何深度学习框架。这一步做完你再看框架文档感觉会完全不同。3.1 为什么我建议从感知机而不是PyTorch开始感知机是最简单的神经元模型输入特征乘以权重加权求和经过激活函数输出预测。它简单到什么程度核心代码不到20行。但它包含了神经网络的一切基本要素权重、偏置、激活函数、损失函数、梯度更新。很多刚入门的人觉得感知机太简单了直接上CNN吧。这个想法非常危险。因为CNN的复杂度会直接淹没你对训练循环本身的理解——你以为你在学神经网络其实你在学API的拼装方法。而感知机的简单恰恰让你能盯着训练循环内部的核心逻辑看数据进来→算预测→算误差→反向传播→更新权重→再来一遍这个循环才是深度学习的真正心脏。3.2 一次完整的从零训练过程代码与解释我直接给出一段可以运行的最小实现。我们用感知机做二分类数据集用sklearn自带的make_classification生成。注意这里只允许用NumPy和sklearn的数据生成部分它只是提供一个方便的数据来源模型本身完全自己写。import numpy as np from sklearn.datasets import make_classification from sklearn.model_selection import train_test_split # 1. 生成数据两个特征两类标签线性可分 X, y make_classification( n_samples300, n_features2, n_redundant0, n_informative2, n_clusters_per_class1, class_sep1.5, random_state42 ) y np.where(y 0, -1, 1).astype(np.float32) # 感知机标签用1/-1 X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_state42 ) # 2. 感知机训练 def perceptron_train(X, y, lr0.01, epochs50): # 初始化权重为零向量含偏置维度 w np.zeros(X.shape[1] 1) # [w1, w2, b] X_b np.c_[X, np.ones((X.shape[0], 1))] # 最后一列是1对应偏置 for epoch in range(epochs): misclassified 0 for i in range(len(X_b)): xi X_b[i] yi y[i] # 前向计算线性输出 logit np.dot(w, xi) # 感知机规则只在误分类时更新 if yi * logit 0: misclassified 1 w w lr * yi * xi # 更新公式 if misclassified 0: print(f第{epoch 1}轮收敛误分类数归零) break return w def predict(X, w): X_b np.c_[X, np.ones((X.shape[0], 1))] logits X_b w return np.where(logits 0, 1, -1) # 3. 训练并测试 w perceptron_train(X_train, y_train) train_pred predict(X_train, w) test_pred predict(X_test, w) print(f训练准确率: {(train_pred y_train).mean():.3f}) print(f测试准确率: {(test_pred y_test).mean():.3f})这段代码你不需要跑光看结构就能明白感知机的全部逻辑。重点观察三件事更新公式w w lr * yi * xi。这个公式的含义是当预测错误时把权重向正确的方向推一步。推的幅度由lr学习率控制。收敛条件感知机的收敛性是一个经典的数学结论——只要数据线性可分算法在有限步内必然收敛。你亲手跑一遍看到第N轮收敛的字样时这种亲手验证定理的感觉是任何框架教程都给不了的。测试评估训练集和测试集分开评估哪怕这么小的模型也能体现出泛化的概念——在训练集上达到100%不代表测试集能到100%。3.3 从感知机到两层网络反向传播的价值感知机只能处理线性可分的数据碰到异或XOR这类线性不可分问题就彻底无能为力。解决办法是引入隐藏层和反向传播。两层网络的代码量大概在一百行左右核心是四个矩阵/向量操作Z1 X W1 b1A1 relu(Z1)Z2 A1 W2 b2A2 sigmoid(Z2)。前向传播就是这四个步骤的连锁。反向传播则是从输出层往前逐层计算损失对各参数的梯度。我建议你手写一遍但这里不贴完整代码了——因为感知机的训练循环逻辑已经为你建立了骨架剩下的就是在骨架里塞进多层非线性链式法则这些零件。你真正要理解的是反向传播中的那个反向二字是怎么来的。还是用链式法则输出层的损失对W2的梯度依赖损失对Z2的梯度而Z2对W2的梯度非常容易算就是A1的转置乘以另一个梯度。再往前一层损失对W1的梯度要经过Z2→A1→Z1→W1这条路径逐层回传。每一层做的事其实就是把上层传来的梯度乘以当前层的局部导数然后继续往前传。这个逐层回传的过程就是反向传播。等你亲自写完并跑通这两层网络你会获得一个极其宝贵的自信以后再碰到任何深度模型哪怕是最新的某种大模型架构你都知道它本质上仍然是在做前向传播→计算损失→反向传播→参数更新这个循环。新架构只是往这个循环里塞了更复杂的层、更巧妙的模块但没有改变这个循环本身。4. 工程化短板数据、实验与评估比模型更拖后腿写到这里我特别想说一个在AI工程里被严重低估的事实模型架构是最容易的部分数据切分、实验管理和评估体系才是最拖后腿的部分。我见过太多新手把一个模型训练好之后卡在我到底该怎么证明这个模型真的有效这一步然后开始胡编指标或者反复调参直到测试集上数字好看为止——这都是在自欺欺人。从零工程化的重点其实不是模型而是数据链路和实验纪律。4.1 数据切分与评估中的隐性错误数据泄漏和过拟合数据泄漏是AI工程最常见的低级错误也是最致命的错误。它的本质是训练集和验证集/测试集之间存在信息交叉导致评估结果虚高。一个非常典型的场景做时间序列预测时如果直接train_test_split随机切分测试集中某些样本的时间戳可能早于训练集中的样本——这就等于让模型偷看未来。正确做法是按时间先后顺序切分训练集只用过去的数据测试集只用未来的数据。另一个场景对特征做归一化、填补缺失值等预处理时如果先对整个数据集拟合了统计量如均值和标准差再切分训练/测试集那测试集就间接暴露给了训练过程。正确做法是先只对训练集做fit再用训练集学到的统计量去transform测试集。数据泄漏一旦发生模型的实际表现会远低于你记录的漂亮指标这在生产环境中是事故级别的灾难。我在真实项目里见过一个团队模型上线后业务指标只有预期的一半排查了一周才发现测试集里混进了训练集同样的图片样本。这个坑的可怕之处在于你很难自己发现因为训练loss看起来一切正常。所以训练前请你手动检查一遍数据切分的代码问自己三个问题训练集和测试集的样本有没有重叠预处理归一化、缺失值填补、特征计算是不是只在训练集上fit的有没有任何字段是未来信息——即预测时无法获取、但训练时你却用了的数据4.2 用一份模板组织你的实验管理AI工程里有句话叫Ablation is the key to understanding消融实验是理解模型的关键。但很多新手从来没有记录实验的习惯。今天调了个学习率明天换了个网络层数三天后想对比结果发现完全不记得当时的参数配置和数据处理方式——只好重新跑浪费时间。我建议你使用我下面这个实验记录模板它是从工程实践中总结出来的。不需要搞什么重型MLOps平台一个Markdown文件或Excel就能搞定字段内容示例说明实验编号EXP-023唯一标识日期2025-06-18时间戳问题描述手写数字识别准确率低于93%明确要解决什么问题数据版本v2修复了旋转增强的随机种子数据变化必须记录模型结构Conv2d(3,32)-ReLU-Pool-ResBlock...完整网络结构关键超参lr1e-3, batch64, wd1e-4学习率、批量、权重衰减等预处理方式归一化水平翻转增强数据管线变化训练指标train_acc0.982, loss0.031训练端指标验证指标val_acc0.951验证端指标唯一可信对比基准备注尝试了AdamW替代Adam验证集提升约1.2%记录直觉和观察有了这张表你做实验时就能回到科学方法论上每次只改一个变量其他全部固定然后对比记录。这是从零工程师和调包侠的分水岭——前者在系统地探索后者在碰运气。5. 端到端串联:第二个月的完整练手项目参考当你完成了前三章的从零理解和第四章的工程化纪律一个自然的进阶是做一个端到端的小项目把数据、模型、训练、评估、部署的所有环节串起来形成一条完整的链路。我强烈建议你现在不要碰任何大型数据集或大模型架构而是做一个手写数字识别系统。它经典、可控、有明确的评估标准是从零到上线这个过程的完美演练场。5.1 项目目标与目录结构目标训练一个神经网络对手写数字MNIST进行分类并把它封装成一个命令行应用用户输入图片路径程序输出预测的数字和置信度。建议的工程目录结构长这样digit_identifier/ ├── data/ │ ├── raw/ │ └── processed/ ├── src/ │ ├── data_loader.py │ ├── tiny_nn.py │ ├── train.py │ ├── evaluate.py │ └── predict.py ├── experiments/ │ └── exp_log.md ├── models/ │ └── last_run.pt └── README.md这个结构并不复杂但它保证了三点数据与代码隔离、实验记录与代码隔离、模型产物集中管理。这已经是生产级项目的雏形了。5.2 关键环节怎么做数据加载、训练循环、评估与导出推理数据加载把原始图片数据存到data/raw/写一个data_loader.py负责读取、预处理、切分。切分时random_state固定保证复现。这一步非常重要很多人在这一步不设随机种子导致每次运行数据都不一样实验永远无法复现。训练循环用你第三章实现的源码雏形换成PyTorch或仍然用NumPy实现都可以。我建议第一版用NumPy实现一个两层网络然后在第二版换成PyTorch这样你能真实感受到框架在工作量上帮你释放的负担——同时也明白框架帮你做的那部分事务是什么。评估测试集上计算准确率的同时一定要生成混淆矩阵。手写数字分类里混淆矩阵能帮你看到模型把7误判成1这类系统性错误——这比单纯一个数字有用得多。伪代码就不用写了实际操作也没那么复杂。重点在于你要完整走完训练→评估→导出→推理这条链而不是再次卡在训练完就结束了。训练完把模型权重保存到models/目录然后写一个predict.py加载权重、对新图片预测打印结果。这一个动作就算完成了模型上线的90%。5.3 完成这个项目后你可以问自己的几个问题做完这个项目之后我建议你认真回答下面几个问题每个问题都指向工程能力的关键一环如果训练集和测试集的分布不一样比如训练集都是白底黑字测试集换成了黑底白字模型表现会怎样为什么如果你把隐藏层从一层加到三层训练时间翻了三倍但测试集准确率反而下降了。这是为什么提示过拟合、梯度消失、优化困难每个都要能说清楚。如果你删掉ReLU激活函数只保留线性层把网络叠到10层会发生什么提示多层线性变换等价于单层线性变换。你的predict.py能不能处理旅游照片里的模糊数字如果不能是模型的问题还是预处理的问题你怎么改进这四个问题没有一个需要新的库或框架全是在从零工程这个阶段你应该能回答的。如果你想检验自己的学习成果这算一份自定义的期中考试卷。6. 从训练师走向工程架构师的进阶路径完成第五章的端到端项目后你已经具备了从零训练一个模型并上线的基本能力。这时候你可能开始不满足了——MNIST太小了我想试试真实业务场景或者更大的模型。这个念头没问题但我建议你带着下面几条主线往前走因为它们决定了你未来是调包侠还是AI工程架构师。6.1 从单机到分布式的三条主线真实的大模型训练不可能在单卡甚至单机上完成。你需要理解分布式训练的三条主线每一条第理解到知道存在并能找到文档的层级就够但你要知道它们为什么存在。数据并行是最直观的思路数据太大一台机器装不下那就把数据切成多份分发到多个GPU上。每个GPU复制一份模型副本用自己的数据块计算梯度然后通过梯度同步机制如AllReduce汇总平均再统一更新参数。PyTorch DDP就是这个机制的标准实现。模型并行解决的是模型太大装不下的问题单张卡放不下整个模型那就把模型的层拆开不同层放在不同GPU上。这带来一个经典问题——序列依赖导致的空闲所以又有了流水线并行把样本分成小的micro-batch让不同GPU在流水线上同时处理不同批次的微批。张量并行是更细的拆分把单层内部的权重矩阵切成多块分别放在多个GPU上最后合并结果。Transformer里每个attention head就可以放在不同的GPU上独立计算这就是典型的张量并行。这三条主线的学习目标不是让你现在就去搭建巨型集群而是让你在面试和真实项目中听到分布式训练名词时不再发怵知道它们在解决什么问题。等你真正遇到单卡训练要跑两周的资源瓶颈时再深入细节会从容得多。6.2 我在实际项目中踩过最深的几个坑希望你别重蹈覆辙最后分享几个我在真实项目中踩过的坑。这些坑有的让我加班到凌晨有的让项目延期了一周每一个都是血泪教训。坑一环境依赖的地狱。我见过一个项目因为训练时用的CUDA版本和推理服务的环境不一致导致模型输出完全紊乱——这不是模型的问题是环境的一致性问题。后来学乖了固定Docker镜像把CUDA、cuDNN、Python、PyTorch全部锁定版本训练和推理用同一个镜像。这可能在AI工程里听着毫无技术含量但它就是生产环境中最实在的快车道。坑二评估指标选择错误。遇到过类别极度不平衡的业务数据正样本占1%负样本占99%。团队用Accuracy做指标训练出来的模型准确率99%但把正样本全部判成了负样本业务价值为0。改成用F1-Score和AUC之后模型的真实能力才被暴露。这提醒了我指标选错整个项目的优化方向就是错的。坑三过度依赖随机种子。有段时间训练结果总是神秘地时好时坏我以为是模型结构的问题调了一周架构。最后发现只是忘了固定NumPy和PyTorch的随机种子每次数据切分和权重初始化都不一样。这件事给我留下的教训是先固定你能固定的所有不确定性来源再去排查模型本身的不确定性。这些坑没有一个需要高深的数学知识它们全都在工程纪律的范畴内。而这恰恰就是AI工程与机器学习理论最大的分野——理论追求优雅工程追求可靠。7. 最后的实操建议别急着看结果把过程走完写到这里我其实最想跟你分享的不是哪段代码更优雅不是哪个框架更流行而是从零开始这个动作本身的含义。市面上有太多AI课程包装出一个30天上手大模型的幻觉但真实世界的AI工程从来不是靠速食学会的。它更像学游泳——你可以看完所有教科书上的动作分解但只有你真正下水扑腾过几回、呛过几口水你才算真的会了。所以我的实操建议非常简单把第二章的感知机代码、第三章的两层网络、第五章的端到端项目按顺序亲手敲一遍每个环节都记录实验日志每篇文章都要写我当时卡在哪、为什么卡。走完这三步你对AI工程的理解就已经超过绝大多数只会调包的人了。之后的路径自然就清晰了想深入模型原理就啃论文加手写复现想做工程部署就去学Docker、推理优化和监控体系想做研究就补数学推导。但所有这些方向的前提都是你已经亲手把那条最基础的训练循环走通了——它不是别人塞给你的魔法而是你自己建起来的地基。最后再分享一个小经验我在带团队时要求新人入职的第一个月必须交一份从零实现的代码运行时把训练loss曲线画出来贴在工位上。原因很简单——失败过一次的人比背过一百个理论的人更知道问题出在哪里。希望你也能在这一篇的引导下把从零走成你的护城河而不是别人口中的口头禅。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进