2. 神经网络基础:感知机模型、激活函数、前向传播与反向传播

各位同学,咱们今天聊聊神经网络的基础。说实话,这部分内容我每年讲都会有些新感悟。你想想看,整个深度学习大厦,就是靠这几块砖头垒起来的。我当年刚入行时,总觉得这些基础太简单,结果在项目里栽了不少跟头。嗯,咱们还是老老实实把地基打牢。

2.1 感知机模型——神经元的鼻祖

感知机,说白了就是模仿人脑神经元的一个简化模型。它接收多个输入,每个输入有个权重,然后把这些加权求和,最后通过一个阈值判断是否激活。

数学上长这样:

y = sign(w₁x₁ + w₂x₂ + ... + wₙxₙ + b)

其中 sign 是符号函数,大于0输出1,小于0输出-1。

我在项目中遇到过这样一个场景:用感知机判断噪声是否超标。输入是分贝值、频率、持续时间三个特征,权重靠人工调。结果呢?调了一整天,准确率不到70%。后来我才明白——感知机只能处理线性可分问题。环境噪声数据哪有那么规整?

核心要点:感知机是线性分类器,只能画一条直线(或超平面)来分割数据。遇到异或问题直接歇菜。

避坑指南:我曾经在噪声源识别项目里硬用感知机,结果模型死活不收敛。后来换成多层网络,问题才解决。记住:单层感知机能力有限,别指望它干太复杂的活。

2.2 激活函数——给网络注入非线性

为什么需要激活函数?你想想看,如果每层都是线性变换,那堆叠再多层也等价于一层。激活函数就是用来打破这种线性关系的。

我常用的三种激活函数,咱们一个一个说。

2.2.1 Sigmoid 函数

公式:σ(x) = 1 / (1 + e⁻ˣ)

输出范围在(0,1)之间。早期神经网络很喜欢用它,因为它能把任意实数映射到概率区间。

但有个致命问题——梯度消失。当x很大或很小时,梯度几乎为0。我在做噪声等级分类时,网络层数一深,Sigmoid 直接让前面几层学不动了。

优点 缺点
输出平滑,适合概率输出 梯度消失严重
可导,便于反向传播 输出不是零中心,收敛慢
历史地位高,经典 计算指数,开销大

2.2.2 Tanh 函数

公式:tanh(x) = (eˣ - e⁻ˣ) / (eˣ + e⁻ˣ)

输出范围在(-1,1)之间。相比 Sigmoid,它是零中心的,收敛速度更快。

我个人习惯在循环神经网络里用 Tanh。记得有一次做噪声时序预测,用 Tanh 比 Sigmoid 快了将近30%的收敛速度。但梯度消失问题依然存在,只是稍微好一点。

2.2.3 ReLU 函数

公式:ReLU(x) = max(0, x)

这玩意儿现在是我的首选。为什么?简单、快、效果好。x大于0时梯度恒为1,梯度消失问题大大缓解。

但要注意——神经元死亡问题。如果某个神经元输出一直为负,那它的梯度永远是0,再也活不过来了。我建议学习率别设太大,可以缓解这个问题。

我的经验:在环境噪声预测这种回归任务里,ReLU 通常比 Sigmoid 和 Tanh 表现好。但如果你做的是分类任务,输出层还是用 Softmax 更合适。

2.3 前向传播——数据从输入到输出

前向传播,说白了就是数据在网络里走一遍。输入层接收数据,经过隐藏层的加权求和和激活函数,最后到输出层给出结果。

咱们用个简单的两层网络来演示:

# 伪代码示例
def forward_propagation(X, W1, b1, W2, b2):
    # 第一层:线性变换 + ReLU
    Z1 = np.dot(X, W1) + b1
    A1 = np.maximum(0, Z1)  # ReLU激活
    
    # 第二层:线性变换 + Sigmoid
    Z2 = np.dot(A1, W2) + b2
    A2 = 1 / (1 + np.exp(-Z2))  # Sigmoid激活
    
    return A2

你看,就这么简单。但实际项目中,我见过有人把前向传播写得特别复杂,各种循环嵌套。其实没必要,用矩阵运算一把梭就行。

下面这张图展示了前向传播的完整流程:

前向传播与反向传播流程图 输入层 x₁, x₂, ..., xₙ W₁·X + b₁ 隐藏层 ReLU / Tanh W₂·A₁ + b₂ 输出层 ŷ 损失函数 L(ŷ, y) 反向传播 梯度更新 W = W - α·∂L/∂W 链式法则求梯度 ∂L/∂W₁ → 前向传播 - - → 反向传播 数据流向:输入 → 隐藏 → 输出 → 损失

2.4 反向传播——让网络学会东西

前向传播算出了预测值,但和真实值有差距。怎么调整权重让差距变小?这就是反向传播干的事。

核心思想就四个字:链式法则。从输出层开始,逐层计算损失函数对权重的梯度,然后沿着梯度反方向更新权重。

数学推导我就不展开了,咱们直接看代码:

# 反向传播伪代码
def backward_propagation(X, y, A2, W2, A1):
    m = X.shape[0]  # 样本数
    
    # 输出层梯度
    dZ2 = A2 - y  # 损失对Z2的梯度
    dW2 = np.dot(A1.T, dZ2) / m
    db2 = np.sum(dZ2, axis=0, keepdims=True) / m
    
    # 隐藏层梯度(链式法则)
    dA1 = np.dot(dZ2, W2.T)
    dZ1 = dA1 * (A1 > 0)  # ReLU的导数
    dW1 = np.dot(X.T, dZ1) / m
    db1 = np.sum(dZ1, axis=0, keepdims=True) / m
    
    return dW1, db1, dW2, db2

关键理解:反向传播不是另一个算法,它只是用链式法则高效计算梯度的方法。没有它,深度学习根本跑不起来。

我在做噪声预测模型时,遇到过梯度爆炸的问题。损失直接变成NaN,模型崩了。后来加了梯度裁剪,才稳住。建议你在训练初期监控一下梯度范数,别等炸了再处理。

小技巧:如果你发现模型训练特别慢,可以检查一下梯度是否太小。我习惯在每轮迭代后打印梯度的均值和方差,这样能快速定位问题。

好了,这一章的内容就到这。感知机是起点,激活函数是灵魂,前向传播和反向传播是骨架。把这些搞明白,后面的卷积、循环网络都是锦上添花。

专注资料整理