机器学习入门:用 Python 亲手实现感知机,迈出神经网络第一步281
今天,我们要一起揭开机器学习世界里一块基石的神秘面纱——感知机(Perceptron)。它不仅是第一个被提出的人工神经网络模型,更是理解后续复杂神经网络的绝佳起点。我们将从理论、数学原理出发,最终用大家最爱的 Python 亲手实现它!
---
各位机器学习的初学者们,大家好!我是你们的AI学习伙伴。今天,我们要深入探讨一个历史悠久却依旧意义非凡的算法——感知机 (Perceptron)。在深度学习风靡全球的今天,感知机可能听起来有些“老派”,但它却是人工神经网络的鼻祖,是理解多层感知机(MLP)乃至更复杂深度学习模型的基石。通过亲手用 Python 实现它,我们不仅能掌握其工作原理,更能体会从零构建智能算法的乐趣。
感知机由美国科学家 Frank Rosenblatt 于1957年提出,灵感来源于生物神经元的工作方式。它是一个二分类的线性分类模型,能够对输入数据进行学习,并输出一个判别结果(例如是/否,1/-1)。虽然它简单,但却在当时掀起了人工智能研究的热潮。
感知机的前世今生:AI的曙光
在20世纪中叶,计算机科学领域迎来了人工智能的萌芽。Frank Rosenblatt 在1957年提出了感知机模型,模拟人脑神经元接收信号、处理信号并作出决策的过程。这一创新性的工作在当时引发了巨大的轰动,人们一度认为人工智能的奇点即将来临。感知机被视为能够“学习”并解决简单分类问题的机器,它甚至被用于识别图像等任务。
然而,1969年 Marvin Minsky 和 Seymour Papert 出版了《Perceptrons》一书,指出了感知机的一个致命缺陷——它无法解决非线性可分问题,其中最著名的就是“异或(XOR)”问题。这一发现如同给当时的AI研究泼了一盆冷水,导致了AI研究进入了所谓的“AI寒冬”。但历史总是螺旋式上升的,感知机的局限性促使科学家们思考更复杂的模型,最终催生了多层感知机和反向传播算法的诞生,为后来的深度学习浪潮奠定了基础。所以,理解感知机,不仅是学习算法本身,更是回顾AI发展历程的重要一课。
感知机的工作原理:一个模拟神经元的决策过程
要理解感知机,我们可以把它想象成一个非常简单的“决策者”。这个决策者接收多个输入信号,每个信号都有一个对应的“重要性”或“权重”。它会将这些加权后的信号累加起来,再加上一个“偏置项”(bias),然后通过一个简单的规则(激活函数)来做出最终的决策。
2.1 神经元模型
一个感知机神经元接收 $n$ 个输入 $x_1, x_2, \ldots, x_n$。每个输入都有一个对应的权重 $w_1, w_2, \ldots, w_n$。此外,还有一个偏置项 $b$。
它的计算过程可以分为两步:
加权求和(Soma):将所有输入与对应权重相乘,然后将结果相加,再加上偏置项。
$$z = w_1x_1 + w_2x_2 + \ldots + w_nx_n + b = \sum_{i=1}^{n} w_ix_i + b$$
激活(Activation):将加权求和的结果 $z$ 输入到激活函数中,产生最终的输出。对于经典的感知机,我们使用阶跃函数(Step Function)作为激活函数:
$$f(z) = \begin{cases} 1 & \text{if } z \ge 0 \\ -1 & \text{if } z < 0 \end{cases}$$
或者有时候也用 0 作为负类:
$$f(z) = \begin{cases} 1 & \text{if } z \ge 0 \\ 0 & \text{if } z < 0 \end{cases}$$
这里我们采用输出为 $1$ 或 $-1$ 的形式。
2.2 决策边界
感知机模型的本质是寻找一个超平面(在二维空间中就是一条直线,三维空间中是一个平面)来将不同类别的样本分隔开。这个超平面就是我们的决策边界。
当 $z = \sum_{i=1}^{n} w_ix_i + b = 0$ 时,就定义了我们的决策边界。感知机模型只能处理线性可分的数据集,即存在一个超平面可以将不同类别的数据完全分开。
2.3 学习算法:如何让感知机“变聪明”
感知机的学习过程,就是通过不断调整权重 $w$ 和偏置 $b$,使得它能够正确地对训练数据进行分类。这个过程是一个迭代优化的过程:
初始化:
随机初始化权重 $w$ 和偏置 $b$(通常初始化为全零或小的随机数)。
设置学习率 $\eta$(eta),它控制了每次权重和偏置更新的步长。
迭代更新:
对于训练集中的每一个样本 $(x^{(j)}, y^{(j)})$,重复以下步骤,直到所有样本都被正确分类(或者达到最大迭代次数):
预测输出:根据当前的权重 $w$ 和偏置 $b$,计算样本 $x^{(j)}$ 的预测值 $\hat{y}^{(j)}$:
$$\hat{y}^{(j)} = f(\sum_{i=1}^{n} w_ix_i^{(j)} + b)$$
计算误差:比较预测值 $\hat{y}^{(j)}$ 和真实标签 $y^{(j)}$。如果预测错误,则进行权重和偏置的更新;如果正确,则不更新。
更新权重和偏置:如果 $\hat{y}^{(j)} e y^{(j)}$,则按照以下规则更新 $w$ 和 $b$:
$$w_i^{\text{new}} = w_i^{\text{old}} + \eta (y^{(j)} - \hat{y}^{(j)}) x_i^{(j)}$$
$$b^{\text{new}} = b^{\text{old}} + \eta (y^{(j)} - \hat{y}^{(j)})$$
这里的 $(y^{(j)} - \hat{y}^{(j)})$ 表示误差。
如果 $y^{(j)}=1$ 但 $\hat{y}^{(j)}=-1$ (实际是正类,预测为负类):误差为 $1 - (-1) = 2$。此时 $w$ 和 $b$ 会增加,使得 $z$ 增大,更容易输出 $1$。
如果 $y^{(j)}=-1$ 但 $\hat{y}^{(j)}=1$ (实际是负类,预测为正类):误差为 $-1 - 1 = -2$。此时 $w$ 和 $b$ 会减小,使得 $z$ 减小,更容易输出 $-1$。
这个更新规则的巧妙之处在于,它通过将误差乘以输入特征 $x_i^{(j)}$ 来调整对应的权重 $w_i$。如果某个特征对于正确分类有帮助,它的权重就会被加强;反之则减弱。
当数据是线性可分时,感知机学习算法保证在有限次迭代后收敛,即能够找到一组权重和偏置,使得所有训练样本都能被正确分类。
Python 编程实现感知机
理论知识讲完了,是时候撸起袖子,用 Python 来实现我们的第一个感知机模型了!我们将创建一个 `Perceptron` 类,并用它来解决一个经典的二分类问题——逻辑与门(AND Gate)问题。
3.1 准备数据:AND 门
AND 门是一个简单的逻辑运算,只有当所有输入都为真时,输出才为真。我们用 $1$ 代表真,$-1$ 代表假(或者 $0$)。
import numpy as np
# AND 门数据
# 输入 X:[x1, x2]
# 输出 y:1 或 -1
X = ([
[1, 1],
[1, -1],
[-1, 1],
[-1, -1]
])
y = ([1, -1, -1, -1]) # 对应于 X 的输出
print("输入数据 X:", X)
print("标签 y:", y)
3.2 实现核心类:Perceptron
现在,我们来定义 `Perceptron` 类,包含初始化、激活函数、训练(fit)和预测(predict)方法。
class Perceptron:
def __init__(self, learning_rate=0.01, n_iterations=1000):
"""
初始化感知机模型。
:param learning_rate: 学习率,控制权重更新的步长。
:param n_iterations: 最大迭代次数。
"""
self.learning_rate = learning_rate
self.n_iterations = n_iterations
= None # 权重
= None # 偏置
self.errors_per_iteration = [] # 记录每次迭代的错误数
def _step_function(self, z):
"""
阶跃激活函数。
:param z: 加权求和结果。
:return: 1 如果 z >= 0,否则 -1。
"""
return (z >= 0, 1, -1)
def fit(self, X, y):
"""
训练感知机模型。
:param X: 训练输入数据,形状 (n_samples, n_features)。
:param y: 训练标签,形状 (n_samples,)。
"""
n_samples, n_features =
# 初始化权重和偏置为零
= (n_features)
= 0
for _ in range(self.n_iterations):
n_errors = 0 # 记录当前迭代中的错误数
for idx, x_i in enumerate(X):
# 计算加权求和
linear_output = (x_i, ) +
# 预测输出
y_predicted = self._step_function(linear_output)
# 计算误差
error = y[idx] - y_predicted
# 如果预测错误,则更新权重和偏置
if error != 0:
+= self.learning_rate * error * x_i
+= self.learning_rate * error
n_errors += 1
(n_errors) # 记录错误数
# 如果当前迭代没有错误,说明模型已经收敛,可以提前停止训练
if n_errors == 0:
print(f"模型在第 {_ + 1} 次迭代时收敛。")
break
def predict(self, X):
"""
使用训练好的模型进行预测。
:param X: 待预测的输入数据。
:return: 预测的标签数组。
"""
linear_output = (X, ) +
y_predicted = self._step_function(linear_output)
return y_predicted
3.3 实际应用与测试
现在,我们创建 `Perceptron` 实例,用 AND 门数据进行训练,然后看看它的预测能力。
# 创建感知机实例
perceptron = Perceptron(learning_rate=0.1, n_iterations=100)
# 训练模型
print("开始训练感知机...")
(X, y)
print("训练完成。")
# 打印学习到的权重和偏置
print("学习到的权重 (w):", )
print("学习到的偏置 (b):", )
# 对训练数据进行预测
predictions = (X)
print("原始标签 y:", y)
print("模型预测 y_hat:", predictions)
# 计算准确率
accuracy = (predictions == y)
print(f"模型在训练集上的准确率: {accuracy * 100:.2f}%")
# 测试新的输入
test_X = ([
[1, 1], # 应该预测为 1
[0.5, -0.5], # 应该预测为 -1
[-2, 3] # 应该预测为 -1
])
test_y_predictions = (test_X)
print("测试输入数据 X_test:", test_X)
print("测试预测结果 y_test_hat:", test_y_predictions)
运行上述代码,你会看到感知机成功地学习了 AND 门的逻辑,并能正确地进行预测。这证明了即使是最简单的神经网络模型,也具备一定的学习能力!
感知机的局限性:XOR 难题
尽管感知机在解决线性可分问题(如 AND 门、OR 门)上表现出色,但它有一个根本性的局限:它无法处理非线性可分的数据。最著名的例子就是异或门(XOR Gate)问题。
XOR 门的逻辑如下:只有当两个输入不同时,输出才为真。
# XOR 门数据
X_xor = ([
[1, 1], # 输出 -1
[1, -1], # 输出 1
[-1, 1], # 输出 1
[-1, -1] # 输出 -1
])
y_xor = ([-1, 1, 1, -1])
# 尝试用感知机训练 XOR 门
print("尝试用感知机训练 XOR 门...")
perceptron_xor = Perceptron(learning_rate=0.1, n_iterations=1000)
(X_xor, y_xor)
predictions_xor = (X_xor)
accuracy_xor = (predictions_xor == y_xor)
print(f"感知机在 XOR 门上的准确率: {accuracy_xor * 100:.2f}%")
# 如果查看 perceptron_xor.errors_per_iteration,你会发现它永远无法收敛到 0 错误
# 每次迭代都会有错误,因为 XOR 问题无法用一条直线分开
# print("XOR 训练过程中的错误数:", perceptron_xor.errors_per_iteration)
你会发现,感知机在 XOR 问题上的准确率通常只有 50% 左右,并且永远无法完全收敛。这是因为 XOR 数据在二维平面上无法通过一条直线将其两个类别完全分开。这就是 Minsky 和 Papert 当年指出的感知机局限性。
要解决 XOR 这样的非线性问题,我们需要更复杂的模型,比如引入“隐藏层”的多层感知机(Multi-Layer Perceptron, MLP)。多层感知机通过组合多个简单感知机,形成一个更复杂的决策边界,从而能够处理非线性问题。而训练多层感知机就需要用到著名的反向传播算法(Backpropagation)。
总结与展望
恭喜你!通过今天的学习,你不仅理解了感知机的基本原理、数学模型,更用 Python 亲手实现了一个可以学习和分类的智能模型。虽然感知机有其局限性,但它无疑是人工神经网络领域的一块重要基石。
从感知机出发,我们看到了机器学习算法是如何模拟生物智能,以及在早期发展中遇到的挑战和突破。它是我们迈向理解更复杂神经网络,如卷积神经网络(CNN)、循环神经网络(RNN)和 Transformer 等深度学习模型的第一步。
希望这次的实践能为你打开机器学习和深度学习的大门,激发你继续探索的热情!如果你对多层感知机和反向传播算法感兴趣,我们可以在未来的文章中深入探讨。
感谢你的阅读和学习,我们下期再见!
2025-10-16

用Python轻松实现BMI指数计算与健康评估,新手入门到实用工具开发
https://jb123.cn/python/69727.html

掌控 JavaScript 渐变:从 CSS 魔法到 Canvas 艺术,打造动态视觉盛宴
https://jb123.cn/javascript/69726.html

Web前端性能优化利器:JavaScript中的LZMA高效压缩与解压缩实践
https://jb123.cn/javascript/69725.html

青少年编程Python:零基础入门到项目实践,开启孩子AI时代创造力!
https://jb123.cn/python/69724.html

揭秘前端魔法:深度解析常用的客户端脚本语言与未来趋势
https://jb123.cn/jiaobenyuyan/69723.html
热门文章

Python 编程解密:从谜团到清晰
https://jb123.cn/python/24279.html

Python编程深圳:初学者入门指南
https://jb123.cn/python/24225.html

Python 编程终端:让开发者畅所欲为的指令中心
https://jb123.cn/python/22225.html

Python 编程专业指南:踏上编程之路的全面指南
https://jb123.cn/python/20671.html

Python 面向对象编程学习宝典,PDF 免费下载
https://jb123.cn/python/3929.html