news 2026/9/15 20:51:31

神经网络前向传播原理详解:从数学公式到代码实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
神经网络前向传播原理详解:从数学公式到代码实现

我一开始接触深度学习的时候,最困惑的问题就是:神经网络凭什么能“猜”出答案?它不像传统代码那样有明确的 if-else 规则,看上去就是一堆数字在瞎算。后来我才明白,神经网络所谓的“猜”,本质上就是一次一次地做数学运算,把输入的数据不断变形、提炼,最终映射到我们想要的结果上。这个从输入到输出的过程,就叫前向传播

这篇博文要讲的,就是前向传播这条主线。我会从神经网络的基本结构讲起,拆开每一个“神经元”内部到底做了什么,然后带你用实际的数字走一遍完整计算流程,最后再聊聊我在实际调试中踩过的坑。不管你是准备系统学习深度学习的初学者,还是已经在用框架、但对底层细节有点模糊的开发者,这篇内容都能帮你把“前向传播”这四个字真正吃透。

1. 神经网络到底是怎么“猜”的:整体思路拆解

1.1 从一个生活化的类比说起

先抛开各种专业名词,想象一个场景:你在水果摊买西瓜,摊主看一眼西瓜,就能说出“这个大概有五斤重,应该挺甜”。摊主凭什么能猜得这么准?是因为他见过成千上万个西瓜,大脑里已经形成了一套“看一眼外表特征,映射到重量和甜度”的规律。

神经网络做的事,本质上和摊主一模一样。你把西瓜的颜色深浅、纹理疏密、敲击声音这些特征作为输入,神经网络经过内部一套计算,输出一个“重量值”或者“甜度概率”。只不过摊主靠的是经验,神经网络靠的是数百万次的参数调整。而前向传播,就是“看一眼就给出答案”的那一瞬间的计算过程。

如果你非得给前向传播下个定义,那就是:数据从输入层进入,经过隐藏层的逐层计算,最后从输出层产生结果的过程。在这个过程中,网络的权重(weight)和偏置(bias)是固定的——也就是网络已经训练好了,它只是按部就班地做矩阵运算。真正让网络变聪明的“学习”发生在反向传播阶段,那个是下篇要聊的内容。

1.2 网络结构:神经元、层、权重和偏置

一个最简单的神经网络通常长这样:左边是输入层,中间是一个或多个隐藏层,右边是输出层。每一层里都有若干“神经元”,层与层之间通过带权重的连线相连。

用专业一点的话说,每个神经元做的事情就是两步:

  1. 把上一层所有神经元的输出值,分别乘以对应的权重,再求和,然后加上一个偏置。
  2. 把求和结果送入一个非线性函数(激活函数),得到这个神经元的最终输出。

为什么非要加非线性函数?这是整篇内容里我最想让你记住的一点。如果没有激活函数,不管网络堆多少层,最终都等价于一个线性变换。你可以把多层线性变换想象成把一张纸一直对折——无论如何对折,它还是一张平面,不可能变成有凹凸起伏的曲面。但真实世界里的数据分布几乎都是非线性的,所以没有激活函数,神经网络的“表达能力”就极其有限。

至于权重和偏置,它们就是网络“猜”的参数。权重决定了“某个输入特征对结果有多大影响”,偏置则相当于一个调节阈值,让神经元的输出可以整体偏移。刚开始这些参数是随机初始化的,所以网络猜得一团糟;经过训练不断调整后,它们会慢慢逼近一组好用的数值,这时前向传播的结果就越来越准了。

提示:理解前向传播时,千万别盯着单个神经元看太久。试着站在“层”的视角——每一层其实就是一个矩阵乘法加上一个激活函数。矩阵乘法负责“混合信息”,激活函数负责“引入非线性”。

2. 前向传播的数学原理:一个带数的完整计算示例

2.1 从单个神经元看起:线性加权求和

先别急着看整个网络。我们把目光聚焦到单个神经元上。

假设这个神经元接收两个输入,x₁ = 1、x₂ = 2,对应的权重是 w₁ = 0.3、w₂ = 0.5,偏置 b = 0.1。那么神经元的“净输入”(也叫加权和)就是:

z = w₁·x₁ + w₂·x₂ + b = 0.3×1 + 0.5×2 + 0.1 = 1.4

如果激活函数是 ReLU(Rectified Linear Unit,修正线性单元),规则是:输入大于 0 就原样输出,小于等于 0 就输出 0。因为 1.4 大于 0,所以这个神经元的最终输出 a = 1.4。

如果换成 Sigmoid 函数,规则是:输出 = 1 / (1 + e^(-z)),也就是把任意实数压缩到 0 和 1 之间。算一下 1 / (1 + e^(-1.4)) ≈ 0.802,输出就成了 0.802。

这个计算过程虽然简单,但它就是整个神经网络的核心零件。你把这个零件复制几千几万个,再按层次连接起来,就得到了深度学习里一个实际可用的网络。

2.2 完整的例子:2-3-1 网络的前向传播计算

现在我们把单个神经元扩展成一个完整的小网络。就用最常见的结构举例:输入层 2 个神经元,隐藏层 3 个神经元,输出层 1 个神经元。这个结构通常写作 2-3-1。

假设输入是 x₁ = 0.5,x₂ = 0.8。隐藏层的权重矩阵和偏置分别为:

隐藏层权重 W₁(形状 3×2):

x₁ (0.5)x₂ (0.8)
神经元 h₁0.20.1
神经元 h₂0.30.4
神经元 h₃0.50.2

隐藏层偏置 b₁ = [0.1, 0.2, 0.1]。

逐个计算隐藏层神经元的加权和:

  • h₁:z₁ = 0.2×0.5 + 0.1×0.8 + 0.1 = 0.28
  • h₂:z₂ = 0.3×0.5 + 0.4×0.8 + 0.2 = 0.67
  • h₃:z₃ = 0.5×0.5 + 0.2×0.8 + 0.1 = 0.51

假设激活函数都用 Sigmoid,那么隐藏层输出:

  • a₁ = 1 / (1 + e^(-0.28)) ≈ 0.570
  • a₂ = 1 / (1 + e^(-0.67)) ≈ 0.661
  • a₃ = 1 / (1 + e^(-0.51)) ≈ 0.625

接下来是输出层。输出层只有 1 个神经元,它接收隐藏层传来的 3 个值。假设输出层权重 W₂ = [0.4, 0.3, 0.2],偏置 b₂ = 0.1。

输出层的加权和:

z_out = 0.4×0.570 + 0.3×0.661 + 0.2×0.625 + 0.1 = 0.228 + 0.1983 + 0.125 + 0.1 = 0.6513

如果输出层也用 Sigmoid,最终输出 y_pred = 1 / (1 + e^(-0.6513)) ≈ 0.658。

整个过程走完,网络对这个输入“猜”的结果就是 0.658。如果你预期是 1,那这个预测还不够准;预期是 0,那也差了一点。距离有多大,就是下一步(反向传播)要解决的问题。

2.3 维度变化的核对:为什么矩阵形状这么重要

上面这个例子只有 2 个输入,人工笔算还撑得住。但真实场景里,输入往往成百上千维,比如一张 28×28 的灰度图就有 784 个输入。这时候矩阵运算的价值就体现出来了,而“维度匹配”是前向传播能不能跑通的第一道关卡。

我总结了一套在代码里核对维度的方法,特别好用。假设输入矩阵 X 的形状是 (m, n_in),其中 m 是样本数量,n_in 是每个样本的特征数。权重矩阵 W 的形状必须是 (n_in, n_out),其中 n_out 是这一层神经元的个数。偏置 b 的形状是 (1, n_out) 或 (n_out,),那么:

Z = X·W + b 的结果形状就是 (m, n_out)

每一层的输出维度,就是下一层的输入维度,一环扣一环。一旦中间某层的权重维度写错,前向传播立刻报错。与其背规则,不如记住一个核心逻辑:矩阵乘法要求左边矩阵的列数等于右边矩阵的行数,而权重矩阵的形状设计,就是为了让输入特征数和你指定的神经元个数正确对齐。

注意:权重矩阵的初始化也非常关键。如果初始权重全部为 0,那么同一层所有神经元的输出会一模一样,无论训练多久网络都学不出差异性。常见做法是随机小值初始化,比如 PyTorch 里的默认初始化、Xavier 初始化或 Kaiming 初始化,具体用哪种要看激活函数的类型。

3. 从零实现一个最小前向传播:代码实操

3.1 用 NumPy 手写一个 2-3-1 网络

为了让你彻底摆脱“只有理论没有手感”的状态,我们用纯 Python 加 NumPy 把刚才那个例子实现一遍。写代码的时候不借助任何深度学习框架,这样能看清每一步到底做了哪些运算。

先导入 NumPy,然后把输入、权重、偏置都定义出来:

import numpy as np # 定义输入:2个特征,1个样本 x = np.array([[0.5, 0.8]]) # 隐藏层权重 (2, 3):2个输入特征 -> 3个隐藏神经元 W1 = np.array([[0.2, 0.3, 0.5], [0.1, 0.4, 0.2]]) b1 = np.array([0.1, 0.2, 0.1]) # 输出层权重 (3, 1):3个隐藏神经元 -> 1个输出 W2 = np.array([[0.4], [0.3], [0.2]]) b2 = np.array([0.1]) # 定义 Sigmoid 激活函数 def sigmoid(z): return 1 / (1 + np.exp(-z)) # 隐藏层前向传播 z1 = np.dot(x, W1) + b1 a1 = sigmoid(z1) # 输出层前向传播 z2 = np.dot(a1, W2) + b2 a2 = sigmoid(z2) print("隐藏层加权和 z1:", z1) print("隐藏层输出 a1:", a1) print("输出层加权和 z2:", z2) print("最终预测 a2:", a2)

运行结果应该和你手算的值一致。隐藏层加权和是 [[0.28, 0.67, 0.51]],隐藏层输出是 [[0.5695, 0.6611, 0.6248]],输出层加权和是 [[0.6513]],最终预测是 [[0.6578]]。

这十几行代码,就是一个完整的全连接网络的前向传播。你甚至可以把它封装成一个函数,输入任意数据和参数,都能得到预测结果。能亲手写出并运行这段代码,前向传播的原理你就掌握了七成。

3.2 加入批量处理:多个样本同时前向传播

实际使用时,我们很少一次只算一个样本,而是一次喂一批样本(batch),这样可以利用 GPU 的并行计算能力加速。这就要说到矩阵运算比 for 循环舒服的地方了。

假设输入 X 的形状从 (1, 2) 变成 (3, 2),也就是 3 个样本、每个 2 个特征。权重矩阵不需要变,依然是 (2, 3) 和 (3, 1),因为矩阵乘法的规则会自动处理批量维度:

# 3个样本,每个样本2个特征 x_batch = np.array([[0.5, 0.8], [0.1, 0.2], [0.9, 0.3]]) z1 = np.dot(x_batch, W1) + b1 a1 = sigmoid(z1) z2 = np.dot(a1, W2) + b2 a2 = sigmoid(z2) print(a2.shape) # (3, 1),每个样本都有一个预测值

注意,偏置 b1 和 b2 在广播机制下会自动被加到每一行上。NumPy 会自动把形状为 (3,) 的偏置数组扩展开,匹配 (3, 3) 的中间结果,这就是所谓的 broadcasting。如果你使用了 PyTorch 或 TensorFlow,它们同样支持这种广播规则。

在写代码时,我强烈建议你在每一层后面打印一下输出张量的形状,保证每一步的维度都符合预期。很多维度错误都是静默发生的——不是报错,而是结果不对劲,这种问题排查起来比报错更头疼。

3.3 用 PyTorch 实现:看看框架帮我们做了什么

现在很多读者平时都用 PyTorch,那我顺手也写一个 PyTorch 版本。对比两个版本,你会更清楚框架到底在底下替你做了什么。

import torch import torch.nn as nn class SimpleNet(nn.Module): def __init__(self): super().__init__() # 输入2个特征,隐藏层3个神经元 self.fc1 = nn.Linear(2, 3) # 隐藏层3个神经元,输出1个值 self.fc2 = nn.Linear(3, 1) # 手动设置权重和偏置,和上面NumPy例子保持一致 with torch.no_grad(): self.fc1.weight.data = torch.tensor([[0.2, 0.1], [0.3, 0.4], [0.5, 0.2]], dtype=torch.float32) self.fc1.bias.data = torch.tensor([0.1, 0.2, 0.1], dtype=torch.float32) self.fc2.weight.data = torch.tensor([[0.4], [0.3], [0.2]], dtype=torch.float32) self.fc2.bias.data = torch.tensor([0.1], dtype=torch.float32) def forward(self, x): x = torch.sigmoid(self.fc1(x)) x = torch.sigmoid(self.fc2(x)) return x # 输入0.5和0.8 x = torch.tensor([[0.5, 0.8]], dtype=torch.float32) model = SimpleNet() print(model(x)) # tensor([[0.6578]], grad_fn=<SigmoidBackward0>)

你看看,PyTorch 的 nn.Linear 做的事情,和前面手写的 np.dot(x, W) + b 完全一致。它默认还会替你做权重初始化,并且自动记录运算图,为反向传播做准备。前向传播在 PyTorch 里就是 forward 方法里定义的运算流程,你先做什么后做什么,完全由 shape 决定。

实操心得:刚用框架时,最好先手动设置一次权重,跑通一个你心算过的例子,验证 forward 逻辑对不对,然后再放开让框架自动初始化。这样一旦有问题,你能快速知道是网络结构写错了,还是参数初始化的问题。

4. 实战场景:一次手写数字“猜”的全过程

4.1 输入、隐藏层与输出的设计逻辑

聊完理论和小例子,我们来点接近实际工程的场景:手写数字识别。这是深度学习的“Hello World”,特别适合用来理解前向传播的实战意义。

假设我们用 MNIST 数据集,每张图是 28×28 像素的灰度图。在输入网络之前,图片会被“拉平”成一个长度为 784 的一维向量,也就是每个像素的灰度值(0 到 255 之间,一般还会归一化到 0 到 1)作为输入特征。所以输入层的神经元数量是 784。

输出层怎么设计?因为要识别 0 到 9 共 10 个数字,所以输出层设 10 个神经元。每个神经元对应一个数字类别,输出值表示“这张图属于这个类别的概率”。常见的做法是最后一层用 Softmax 激活函数,把 10 个原始输出值变成一组加起来等于 1 的概率值。

中间隐藏层可以自己定。经典的做法是加一层或两层,比如 784 → 256 → 10,又或者 784 → 128 → 64 → 10。隐藏层的宽度和深度没有绝对标准,更多是靠经验加实验。但有一个非常直观的直觉:隐藏层越宽,网络记住细节的能力越强,但也越容易过拟合;隐藏层越深,网络越能提取抽象特征,但训练难度和计算成本也越高。

4.2 前向传播过程中数据经历了什么

我们跟着一张“7”的手写图片,走一遍整个前向传播,看看数据在每个阶段到底变成了什么形态。

第一步,图片转成向量。一张 28×28 的图像,变成形状为 (1, 784) 的矩阵,行代表一个样本,列代表 784 个特征。像素值除以 255,全部落到 0 到 1 之间。

第二步,输入层到隐藏层。权重矩阵形状是 (784, 256),偏置形状是 (256,)。矩阵乘法 (1, 784) × (784, 256),得到 (1, 256),这就是隐藏层 256 个神经元的加权和。然后过 ReLU 激活函数,小于 0 的全部置 0,大于 0 的保持不变。这一层的作用,是让网络学会识别一些低层特征,比如“边缘”、“角落”、“小线段”。

第三步,隐藏层到输出层。权重矩阵形状是 (256, 10),偏置形状是 (10,)。矩阵乘法 (1, 256) × (256, 10),得到 (1, 10)。接着过 Softmax,10 个原始数值被压缩成 10 个 0 到 1 之间的概率,所有值加起来正好等于 1。

第四步,解读结果。假设输出的概率分布是 0 号数字 0.02,7 号数字 0.91,8 号数字 0.03,其他都接近 0,那么这个网络“猜”这张图是数字 7,置信度约 91%。这就是前向传播的完整闭环。

4.3 为什么说前向传播是“推理”而非“学习”

很多人容易混淆一个概念:前向传播到底是推理还是学习?我的理解是,前向传播只是推理,也就是拿着当前的参数,对输入做一次预测。参数好,预测就准;参数差,预测就离谱。真正让参数变好的过程是反向传播和梯度下降,那是“学习”。

这也解释了为什么一个刚初始化的网络,前向传播的输出基本就是随机乱猜。比如上面 2-3-1 那个例子,如果你随机初始化权重,输出大概率不会接近你预期的目标值。没关系,这就是深度学习训练的正常起点。

我见过一些初学者在前向传播结果不好时,怀疑自己的网络结构写错了,其实大概率不是。结构写错通常表现为维度不匹配、报错崩溃;而结果不准,属于正常现象,需要通过训练去优化参数。分清这两件事,能省下不少排查问题的时间。

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

5.1 维度不匹配、输出全相同、结果全为NaN

我在带新手和在实际调试中,遇到过太多的前向传播问题。挑几个典型来说,建议你收藏一下,踩坑时对照着排查。

维度不匹配(shape mismatch)

这个问题最好解决,但报错信息往往让新手头大,比如 “mat1 and mat2 shapes cannot be multiplied (3x5 and 6x4)”。这时候不要慌,第一步看输入形状,第二步看权重形状,记住我前面说的规则:矩阵 A 的列数必须等于矩阵 B 的行数。既然是 (3, 5) 和 (6, 4) 相乘,那问题就出在 5 ≠ 6 上。这时候去检查上一层输出维度是不是 5,当前层权重第一维是不是 6,哪个不对改哪个。

输出层全是同一个值

如果你的网络前向传播输出每个样本的结果都一样,比如都是 0.5,那多半是权重初始化的问题。权重全部为 0,或者偏置设置不当,会导致同一层所有神经元计算出的结果完全相同。还有一种可能是输入数据本身没有归一化,数量级差异太夸张,导致网络对某些维度的变化不敏感。解决办法:重新初始化权重,推荐用 PyTorch 的默认初始化或 Xavier、Kaiming 初始化;同时把输入特征做归一化,让每个特征的数值范围保持在 0 到 1 或 -1 到 1 之间。

输出出现 NaN

这个我在训练深层网络时遇到过不止一次。前向传播出现 NaN,通常原因有两个:一是学习率太大导致数值溢出,虽然这在反向传播中更常见,但某些激活函数(如 Sigmoid)在输入非常大时会出现梯度饱和,进而影响前向输出;二是数据里有 NaN 或无穷值混入,比如原始数据没洗干净。排查方法也很直接:在每一层后面打印输出值,定位第一个出现 NaN 的层,然后从那一层往前反向找原因。

激活函数选择不当

很多人在隐藏层用了 Sigmoid 就万事大吉,结果发现网络训练不动。这不是前向传播的错,而是 Sigmoid 的输出不是零中心的,且在大输入时梯度几乎为 0,后续反向传播特别容易梯度消失。现在的实践里,隐藏层更多用 ReLU 或其变体(LeakyReLU、SiLU),只有在最后一层做二分类概率输出时才用 Sigmoid,做多分类时用 Softmax。

5.2 常见问题速查表

问题现象可能原因解决建议
矩阵乘法报维度错误层与层之间特征数不匹配打印每一层输出维度,逐层核对
所有输出都一样权重全零初始化或输入未归一化换用随机初始化,归一化输入
输出全是 NaN数据含脏值或梯度过大导致溢出清洗数据,调低学习率,加归一化层
隐藏层输出全为 0ReLU 死亡(输入全为负数)换 LeakyReLU,调整偏置或初始化方式
网络“猜”不准参数还没训练,前向传播本身不负责参数更新连接反向传播,开始训练

补充一条实操技巧:调试前向传播时,最好用固定随机种子固定参数,然后构造一个只有几个样本的极简输入,打印每一步的中间变量。等一切都符合预期了,再放开大规模数据。别一上来就跑完整数据集,否则出了问题你连是数据问题还是网络问题都分不清。

5.3 我实测过的三个排查方法

方法一:分步打印中间变量

别嫌麻烦,这是最有用的一招。我调试时不只打印最终输出,还会在每一层后面打印 Z 和 A 的形状、均值、标准差、最大最小值。如果某一层突然出现极大的值或者全部为 0,那一层就是问题所在。

方法二:用单个样本做“过拟合测试”

想确认前向传播和反向传播整个链路是否通畅,可以拿一个样本、让网络反复训练几十步,看 loss 能不能降到非常低。如果 loss 始终不降,说明网络本身有问题。虽然这招主要测整体链路,但前向传播的 bug 会导致这个测试直接失败,所以它能快速暴露出问题。

方法三:与手算结果对拍

就像我在第 3 章做的那样,构造一个小网络,固定所有权重和偏置,用手算一遍前向传播,再用代码跑一遍,对比结果是否一致。如果一致,说明代码逻辑正确。这个方法看着原始,但对初学者理解前向传播的价值是无可替代的。

6. 前向传播之外:下一步该往哪儿走

如果你把前面这些内容都消化了,你已经掌握了深度学习最基础但也最核心的一块拼图。接下来你自然会想:网络猜完后,怎么让它猜得更准?这就引出了损失函数、反向传播和梯度下降。损失函数负责量化“猜得有多差”,反向传播负责把误差从输出层往回传,梯度下降则根据梯度更新权重和偏置。三者结合,才组成了完整的训练闭环。

我个人觉得,学好前向传播的最佳路径,是在纸上手算一个 2-3-1 网络,然后用 NumPy 实现,再切换到 PyTorch 复刻同一个结构。完成这三步,你对“神经网络在做什么”的理解,会和只调框架 API 完全不同。

另外,我想多说一句。网上好多教程一上来就扯 CNN、RNN、Transformer,我觉得对初学者并不友好。这些结构的底层,都离不开“输入经过矩阵运算加激活函数得到输出”这个范式。CNN 里的卷积操作,本质上是滑动窗口内的加权求和;RNN 里是每个时间步做一次带隐藏状态的前向传播;Transformer 里的自注意力,也是一次复杂的矩阵变换。把基础的前向传播想明白了,后面学任何模型,你都是在往这个框架上添砖加瓦,而不是推倒重来。

所以,别急。先把这篇里的内容吃透,动手把示例代码跑几遍,亲眼看一看每一层的输出是什么样子。等到你对“数据从输入到输出经历了什么”有了肌肉记忆,下一篇文章,我们就可以放心大胆地聊反向传播了。

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

PET/CT图像融合全攻略:从配准算法到临床显示标准化流程

1. 项目概述&#xff1a;PET/CT图像融合到底在做什么先把我这几年的一个感受放在前面&#xff1a;PET/CT图像融合这件事&#xff0c;听起来像是“把两张图叠在一起”&#xff0c;但真正做过一轮的人都会明白&#xff0c;这个“叠”字背后是整整一套医学影像工程体系。你拿到的不…

作者头像 李华
网站建设 2026/9/15 20:50:54

主线程卡顿根因与解法:从16ms铁律到Web Workers实战

1. 为什么你的页面卡得像PPT&#xff1f;这不是加载慢&#xff0c;是主线程在“窒息”你有没有遇到过这种场景&#xff1a;页面明明资源都加载完了&#xff0c;点击按钮却要等半秒才响应&#xff1b;滚动列表时帧率掉到15fps&#xff0c;手指一划&#xff0c;画面像老式幻灯片一…

作者头像 李华
网站建设 2026/9/15 20:50:44

LISFLOOD_8在Windows 10上的避坑指南:环境配置、编译运行与报错排查

先说结论&#xff1a;我花了整整两天&#xff0c;才让LISFLOOD_8在Windows 10上安安稳稳地跑完一个案例。中间经历了编译器报错、安全中心乱杀exe、路径中文读不出来、参数文件编码乱掉、跑一半直接Segmentation fault这些破事。这篇文章把整个过程和排查思路整理出来&#xff…

作者头像 李华
网站建设 2026/9/15 20:50:15

空时自适应处理(STAP)MATLAB仿真:杂波数据生成与算法验证

简介&#xff1a;面向雷达信号处理学习者与工程技术人员&#xff0c;该压缩包提供空时自适应处理&#xff08;STAP&#xff09;的MATLAB实现&#xff0c;围绕杂波抑制与干扰消除场景&#xff0c;演示空间、时间联合滤波的核心流程&#xff0c;适合入门STAP原理并快速跑通基础实…

作者头像 李华
网站建设 2026/9/15 20:50:01

机器人导航local planner深度解析:DWA与TEB选型及调参实战

我这几年做机器人导航项目&#xff0c;从建图、定位到全局规划一路趟过来&#xff0c;说实话前面几步的成就感都来得比较“虚”&#xff1a;地图画出来了&#xff0c;路径规划出来了&#xff0c;看起来头头是道&#xff0c;可真让机器人跑起来才发现&#xff0c;真正决定它能不…

作者头像 李华