趋近智
这个动手练习将指导你使用Python和NumPy库从零开始实现一个简单的感知器。感知器的设计依赖于其理论原理,例如基于人工神经元的结构及其对线性可分问题的局限性。构建这个模型将巩固你对输入、权重 (weight)、偏置 (bias)以及学习规则如何共同作用以实现分类的理解。
我们将处理一个经典的线性可分问题:逻辑AND门。AND门仅当两个输入都为1时才输出1,否则输出0。
AND门的真值表如下:
| 输入 1 (x1) | 输入 2 (x2) | 输出 (y) |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |
我们的目标是训练一个感知器,它以 作为输入并正确预测 。因为在二维图中,我们可以画一条直线来分隔 的点和 的点,所以这个问题是线性可分的,可以通过单个感知器解决。
回顾感知器学习步骤:
我们对所有训练样本重复步骤2-4多次(迭代),直到模型收敛(对所有样本做出正确预测)或达到最大迭代次数。
让我们来实现它。我们将使用NumPy进行高效的数值运算。
import numpy as np
# 定义AND门数据集
# 输入 (X) (为方便后续处理而包含了一个偏置项)
# 但为清晰起见,我们将在下面的代码中单独处理偏置。
X = np.array([
[0, 0],
[0, 1],
[1, 0],
[1, 1]
])
# 输出 (y)
y = np.array([0, 0, 0, 1])
# 初始化权重和偏置
# 两个输入,因此两个权重。设置为小的随机值。
np.random.seed(42) # 用于结果可复现
weights = np.random.rand(2) * 0.1 # 例如,[0.037, 0.095]
bias = np.random.rand(1) * 0.1 # 例如,[0.073]
# 定义阶跃激活函数
def step_function(z):
return np.where(z >= 0, 1, 0)
# 设置学习参数
learning_rate = 0.1
epochs = 50 # 遍历整个数据集的次数
print(f"初始权重: {weights}, 初始偏置: {bias[0]:.3f}")
print("-" * 30)
# 训练循环
for epoch in range(epochs):
errors = 0
for i in range(len(X)):
# 获取当前输入样本和目标
inputs = X[i]
target = y[i]
# 1. 计算加权和(激活值)
z = np.dot(inputs, weights) + bias
# 2. 进行预测
prediction = step_function(z)
# 3. 计算误差
error = target - prediction
# 4. 如果误差不为零,更新权重和偏置
if error != 0:
errors += 1
weights += learning_rate * error * inputs
bias += learning_rate * error
# 打印进度(可选)
if (epoch + 1) % 10 == 0:
print(f"迭代 {epoch+1}/{epochs}, 误差: {errors}, 权重: [{weights[0]:.3f}, {weights[1]:.3f}], 偏置: {bias[0]:.3f}")
# 检查收敛性(一个迭代中没有误差)
if errors == 0 and epoch > 0:
print(f"\n模型在迭代 {epoch+1} 达到收敛。")
break
print("-" * 30)
print(f"最终权重: [{weights[0]:.3f}, {weights[1]:.3f}]")
print(f"最终偏置: {bias[0]:.3f}")
# 测试训练好的感知器
print("\n测试训练好的感知器:")
for i in range(len(X)):
inputs = X[i]
target = y[i]
z = np.dot(inputs, weights) + bias
prediction = step_function(z)
print(f"输入: {inputs}, 目标: {target}, 预测: {prediction[0]}")
运行上述代码应产生类似于以下内容的输出(由于随机初始化,具体权重 (weight)可能略有不同):
Initial weights: [0.03745401 0.09507143], Initial bias: 0.073
------------------------------
Epoch 10/50, Errors: 0, Weights: [0.137, 0.095], Bias: -0.127
Convergence reached at epoch 10.
------------------------------
Final weights: [0.137, 0.095]
Final bias: -0.127
Testing the trained Perceptron:
Input: [0 0], Target: 0, Prediction: 0
Input: [0 1], Target: 0, Prediction: 0
Input: [1 0], Target: 0, Prediction: 0
Input: [1 1], Target: 1, Prediction: 1
你可以看到权重和偏置 (bias)在各个迭代中进行调整。错误数量减少直到变为零,表明感知器已学会正确分类AND门的所有输入模式。最终测试确认预测与目标输出一致。
对于这样的二维问题,我们可以可视化感知器学习到的决策边界。该边界是加权和为零的线:。我们可以将其重写为 作为 的函数来绘图:。
该图显示了AND门的四个输入点。红色的点代表输出为0,蓝色的点代表输出为1。绿线是感知器学习到的决策边界 ()。线上方的所有点都被分类为0,线下方的点被分类为1。
这种实际实现说明了感知器的核心机制。尽管简单,但它提供了理解学习过程中权重 (weight)如何调整的途径。正如我们之前所看到的,这个模型有局限性(它不能解决XOR问题)。这促使我们转向多层感知器(MLP),多层感知器增加了隐藏层以处理更复杂的非线性可分模式,我们将在后续章节中讨论。
这部分内容有帮助吗?
© 2026 ApX Machine LearningAI伦理与透明度•