news 2026/10/2 7:22:12

从零搭建AI工程能力:手写自动求导与神经网络实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从零搭建AI工程能力:手写自动求导与神经网络实战

1. 从零搭建AI工程能力:为什么我劝你别一上来就调包

这两年AI应用开发的门槛肉眼可见地降低了,随便拉个框架、调个API就能跑出一个能对话的Demo。但我带过不少新人,也面试过不少号称“做过AI项目”的候选人,发现一个很普遍的问题:大家会用工具,但不知道工具背后发生了什么。模型输出不稳定、推理速度慢、显存爆了、部署上线后效果和本地测试对不上——这些问题一出来,很多人就懵了,因为他们从来没有从底层理解过AI工程到底在做什么。

“ai-engineering-from-scratch”这个方向,说白了就是不依赖高级封装,从最基础的数学原理和工程组件出发,亲手搭建一套可运行、可调试、可优化的AI工程链路。它解决的不是“怎么快速做个Demo”,而是“怎么真正理解并掌控AI系统的每一个环节”。适合谁看?如果你已经会用Python,了解基本的机器学习概念,但总觉得自己的AI能力浮在表面,想扎扎实实把地基打牢,那这篇内容就是写给你的。

我自己走过这条路,也踩过不少坑。下面我会从整体设计思路、核心细节、实操过程、常见问题四个维度,把从零搭建AI工程能力的完整路径拆开来讲,尽量做到你照着就能复现。

2. 整体设计与思路拆解

2.1 为什么不建议从框架开始学

现在主流的深度学习框架已经把很多底层细节封装得很好了,一行代码就能定义一个网络层,三行代码就能完成一次训练循环。这种便利性对于快速验证想法当然很好,但对于真正想理解AI工程的人来说,它隐藏了太多关键信息。

举个例子,你在框架里调用一个全连接层,传入了输入维度和输出维度,框架自动帮你初始化了权重矩阵。但你知道这个权重矩阵是怎么初始化的吗?为什么用Xavier初始化而不是高斯初始化?不同的初始化方式对梯度消失和梯度爆炸有什么影响?这些问题在框架的使用文档里通常不会详细讲,但它们在真实项目中直接决定了你的模型能不能训起来。

从零搭建的核心思路是:先理解每个组件的最小实现,再逐步引入工程优化。具体来说,我会把整个学习路径分成四个阶段:数学基础与张量操作、前向传播与反向传播的手动实现、训练循环的完整搭建、推理优化与部署。每个阶段都有明确的产出物,不是光看理论,而是要写出能跑的代码。

这个路径的优势在于,你对每一个环节都有掌控感。当模型效果不好的时候,你知道该从哪里入手排查,而不是盲目地调参或者换框架。劣势也很明显:前期投入的时间会比直接调包多得多。但根据我的经验,这个投入是值得的,因为后面你在做实际项目时,排查问题的速度会快很多。

2.2 技术选型的取舍逻辑

从零搭建不代表什么都要自己写。我的原则是:核心逻辑必须手写,辅助工具可以用现成的。具体来说,张量操作和自动求导的底层实现需要自己写一遍,但矩阵乘法这种基础运算可以直接用NumPy,没必要自己写CUDA核函数。数据加载和预处理可以用PyTorch的DataLoader,但数据增强的策略需要自己根据业务场景来设计。

编程语言方面,Python是首选,因为生态最完善,调试也方便。但如果你对性能有极致要求,关键的计算密集型部分可以用C++或者Rust重写,通过Python的C扩展接口调用。不过对于学习阶段来说,纯Python加上NumPy就够了,先把逻辑跑通,再考虑性能优化。

硬件方面,我建议至少有一块支持CUDA的GPU。虽然CPU也能跑通整个流程,但训练速度会慢到让你怀疑人生。如果没有GPU,可以用Google Colab或者Kaggle Notebooks的免费GPU资源,对于学习来说完全够用。显存方面,8GB起步,16GB会比较舒服,因为你可以尝试更大的batch size和更复杂的模型结构。

2.3 分阶段目标与产出物

我把整个学习路径拆成了四个阶段,每个阶段都有明确的产出物,方便你检验自己是否真的掌握了。

第一阶段是张量操作与自动求导。产出物是一个简单的自动求导引擎,支持标量和张量的加减乘除、矩阵乘法、ReLU、Sigmoid等基本操作,并且能够自动计算梯度。这个阶段的核心是理解计算图的概念,知道前向传播时如何构建图,反向传播时如何利用链式法则计算梯度。

第二阶段是手动实现前向传播和反向传播。产出物是一个两层神经网络,不依赖任何深度学习框架,纯用NumPy实现。你需要手动初始化权重、手动实现前向传播、手动推导反向传播的梯度公式,并用梯度下降更新参数。这个阶段会让你对神经网络的训练过程有非常直观的理解。

第三阶段是完整训练循环的搭建。产出物是一个可配置的训练框架,支持不同的优化器(SGD、Momentum、Adam)、不同的学习率调度策略、训练过程中的指标记录和可视化。这个阶段的核心是理解训练过程中的各种工程细节,比如梯度裁剪、权重衰减、早停策略等。

第四阶段是推理优化与部署。产出物是一个可以对外提供服务的推理接口,支持批量推理、动态batching、模型量化等优化手段。这个阶段的核心是理解从训练到部署的gap,知道如何在不损失太多精度的情况下提升推理速度。

3. 核心细节解析与实操要点

3.1 自动求导引擎的最小实现

自动求导是深度学习框架最核心的功能,理解它的实现原理对于排查梯度相关的问题至关重要。我从最基础的计算图开始讲。

计算图本质上是一个有向无环图,每个节点代表一个张量或者一个操作,边代表数据流动的方向。前向传播时,我们按照拓扑顺序依次计算每个节点的值;反向传播时,我们从损失函数出发,沿着图的反方向计算每个节点对损失的梯度。

实现一个最小化的自动求导引擎,关键是要定义一个Value类,它包含三个核心属性:data(当前值)、grad(梯度值)、_backward(反向传播函数)。每次进行运算时,我们不仅计算结果,还要记录这个结果是如何从输入计算得来的,也就是构建计算图。

class Value: def __init__(self, data, _children=(), _op=''): self.data = data self.grad = 0.0 self._backward = lambda: None self._prev = set(_children) self._op = _op def __add__(self, other): other = other if isinstance(other, Value) else Value(other) out = Value(self.data + other.data, (self, other), '+') def _backward(): self.grad += out.grad other.grad += out.grad out._backward = _backward return out def __mul__(self, other): other = other if isinstance(other, Value) else Value(other) out = Value(self.data * other.data, (self, other), '*') def _backward(): self.grad += other.data * out.grad other.grad += self.data * out.grad out._backward = _backward return out

上面这段代码展示了加法和乘法的前向计算和反向传播逻辑。加法操作的反向传播是将梯度原样传递给两个输入,乘法操作的反向传播是将梯度乘以另一个输入的值。这就是链式法则的具体体现。

注意:在实现反向传播时,梯度需要累加而不是覆盖,因为一个节点可能被多个下游节点使用。这就是为什么代码里用的是+=而不是=。

3.2 权重初始化与激活函数的选择

权重初始化看起来是个小问题,但它对训练的影响非常大。如果初始化不当,模型可能从一开始就陷入梯度消失或者梯度爆炸的困境。

最常见的初始化方法有几种。零初始化会导致所有神经元的输出相同,反向传播时梯度也相同,网络无法学习到不同的特征。随机初始化(比如高斯分布)可以打破对称性,但如果方差选择不当,深层网络的激活值会逐层衰减或者放大。Xavier初始化根据输入和输出的维度来调整方差,适合Sigmoid和Tanh激活函数。He初始化是Xavier的变体,适合ReLU及其变体。

具体来说,Xavier初始化的方差是2 / (fan_in + fan_out),He初始化的方差是2 / fan_in。这里的fan_in是输入维度,fan_out是输出维度。为什么He初始化要用2而不是1?因为ReLU会把负半轴的输出置零,相当于丢掉了一半的信息,所以需要更大的方差来补偿。

激活函数的选择同样关键。Sigmoid函数在输入很大或很小时梯度接近零,会导致梯度消失,现在很少用在隐藏层。Tanh函数虽然输出是零中心的,但同样存在梯度消失问题。ReLU函数计算简单,在正半轴梯度恒为1,有效缓解了梯度消失,但存在神经元死亡的问题。LeakyReLU和ELU是ReLU的改进版本,在负半轴给了一个小斜率,避免神经元完全死亡。

我在实际项目中的经验是:隐藏层默认用ReLU或者它的变体,输出层根据任务类型选择。二分类用Sigmoid,多分类用Softmax,回归任务直接线性输出。如果训练过程中发现很多神经元的输出一直是零,可以考虑换成LeakyReLU。

3.3 反向传播的梯度推导与实现

反向传播的核心是链式法则,但手动推导每个操作的梯度公式是很多人的痛点。我以两层神经网络为例,把完整的推导过程写出来。

假设网络结构是:输入层维度为D,隐藏层维度为H,输出层维度为C。前向传播的公式是:

z1 = x @ W1 + b1 a1 = ReLU(z1) z2 = a1 @ W2 + b2 loss = CrossEntropy(softmax(z2), y)

其中x是输入,W1和W2是权重矩阵,b1和b2是偏置,y是真实标签。

反向传播需要计算loss对W1、b1、W2、b2的梯度。我们从loss开始,逐步往前推导。

首先计算loss对z2的梯度。对于Softmax加交叉熵的组合,这个梯度有一个很简洁的形式:dz2 = softmax(z2) - y_onehot。这个结论可以直接用,不需要重新推导。

然后计算loss对W2和b2的梯度:dW2 = a1.T @ dz2,db2 = sum(dz2, axis=0)。这里的sum是对batch维度求和,因为b2对每个样本的贡献是相同的。

接着计算loss对a1的梯度:da1 = dz2 @ W2.T。然后通过ReLU的反向传播得到dz1:dz1 = da1 * (z1 > 0)。ReLU的导数在正半轴是1,负半轴是0,所以直接用z1是否大于零作为掩码。

最后计算loss对W1和b1的梯度:dW1 = x.T @ dz1,db1 = sum(dz1, axis=0)。

整个推导过程看起来步骤很多,但每一步都是链式法则的直接应用。我建议你至少手动推导一遍,然后在代码里实现出来,用数值梯度检验一下是否正确。数值梯度的计算方法是:对每个参数加上一个很小的epsilon,计算loss的变化,然后除以epsilon。如果解析梯度和数值梯度的差异在1e-6以内,说明推导是正确的。

3.4 优化器的演进与选择依据

梯度下降是最基础的优化算法,但它有几个明显的缺点:容易陷入局部最优、对学习率敏感、在鞍点附近震荡。为了解决这些问题,研究者提出了各种改进的优化器。

Momentum引入了动量的概念,模拟物理中的惯性,让参数更新方向不仅取决于当前梯度,还取决于之前的更新方向。这样可以加速收敛,减少震荡。具体实现是维护一个速度变量v,每次更新时v = beta * v + (1 - beta) * grad,然后用v来更新参数。

RMSProp和Adam则引入了自适应学习率的思想。RMSProp维护一个梯度平方的指数移动平均,用这个平均值来缩放学习率,使得每个参数的学习率可以根据其历史梯度自动调整。Adam结合了Momentum和RMSProp的优点,同时维护梯度的一阶矩和二阶矩估计,并进行了偏差校正。

在实际项目中,Adam通常是默认选择,因为它对学习率不敏感,收敛速度快,适合大多数场景。但Adam也有缺点,比如在某些任务上泛化能力不如SGD with Momentum。我的建议是:先用Adam快速验证模型是否能够学习,然后再尝试SGD with Momentum看能否获得更好的最终效果。

学习率的选择也很关键。太大会导致loss震荡甚至发散,太小会导致收敛速度极慢。常用的策略是先用一个较大的学习率(比如1e-3),然后根据训练过程中的loss变化动态调整。ReduceLROnPlateau是一种常用的调度策略,当验证集loss不再下降时,将学习率乘以一个衰减因子(比如0.1)。

4. 实操过程与核心环节实现

4.1 环境准备与依赖安装

开始动手之前,先把环境搭好。我推荐用conda来管理Python环境,因为可以方便地创建隔离的环境,避免不同项目之间的依赖冲突。

conda create -n ai-from-scratch python=3.10 conda activate ai-from-scratch pip install numpy matplotlib jupyter

NumPy是核心依赖,所有的张量操作都基于它。Matplotlib用于训练过程的可视化,Jupyter Notebook方便交互式调试。如果你有GPU,可以额外安装PyTorch的CUDA版本,但在这个阶段我们主要用NumPy,暂时不需要。

提示:不要一上来就装一堆框架,保持环境干净,减少干扰。等你把底层逻辑跑通了,再引入框架做对比实验。

4.2 手写两层神经网络的完整代码

下面是一个完整的两层神经网络实现,包括数据生成、前向传播、反向传播、参数更新和训练循环。代码可以直接运行,你会看到loss逐渐下降,准确率逐渐上升。

import numpy as np # 生成模拟数据:两类,每类500个样本 np.random.seed(42) N = 500 D = 2 X = np.random.randn(N, D) y = (X[:, 0] * X[:, 1] > 0).astype(int) # 初始化参数 H = 64 W1 = np.random.randn(D, H) * np.sqrt(2.0 / D) b1 = np.zeros(H) W2 = np.random.randn(H, 2) * np.sqrt(2.0 / H) b2 = np.zeros(2) # 超参数 lr = 0.01 epochs = 1000 for epoch in range(epochs): # 前向传播 z1 = X @ W1 + b1 a1 = np.maximum(0, z1) # ReLU z2 = a1 @ W2 + b2 # Softmax exp_z2 = np.exp(z2 - np.max(z2, axis=1, keepdims=True)) probs = exp_z2 / np.sum(exp_z2, axis=1, keepdims=True) # 交叉熵损失 log_probs = -np.log(probs[np.arange(N), y]) loss = np.mean(log_probs) # 反向传播 dz2 = probs.copy() dz2[np.arange(N), y] -= 1 dz2 /= N dW2 = a1.T @ dz2 db2 = np.sum(dz2, axis=0) da1 = dz2 @ W2.T dz1 = da1 * (z1 > 0) dW1 = X.T @ dz1 db1 = np.sum(dz1, axis=0) # 参数更新 W1 -= lr * dW1 b1 -= lr * db1 W2 -= lr * dW2 b2 -= lr * db2 if epoch % 100 == 0: preds = np.argmax(probs, axis=1) acc = np.mean(preds == y) print(f"Epoch {epoch}, Loss: {loss:.4f}, Acc: {acc:.4f}")

这段代码虽然不长,但包含了神经网络训练的所有核心要素。你可以尝试修改隐藏层维度、学习率、激活函数,观察对训练效果的影响。比如把ReLU换成Sigmoid,你会发现收敛速度明显变慢,这就是梯度消失的直观体现。

4.3 训练过程的可视化与监控

光看loss数值不够直观,把训练过程画出来能帮你更快地发现问题。我通常会画三张图:loss曲线、准确率曲线、以及梯度的范数变化。

import matplotlib.pyplot as plt # 在训练循环中记录 losses = [] accs = [] grad_norms = [] # ... 训练循环内部 ... losses.append(loss) accs.append(acc) grad_norms.append(np.linalg.norm(dW1) + np.linalg.norm(dW2)) # 训练结束后绘图 fig, axes = plt.subplots(1, 3, figsize=(15, 4)) axes[0].plot(losses) axes[0].set_title('Loss') axes[1].plot(accs) axes[1].set_title('Accuracy') axes[2].plot(grad_norms) axes[2].set_title('Gradient Norm') plt.show()

loss曲线如果震荡很厉害,说明学习率可能太大了。如果loss下降很慢,说明学习率太小或者初始化有问题。如果梯度范数逐渐趋近于零,说明可能出现了梯度消失,需要检查激活函数和初始化方式。如果梯度范数突然变得很大,说明可能出现了梯度爆炸,需要考虑梯度裁剪。

4.4 从手动实现到框架对比

当你把手动实现跑通之后,可以再用PyTorch实现同样的网络结构,对比两者的结果。这样做的好处是,你能清楚地知道框架帮你做了什么,以及框架的默认行为是否符合你的预期。

import torch import torch.nn as nn model = nn.Sequential( nn.Linear(2, 64), nn.ReLU(), nn.Linear(64, 2) ) criterion = nn.CrossEntropyLoss() optimizer = torch.optim.SGD(model.parameters(), lr=0.01) X_tensor = torch.tensor(X, dtype=torch.float32) y_tensor = torch.tensor(y, dtype=torch.long) for epoch in range(1000): optimizer.zero_grad() output = model(X_tensor) loss = criterion(output, y_tensor) loss.backward() optimizer.step()

对比两段代码,你会发现PyTorch把梯度计算、参数更新、设备管理等细节都封装起来了。这当然提高了效率,但也意味着你对底层发生的事情失去了直接控制。我的建议是:学习阶段用手动实现,生产阶段用框架。手动实现帮你建立直觉,框架帮你提高效率。

5. 常见问题与排查技巧实录

5.1 梯度消失与梯度爆炸的排查

梯度消失和梯度爆炸是训练深度网络时最常见的问题。梯度消失的表现是:靠近输入层的参数几乎不更新,loss下降非常缓慢。梯度爆炸的表现是:loss突然变成NaN,或者参数值变得极大。

排查梯度消失,首先检查激活函数。如果隐藏层用的是Sigmoid或Tanh,换成ReLU通常能缓解。其次检查权重初始化,确保使用了Xavier或He初始化。还可以考虑引入Batch Normalization,它通过规范化每层的输入分布,有效缓解了梯度消失问题。

排查梯度爆炸,最直接的方法是梯度裁剪。具体做法是:计算所有参数的梯度范数,如果超过某个阈值(比如1.0),就将梯度按比例缩放。PyTorch提供了torch.nn.utils.clip_grad_norm_函数,一行代码就能搞定。

torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)

注意:梯度裁剪的阈值需要根据具体任务调整。太小会限制模型的表达能力,太大则起不到防止爆炸的作用。我通常从1.0开始尝试,根据训练情况微调。

5.2 过拟合与欠拟合的判断与处理

过拟合的表现是:训练集loss持续下降,但验证集loss先下降后上升,两者之间的gap越来越大。欠拟合的表现是:训练集loss和验证集loss都很高,且下降缓慢。

处理过拟合,常用的手段有:增加数据量、数据增强、Dropout、权重衰减(L2正则化)、早停。Dropout的原理是在训练时随机将一部分神经元的输出置零,迫使网络学习更鲁棒的特征。权重衰减是在loss中加入参数平方和的惩罚项,限制参数的大小。早停是在验证集loss不再下降时停止训练,防止模型在训练集上过度拟合。

处理欠拟合,需要增加模型的容量。可以增加隐藏层的维度、增加层数、或者使用更复杂的网络结构。也可以检查数据预处理是否有问题,比如特征是否归一化、标签是否正确。

我在实际项目中的经验是:先确保模型能够过拟合一个小数据集。如果连训练集都拟合不了,说明模型容量不够或者训练过程有问题。等模型能在小数据集上过拟合了,再引入正则化手段来提升泛化能力。

5.3 学习率设置的常见误区

学习率是训练过程中最重要的超参数之一,但很多人对它的设置存在误区。

第一个误区是认为学习率越小越好。学习率太小会导致收敛速度极慢,训练时间大幅增加。而且太小的学习率可能让模型陷入局部最优或者鞍点,无法跳出。

第二个误区是全程使用固定的学习率。实际上,训练初期用较大的学习率可以快速下降,训练后期用较小的学习率可以精细调整。学习率预热(warmup)和余弦退火(cosine annealing)是两种常用的调度策略。

第三个误区是不同参数使用相同的学习率。对于Embedding层和输出层,通常需要不同的学习率。Embedding层的学习率可以大一些,输出层的学习率可以小一些。

我通常的做法是:先用一个较大的学习率(比如1e-2)跑几百步,观察loss的变化。如果loss震荡,就减小学习率;如果loss下降太慢,就增大学习率。找到一个使loss稳定下降的学习率后,再引入学习率调度策略。

5.4 常见问题速查表

问题现象可能原因排查方法解决方案
loss变成NaN学习率太大、梯度爆炸检查梯度范数减小学习率、梯度裁剪
loss不下降学习率太小、初始化不当检查参数更新量增大学习率、换初始化方法
训练集loss低但验证集loss高过拟合对比训练集和验证集指标增加正则化、数据增强、早停
梯度范数趋近于零梯度消失检查激活函数和初始化换ReLU、用He初始化、加BN
参数更新量极小学习率太小或梯度消失打印参数更新前后的差值调整学习率、检查梯度
训练速度慢batch size太小、模型太大检查GPU利用率增大batch size、简化模型

6. 从训练到推理:工程化的关键一步

6.1 模型保存与加载的正确姿势

训练完模型只是第一步,如何正确地保存和加载模型同样重要。很多人习惯直接保存整个模型对象,但这种方式有几个问题:依赖具体的代码结构、版本兼容性差、安全性低。

推荐的做法是只保存模型的参数(state_dict),加载时先实例化模型结构,再加载参数。这样代码和参数分离,便于版本管理和迁移。

# 保存 torch.save(model.state_dict(), 'model_weights.pth') # 加载 model = MyModel() model.load_state_dict(torch.load('model_weights.pth')) model.eval()

注意:加载模型后一定要调用model.eval(),这会将Dropout和BatchNorm切换到推理模式。忘记这一步是新手常犯的错误,会导致推理结果和训练时不一致。

6.2 推理性能优化的几个实用手段

推理性能和训练性能的关注点不同。训练时关注吞吐量(每秒处理多少样本),推理时关注延迟(单个请求的响应时间)。优化推理性能的手段主要有以下几种。

模型量化是将浮点参数转换为低精度表示(比如int8),可以显著减少模型大小和推理时间。量化分为训练后量化和量化感知训练两种。训练后量化简单快捷,但可能损失一些精度;量化感知训练在训练过程中模拟量化误差,精度损失更小。

算子融合是将多个连续的操作合并成一个,减少内存访问和内核启动开销。比如将卷积、BatchNorm、ReLU融合成一个操作。大多数推理框架都支持自动算子融合。

动态batching是将多个推理请求合并成一个batch处理,提高GPU利用率。但会增加单个请求的延迟,需要根据业务场景权衡。

我在实际项目中的经验是:先做模型量化,再做算子融合,最后考虑动态batching。量化通常能带来2到4倍的速度提升,而且实现成本最低。

6.3 部署上线的注意事项

模型部署上线时,有几个容易被忽视的问题。

第一个是输入数据的预处理。训练时的预处理逻辑必须和推理时完全一致,否则会导致效果下降。建议把预处理逻辑封装成独立的模块,训练和推理共用同一份代码。

第二个是版本管理。模型文件、预处理代码、后处理代码需要一起版本化,确保任何时候都能复现某个版本的推理结果。

第三个是监控。上线后需要监控推理延迟、吞吐量、错误率等指标,以及模型输出的分布变化。如果发现输出分布发生显著偏移,可能意味着数据分布发生了变化,需要重新训练模型。

第四个是回滚机制。新模型上线后如果效果不及预期,需要能够快速回滚到旧版本。建议采用灰度发布的方式,先让小部分流量走新模型,观察一段时间后再全量切换。

7. 我在这条路上踩过的几个坑

第一个坑是过早引入框架。我一开始学的时候,直接上手PyTorch,跟着教程跑通了几个Demo,觉得自己会了。但后来遇到一个梯度不更新的问题,完全不知道从哪里排查,因为框架把梯度计算都封装了。后来我花了两周时间手动实现了一遍反向传播,才真正理解了计算图和链式法则,再回头看框架的代码就清晰多了。

第二个坑是忽视数值稳定性。在实现Softmax的时候,我一开始直接算exp(z),结果当z稍微大一点就溢出了,loss变成NaN。后来才知道要先减去最大值,即exp(z - max(z)),这样既不会溢出,数学上也是等价的。类似的技巧还有log-sum-exp、Sigmoid的数值稳定实现等,这些都是工程实践中必须掌握的。

第三个坑是不重视实验记录。刚开始做实验的时候,我改了学习率、改了网络结构,但没有系统地记录每次实验的配置和结果。后来想复现某个效果好的配置时,完全想不起来当时改了什么。从那以后,我养成了用表格记录每次实验的习惯,包括超参数、训练曲线、最终指标,这个习惯帮我节省了大量时间。

第四个坑是忽略数据质量。我曾经在一个项目上花了很多时间调模型结构,但效果一直上不去。后来发现是数据标注有问题,有大约10%的样本标签是错的。清理数据后,用同样的模型结构,效果直接提升了一大截。这件事让我深刻认识到:数据和特征决定了模型效果的上限,模型和算法只是在逼近这个上限。

8. 后续可以继续深入的方向

把从零搭建的基础打牢之后,你可以往几个方向继续深入。

一个是分布式训练。当模型和数据规模变大时,单卡训练不够用了,需要掌握数据并行、模型并行、流水线并行等技术。这部分涉及通信原语、梯度同步、负载均衡等工程细节,是进阶的必经之路。

另一个是模型压缩与加速。除了量化,还有剪枝、知识蒸馏、低秩分解等手段。这些技术可以在保持精度的前提下大幅减少模型的计算量和存储需求,对于端侧部署尤其重要。

还有一个是自动化机器学习。包括超参数搜索、神经网络架构搜索、自动特征工程等。这些技术可以减少人工调参的工作量,但需要理解搜索空间的设计和评估策略。

不管往哪个方向深入,底层的基本功都是相通的。你对张量操作、梯度计算、优化算法的理解越深,学习新技术时就越快。这也是我为什么一直强调“from scratch”的价值——它给你的不是某个具体的技能,而是一种理解问题的框架和排查问题的能力。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/2 7:18:55

2026年无损换窗服务商排名前五,资质齐全省心之选

选无损换窗别踩坑!先看清这4个最常见的行业陷阱 很多业主在准备做无损换窗时,心里都藏着不少顾虑。先是怕花了钱买不到好材料,商家拿薄型材、劣质玻璃糊弄人;接着担心施工不专业,拆旧窗的时候破坏墙面、地板,后期还要额外花功夫补…

作者头像 李华
网站建设 2026/10/2 7:18:40

当深度学习第一次打败了人类设计的特征:双流网络的故事

2014 年的计算机视觉圈子里,有一件事让很多人心里不太舒服。卷积神经网络在图像识别上已经把传统方法打得溃不成军,AlexNet 横空出世才两年,图像分类的准确率被一次次刷新。可是一旦把静止的图片换成动态的视频,风向完全变了。在动…

作者头像 李华
网站建设 2026/10/2 7:18:38

ESP32+MicroPython+天问ASR-PRO离线语音播报实战指南

做物联网项目,最烦的就是“设备有数据,人却看不见”。我自己的环境监测盒子跑了很久,每次想看温度还得掏手机、开App,体验很割裂。后来我给它加了语音播报:ESP32做主控,MicroPython写业务逻辑,天…

作者头像 李华
网站建设 2026/10/2 7:17:15

排序与排列:算法竞赛选手的核心基本功与实战技巧

1. 排序与排列:竞赛选手绕不开的核心基本功我接触算法竞赛这么多年,最深的一个体会就是:排序不是“会写”就行,而是要在任何场景下都“信手拈来”。无论你是刚接触蓝桥杯、ICPC、Codeforces,还是在应付各类机试和笔试&…

作者头像 李华