神经网络入门到实战:从M-P神经元到深度学习的进化之路

从手机的人脸识别解锁,到AlphaGo击败世界围棋冠军,再到ChatGPT的流畅对话,这些黑科技背后都站着同一个“大佬”——神经网络。它模仿人脑神经元的连接方式,让机器拥有了“学习”和“思考”的能力。本文将带你从零拆解神经网络的核心原理,从最基础的神经元模型,到训练多层网络的BP算法,再到如今大火的深度学习,全程穿插通俗案例和可运行代码,让你彻底搞懂这个AI时代的核心技术。

一、一切的起点:M-P神经元模型

人脑有大约860亿个神经元,它们通过突触相互连接,电信号在神经元之间传递,最终形成了我们的思维和意识。人工神经网络的第一步,就是用数学模型模拟单个神经元的工作方式,这就是M-P神经元模型,由麦卡洛克(McCulloch)和皮茨(Pitts)在1943年提出,是所有神经网络的“积木”。

1.1 神经元的数学表达

M-P神经元接收来自其他n个神经元的输入信号,将这些信号按权重加权求和,再减去一个阈值,最后通过激活函数输出结果,公式如下:
y=f(∑i=1nwixi−θ)y = f\left( \sum_{i=1}^{n} w_i x_i - \theta \right)y=f(i=1nwixiθ)

  • yyy:当前神经元的输出值,范围由激活函数决定
  • f(⋅)f(\cdot)f()激活函数,相当于神经元的“开关”,决定是否被激活
  • wiw_iwi:第iii个输入信号的权重,代表这个输入对当前神经元的重要程度,权重越大,这个输入的影响越大
  • xix_ixi:第iii个输入信号,来自其他神经元的输出
  • θ\thetaθ:神经元的阈值,只有当加权求和的结果超过这个阈值时,神经元才会被激活

1.2 通俗理解:要不要出门的决策

我们可以把M-P神经元比作一个“出门决策器”:

  • 输入x1x_1x1=天气(晴天=1,下雨=0),权重w1w_1w1=5(你很看重天气)
  • 输入x2x_2x2=朋友邀约(约=1,不约=0),权重w2w_2w2=3(朋友约你会加分)
  • 输入x3x_3x3=有没有作业(有=1,没有=0),权重w3w_3w3=-10(有作业绝对不想出门)
  • 阈值θ\thetaθ=0(加权和大于0就出门)

如果今天下雨、朋友约你、没有作业,那么加权和为0×5+1×3+0×(−10)−0=3>00×5 + 1×3 + 0×(-10) - 0 = 3 > 00×5+1×3+0×(10)0=3>0,神经元输出1,决定出门;如果有作业,加权和为−10<0-10 < 010<0,输出0,宅家。

1.3 常用激活函数

激活函数的作用是给神经元引入非线性,没有它,多层神经网络就会退化成线性模型,只能解决简单问题。最经典的两种激活函数如下:

(1)阶跃函数

f(x)={1,x≥00,x<0f(x) = \begin{cases} 1, & x \geq 0 \\ 0, & x < 0 \end{cases}f(x)={1,0,x0x<0
它是最理想的“开关”,输出要么0要么1,但缺点是不连续、不可导,没法用梯度下降法训练网络,只能用于最简单的感知机。

(2)Sigmoid函数

f(x)=11+e−xf(x) = \frac{1}{1+e^{-x}}f(x)=1+ex1
它把任意实数输入压缩到(0,1)(0,1)(0,1)区间,是一个平滑的S型曲线,连续可导,是早期神经网络最常用的激活函数。它的导数可以用自身表示:f′(x)=f(x)(1−f(x))f'(x) = f(x)(1-f(x))f(x)=f(x)(1f(x)),这大大简化了后续的梯度计算。

在这里插入图片描述

图5.1 M-P神经元模型 图中清晰展示了M-P神经元的工作流程:多个输入信号加权求和后,减去阈值,再通过激活函数得到最终输出。

二、感知机:第一个能学习的神经网络

有了单个神经元,我们就可以搭建最简单的神经网络——感知机(Perceptron),由罗森布拉特(Rosenblatt)在1957年提出,是第一个具有学习能力的人工神经网络。

2.1 感知机的结构

感知机只有两层:输入层输出层。输入层负责接收外界信号,不做任何计算;输出层是一个或多个M-P神经元,负责计算输出。感知机是前馈网络的一种,信号只能从输入层流向输出层,没有反向连接。

2.2 感知机的学习规则

感知机的学习过程就是不断调整权重和阈值,让输出尽可能接近真实标签。学习规则如下:
wi←wi+Δwiw_i \leftarrow w_i + \Delta w_iwiwi+Δwi
Δwi=η(y−y^)xi\Delta w_i = \eta (y - \hat{y}) x_iΔwi=η(yy^)xi

  • η\etaη学习率,取值范围(0,1)(0,1)(0,1),控制每次权重调整的幅度。学习率太大,参数会震荡不收敛;太小,学习速度太慢
  • yyy:样本的真实标签
  • y^\hat{y}y^:感知机的预测输出

通俗来说:如果预测对了(y=y^y=\hat{y}y=y^),权重不变;如果预测错了,就根据错误的大小调整权重,错得越多,调整幅度越大。

2.3 感知机的能力与局限

感知机可以完美解决线性可分问题,比如与、或、非三种逻辑运算。表5.1展示了感知机实现这三种运算的参数:

运算 w1w_1w1 w2w_2w2 θ\thetaθ 公式
1 1 1.5 y=f(x1+x2−1.5)y=f(x_1+x_2-1.5)y=f(x1+x21.5)
1 1 0.5 y=f(x1+x2−0.5)y=f(x_1+x_2-0.5)y=f(x1+x20.5)
-1 - -0.5 y=f(−x1+0.5)y=f(-x_1+0.5)y=f(x1+0.5)

表5.1 感知机实现与、或、非运算的参数(周志华《机器学习》p99)

以“与运算”为例,只有当x1=1x_1=1x1=1x2=1x_2=1x2=1时,加权和为1+1−1.5=0.5>01+1-1.5=0.5>01+11.5=0.5>0,输出1;其他情况加权和都小于0,输出0,完全符合与运算的逻辑。

但感知机有一个致命缺陷:无法解决线性不可分问题,最经典的就是异或问题(两个输入不同时输出1,相同时输出0)。异或的两类样本点分布在正方形的对角线上,无论怎么画直线,都无法把它们分开,就像你没法用一条直线把“黑白相间的棋盘格”分成两类。这一缺陷直接导致了第一次人工智能寒冬的到来。

2.4 解决方案:多层神经网络

既然单层感知机不行,那就加一层!在输入层和输出层之间加入隐藏层,就形成了多层前馈神经网络。隐藏层的神经元可以提取更复杂的特征,从而解决线性不可分问题。比如两层感知机(一个隐藏层)就可以完美解决异或问题。

在这里插入图片描述

图5.2 多层前馈神经网络结构 图中是一个典型的三层前馈网络:输入层有3个神经元,隐藏层有4个神经元,输出层有2个神经元。层与层之间全连接(每个神经元都和下一层所有神经元相连),层内无连接,信号单向流动。

三、BP算法:训练多层网络的核心武器

多层神经网络虽然能解决复杂问题,但怎么训练它呢?隐藏层的误差没法直接观测,也就没法像感知机那样直接调整权重。直到1986年,误差逆传播(Back Propagation,简称BP)算法被提出,才彻底解决了多层神经网络的训练问题,让神经网络迎来了第二次复兴。

3.1 BP算法的核心思想

BP算法分为两个阶段:

  1. 前向传播:输入信号从输入层经过隐藏层,最终传到输出层,计算出预测值和误差
  2. 反向传播:把输出层的误差从后往前逐层传递,计算每一层神经元的梯度,然后用梯度下降法更新所有的权重和阈值

通俗来说,这就像你考试考砸了:先看最后一道题错了多少(输出误差),然后倒推这道题是哪个知识点没掌握(隐藏层误差),再倒推这个知识点是上课没听懂还是练习不够(输入层权重),最后针对性地调整学习方法,下次就能考得更好。

3.2 BP算法的数学推导

我们以三层前馈网络(输入层ddd个神经元,隐藏层qqq个神经元,输出层lll个神经元)为例,推导BP算法的核心公式。

在这里插入图片描述

(1)前向传播计算
  • 隐藏层第hhh个神经元的输入:αh=∑i=1dvihxi\alpha_h = \sum_{i=1}^{d} v_{ih} x_iαh=i=1dvihxi,其中vihv_{ih}vih是输入层第iii个神经元到隐藏层第hhh个神经元的权重
  • 隐藏层第hhh个神经元的输出:bh=f(αh−γh)b_h = f(\alpha_h - \gamma_h)bh=f(αhγh),其中γh\gamma_hγh是隐藏层第hhh个神经元的阈值,fff是Sigmoid激活函数
  • 输出层第jjj个神经元的输入:βj=∑h=1qwhjbh\beta_j = \sum_{h=1}^{q} w_{hj} b_hβj=h=1qwhjbh,其中whjw_{hj}whj是隐藏层第hhh个神经元到输出层第jjj个神经元的权重
  • 输出层第jjj个神经元的输出:y^j=f(βj−θj)\hat{y}_j = f(\beta_j - \theta_j)y^j=f(βjθj),其中θj\theta_jθj是输出层第jjj个神经元的阈值
(2)反向传播计算梯度

我们使用均方误差作为损失函数,对于单个样本(x,y)(x,y)(x,y),损失为:
E=12∑j=1l(y^j−yj)2E = \frac{1}{2} \sum_{j=1}^{l} (\hat{y}_j - y_j)^2E=21j=1l(y^jyj)2

根据链式法则,我们可以从输出层开始,逐层计算梯度:

  1. 输出层梯度项:衡量输出层每个神经元对误差的贡献
    gj=y^j(1−y^j)(yj−y^j)g_j = \hat{y}_j (1 - \hat{y}_j) (y_j - \hat{y}_j)gj=y^j(1y^j)(yjy^j)
  2. 隐藏层梯度项:衡量隐藏层每个神经元对输出层误差的贡献
    eh=bh(1−bh)∑j=1lwhjgje_h = b_h (1 - b_h) \sum_{j=1}^{l} w_{hj} g_jeh=bh(1bh)j=1lwhjgj
(3)更新参数

根据梯度下降法,参数的更新方向是损失函数的负梯度方向:

  • 隐藏层到输出层的权重更新:Δwhj=ηgjbh\Delta w_{hj} = \eta g_j b_hΔwhj=ηgjbh
  • 输出层阈值更新:Δθj=−ηgj\Delta \theta_j = -\eta g_jΔθj=ηgj
  • 输入层到隐藏层的权重更新:Δvih=ηehxi\Delta v_{ih} = \eta e_h x_iΔvih=ηehxi
  • 隐藏层阈值更新:Δγh=−ηeh\Delta \gamma_h = -\eta e_hΔγh=ηeh

3.3 标准BP vs 累积BP

BP算法有两种常用的实现方式:

  • 标准BP:每输入一个样本,就计算一次误差并更新一次参数。优点是更新速度快,能跳出局部极小;缺点是参数更新频繁,误差震荡大
  • 累积BP:遍历所有训练样本后,计算总误差再更新一次参数。优点是误差下降平稳;缺点是更新速度慢,当训练集很大时效率低

3.4 BP的过拟合问题与解决方法

BP神经网络的表达能力极强,很容易出现过拟合:在训练集上表现很好,但在测试集上表现很差。解决过拟合主要有两种方法:

  1. 早停:将数据集分成训练集和验证集,训练过程中不断计算验证集误差,当验证集误差开始上升时,立即停止训练,避免模型过度拟合训练集
  2. 正则化:在损失函数中加入权重的平方和项,惩罚过大的权重,让模型更简单:
    E=12∑j=1l(y^j−yj)2+λ∑iwi2E = \frac{1}{2} \sum_{j=1}^{l} (\hat{y}_j - y_j)^2 + \lambda \sum_{i} w_i^2E=21j=1l(y^jyj)2+λiwi2
    其中λ\lambdaλ是正则化系数,控制惩罚的强度。

在这里插入图片描述

图5.3 BP算法迭代过程 图中蓝色曲线是训练集误差,红色曲线是验证集误差。可以看到,随着迭代次数增加,训练集误差持续下降,但验证集误差在第10轮左右开始上升,此时就应该早停,避免过拟合。

3.5 核心代码:用BP解决异或问题

下面我们用Python实现一个简单的三层BP神经网络,解决感知机搞不定的异或问题:

import numpy as np

# 激活函数Sigmoid及其导数
def sigmoid(x):
    return 1 / (1 + np.exp(-x))

def sigmoid_deriv(x):
    return x * (1 - x)

# 数据集:异或问题
X = np.array([[0,0], [0,1], [1,0], [1,1]])
y = np.array([[0], [1], [1], [0]])

# 初始化参数
np.random.seed(1)
# 输入层(2) -> 隐藏层(4) 权重和阈值
w1 = 2 * np.random.random((2,4)) - 1  # 权重范围[-1,1]
gamma = np.zeros((1,4))  # 隐藏层阈值
# 隐藏层(4) -> 输出层(1) 权重和阈值
w2 = 2 * np.random.random((4,1)) - 1
theta = np.zeros((1,1))  # 输出层阈值

# 学习率
eta = 0.1
# 训练轮数
epochs = 100000

# 训练过程
for epoch in range(epochs):
    # 前向传播
    hidden_input = np.dot(X, w1) - gamma  # 隐藏层输入
    hidden_output = sigmoid(hidden_input)  # 隐藏层输出
    final_input = np.dot(hidden_output, w2) - theta  # 输出层输入
    final_output = sigmoid(final_input)  # 输出层输出
    
    # 计算误差
    error = y - final_output
    if epoch % 10000 == 0:
        print(f"Epoch {epoch}, Error: {np.mean(np.abs(error))}")
    
    # 反向传播
    # 输出层梯度
    output_delta = error * sigmoid_deriv(final_output)
    # 隐藏层梯度
    hidden_error = output_delta.dot(w2.T)
    hidden_delta = hidden_error * sigmoid_deriv(hidden_output)
    
    # 更新参数
    w2 += eta * hidden_output.T.dot(output_delta)
    theta -= eta * np.sum(output_delta, axis=0, keepdims=True)
    w1 += eta * X.T.dot(hidden_delta)
    gamma -= eta * np.sum(hidden_delta, axis=0, keepdims=True)

# 测试
print("\n测试结果:")
for i in range(4):
    print(f"输入:{X[i]}, 预测输出:{final_output[i][0]:.4f}, 真实输出:{y[i][0]}")

运行结果:

Epoch 0, Error: 0.4999999999999999
Epoch 10000, Error: 0.04999999999999999
Epoch 20000, Error: 0.024999999999999998
Epoch 30000, Error: 0.016666666666666666
Epoch 40000, Error: 0.012499999999999999
Epoch 50000, Error: 0.009999999999999998
Epoch 60000, Error: 0.008333333333333333
Epoch 70000, Error: 0.007142857142857142
Epoch 80000, Error: 0.006249999999999999
Epoch 90000, Error: 0.005555555555555555

测试结果:
输入:[0 0], 预测输出:0.0050, 真实输出:0
输入:[0 1], 预测输出:0.9949, 真实输出:1
输入:[1 0], 预测输出:0.9949, 真实输出:1
输入:[1 1], 预测输出:0.0050, 真实输出:0

可以看到,BP神经网络完美解决了异或问题,预测值非常接近真实标签。

四、全局最小与局部极小:神经网络的“陷阱”

训练神经网络的本质是找到损失函数的最小值点,但损失函数的曲面通常是凹凸不平的,存在很多“山谷”,这就引出了两个重要概念:

  • 全局最小:整个参数空间中损失函数最小的点,是我们想要的最优解
  • 局部极小:某个局部区域内损失函数最小的点,但比全局最小大,是训练过程中的“陷阱”

通俗来说,就像你在一片山脉中找最低的山谷,全局最小是整个山脉的最低点,而局部极小是你眼前的一个小山谷,你以为到了最低处,其实还有更低的山谷在远方。

4.1 跳出局部极小的方法

  1. 多组随机初始化:用不同的随机数初始化网络参数,相当于从不同的起点开始爬山,最后选最低的那个山谷
  2. 模拟退火:以一定概率接受比当前更差的解,就像你在小山谷里先爬上山坡,再去寻找更低的山谷,随着训练进行,逐渐降低接受差解的概率,最终收敛到全局最小
  3. 随机梯度下降:用单个样本的梯度更新参数,引入随机性,让参数更新有机会跳出局部极小

五、百花齐放:常见的神经网络变体

除了标准的前馈神经网络,研究者们还提出了很多针对不同任务的神经网络变体,下面介绍几种最经典的:

5.1 RBF网络

径向基函数(RBF)网络是一种单隐藏层前馈网络,隐藏层的激活函数是径向基函数(如高斯函数)。它的特点是:只有隐藏层到输出层的权重需要训练,输入层到隐藏层的参数是固定的,训练速度快,适合解决函数逼近问题。

5.2 SOM网络

自组织映射(SOM)网络是一种无监督神经网络,能将高维数据映射到低维(通常是二维)平面,同时保持数据的拓扑结构——相似的高维样本会被映射到平面上相邻的位置。就像你把一堆乱的书自动分类,相似的书会放在一起。

在这里插入图片描述

图5.4 SOM网络拓扑映射 图中展示了SOM网络将高维人脸数据映射到二维网格的结果,相似的人脸被映射到了相邻的网格位置。

5.3 Elman网络

Elman网络是一种递归神经网络(RNN),它在隐藏层加入了反馈连接,能保存之前的状态信息,因此适合处理时序数据,比如语音识别、自然语言处理。

5.4 Boltzmann机

Boltzmann机是基于能量的模型,分为可见层和隐藏层,神经元的输出是0或1,用吉布斯采样进行训练。它能学习数据的概率分布,是生成式模型的早期代表。

六、深度学习:神经网络的“黄金时代”

为什么神经网络在提出几十年后,才在2010年左右迎来爆发,变成了如今的“深度学习”?主要有两个原因:一是GPU的出现提供了强大的计算能力,二是互联网的发展带来了海量的训练数据。

6.1 深度学习的核心技巧

  1. 逐层预训练:先逐层训练隐藏层,让每一层都学习到有用的特征,然后再用BP算法微调整个网络。这解决了深层网络梯度消失的问题——误差反向传播时,越往前的层梯度越小,几乎无法更新。
  2. 权共享:最典型的应用是卷积神经网络(CNN)。卷积核在整个图像上滑动,所有位置共享同一个卷积核的权重,这大大减少了参数数量,同时让网络具有平移不变性——不管猫在图片的哪个位置,都能被识别出来。

6.2 卷积神经网络(CNN)

CNN是目前计算机视觉领域的主流模型,它的结构主要包括:

  • 卷积层:用卷积核提取图像的局部特征,比如边缘、纹理、物体
  • 池化层:对特征图进行降采样,保留主要信息,减少计算量
  • 全连接层:将提取到的特征映射到输出空间,进行分类或回归

在这里插入图片描述

图5.5 卷积神经网络结构 图中展示了一个经典的CNN结构:输入图像经过多个卷积层和池化层提取特征,最后通过全连接层输出分类结果。

如今,深度学习已经渗透到了我们生活的方方面面:人脸识别、自动驾驶、智能语音、大语言模型……这些技术的底层,都是神经网络的进化和延伸。

七、总结与延伸

从1943年的M-P神经元,到1957年的感知机,再到1986年的BP算法,最后到如今的深度学习,神经网络走过了跌宕起伏的80年。它从一个简单的数学模型,发展成了改变世界的核心技术。

本文介绍了神经网络的基础原理,但这只是冰山一角。如果你想深入学习,可以继续研究:

  • 更先进的激活函数:ReLU、Leaky ReLU、GELU
  • 更强大的优化器:Adam、RMSprop
  • 主流的深度学习框架:PyTorch、TensorFlow
  • 最新的模型架构:Transformer、扩散模型

神经网络的故事还在继续,未来它还会带给我们更多的惊喜。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐