欢迎光临
我们一直在努力

周志华《Machine Learning》学习笔记--第五章--神经网络

神经网络入门到实战:从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_1w1w2w_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算法分为两个阶段:

  • 前向传播:输入信号从输入层经过隐藏层,最终传到输出层,计算出预测值和误差
  • 反向传播:把输出层的误差从后往前逐层传递,计算每一层神经元的梯度,然后用梯度下降法更新所有的权重和阈值
  • 通俗来说,这就像你考试考砸了:先看最后一道题错了多少(输出误差),然后倒推这道题是哪个知识点没掌握(隐藏层误差),再倒推这个知识点是上课没听懂还是练习不够(输入层权重),最后针对性地调整学习方法,下次就能考得更好。

    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

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

  • 输出层梯度项:衡量输出层每个神经元对误差的贡献
    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)
  • 隐藏层梯度项:衡量隐藏层每个神经元对输出层误差的贡献
    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神经网络的表达能力极强,很容易出现过拟合:在训练集上表现很好,但在测试集上表现很差。解决过拟合主要有两种方法:

  • 早停:将数据集分成训练集和验证集,训练过程中不断计算验证集误差,当验证集误差开始上升时,立即停止训练,避免模型过度拟合训练集
  • 正则化:在损失函数中加入权重的平方和项,惩罚过大的权重,让模型更简单:
    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 跳出局部极小的方法

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

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

    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 深度学习的核心技巧

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

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

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

    在这里插入图片描述

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

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

    七、总结与延伸

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

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

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

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

    赞(0)
    未经允许不得转载:171主机测评 » 周志华《Machine Learning》学习笔记--第五章--神经网络
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址