Python神经网络编程(一):预测器、分类器与神经网络基础概念

本文是《Python神经网络编程》系列博客的第1篇,基于真实服务器实操输出,涵盖实验1-2的所有内容。

服务器环境:Ubuntu 24.04 / Python 3.12.3 / NumPy 2.5.1 / Matplotlib 3.11.0
服务器:华为云 ecs-1f62-0001 (120.46.93.164)


目录


你将学到什么

在本篇博客中,你将通过从零开始的数学推导Python代码实操,理解神经网络的核心概念:

  1. 预测器(Predictor):线性回归如何工作
  2. 分类器(Classifier):从回归到分类的跨越
  3. 线性分类器的局限性:为什么XOR问题无法用一条直线解决
  4. 激活函数(Activation Function):给神经网络引入非线性
  5. 神经网络的结构:从单层到多层,从线性到非线性

实验1:预测器与分类器

1.1 人工智能的概念

人工智能(Artificial Intelligence, AI) 的本质是让机器能够模拟人类的智能行为,包括学习、推理、感知和决策。

神经网络是人工智能的一个重要分支,它受到生物神经网络的启发:

生物神经网络                    人工神经网络
┌──────────┐                  ┌──────────┐
│  神经元    │                  │   节点    │
│  (Neuron) │  ←类比→       │  (Node)  │
└──────────┘                  └──────────┘
      │                              │
      ▼                              ▼
  树突接收信号                加权求和 + 激活函数
  轴突传递信号                输出到下一层

1.2 预测机(Predictor)

预测器是一个简单的数学模型,用于根据输入预测输出。

核心公式
y = w × x + b

其中:

  • x:输入(特征)
  • y:输出(预测值)
  • w:权重(weight),表示输入对输出的影响程度
  • b:偏置(bias),表示当输入为0时的输出
Python实现:简单线性预测器
import numpy as np

# 简单线性预测器
def predict(x, w, b):
    """简单的线性预测器"""
    return w * x + b

# 示例:根据学习时间预测考试分数
# 训练数据:(学习时间, 考试分数)
training_data = [
    [1.0, 35.0],
    [2.0, 48.0],
    [3.0, 62.0],
    [4.0, 75.0],
    [5.0, 85.0],
    [6.0, 92.0]
]

# 使用最小二乘法计算权重w和偏置b
# 公式:w = Σ((x_i - x_mean)(y_i - y_mean)) / Σ((x_i - x_mean)²)
#       b = y_mean - w * x_mean
x = np.array([d[0] for d in training_data])
y = np.array([d[1] for d in training_data])

x_mean = np.mean(x)
y_mean = np.mean(y)

w = np.sum((x - x_mean) * (y - y_mean)) / np.sum((x - x_mean) ** 2)
b = y_mean - w * x_mean

print(f"训练数据: {training_data}")
print(f"计算得到: w = {w:.4f}, b = {b:.4f}")
print(f"预测函数: y = {w:.4f} * x + {b:.4f}")

# 预测
for test_x in [3.5, 7, 8]:
    pred_y = predict(test_x, w, b)
    print(f"  学习 {test_x} 小时 -> 预测分数: {pred_y:.1f}")

服务器真实输出

训练数据: [[1.0, 35.0], [2.0, 48.0], [3.0, 62.0], [4.0, 75.0], [5.0, 85.0], [6.0, 92.0]]
计算得到: w = 11.6857, b = 25.2667
预测函数: y = 11.6857 * x + 25.2667
  学习 3.5 小时 -> 预测分数: 66.2
  学习 7 小时 -> 预测分数: 107.1
  学习 8 小时 -> 预测分数: 118.8
最小二乘法推导

目标:找到一条直线 y = wx + b,使得所有样本点到直线的垂直距离平方和最小。

误差函数(Loss Function)

E = Σ(y_i - (w × x_i + b))²

求解:对 wb 求偏导,令偏导为0:

∂E/∂w = -2 × Σ(y_i - w×x_i - b) × x_i = 0
∂E/∂b = -2 × Σ(y_i - w×x_i - b) = 0

解方程组得到:

w = Σ((x_i - x_mean)(y_i - y_mean)) / Σ((x_i - x_mean)²)
b = y_mean - w × x_mean

1.3 分类机(Classifier)

分类器将输入映射到离散的类别标签,而不是连续值。

从预测到分类

预测器的输出是连续值(如分数 66.2),而分类器的输出是类别(如"及格"/“不及格”)。

方法:设置一个阈值(threshold),将连续输出转换为类别。

# 简单分类器
def classify(score, threshold=60):
    """根据分数判断是否及格"""
    return "及格" if score >= threshold else "不及格"

# 测试
for hours in [1, 2, 3, 4, 5, 6]:
    score = predict(hours, w, b)
    label = classify(score)
    print(f"  学习 {hours} 小时, 分数 {score:.0f} -> {label}")

服务器真实输出

学习 1 小时, 分数 35 -> 不及格
学习 2 小时, 分数 48 -> 不及格
学习 3 小时, 分数 62 -> 及格
学习 4 小时, 分数 75 -> 及格
学习 5 小时, 分数 85 -> 及格
学习 6 小时, 分数 92 -> 及格

实验2:多分类器与神经网络

2.1 线性分类器的局限

线性分类器只能用一个**超平面(在2D中是直线)**来划分两类数据。

XOR问题:线性不可分

XOR(异或) 是一个经典的线性不可分问题:

输入A 输入B XOR输出
0 0 0
0 1 1
1 0 1
1 1 0

在2D平面上,XOR的输出分布如下:

     B=1
      │ 1   0
      │
B=0───┼───B=1
      │
      │ 0   1
     B=0
      A=0  A=1

无法用一条直线将"1"和"0"分开! 这就是线性分类器的局限性。

可视化:线性分类器的局限

在这里插入图片描述

(图1:线性分类器无法用一条直线将XOR的两类分开)

2.2 激活函数的意义

激活函数(Activation Function) 是神经网络的灵魂,它引入了非线性,使得神经网络可以拟合任意复杂的函数。

常见激活函数
激活函数 公式 输出范围 特点
Step 0 if x<0 else 1 {0, 1} 最早使用,不可导
Sigmoid 1 / (1 + e^(-x)) (0, 1) 平滑,可导,梯度消失
Tanh (e^x - e^(-x)) / (e^x + e^(-x)) (-1, 1) 零中心,梯度消失
ReLU max(0, x) [0, +∞) 计算简单,缓解梯度消失
Python实现:激活函数对比
import numpy as np
import matplotlib.pyplot as plt

def sigmoid(x):
    return 1 / (1 + np.exp(-x))

def tanh(x):
    return np.tanh(x)

def relu(x):
    return np.maximum(0, x)

def step(x):
    return np.where(x >= 0, 1, 0)

# 测试各激活函数
x_values = [-2, -1, 0, 1, 2]
print(f"{'x':>4} | {'Sigmoid':>12} | {'Tanh':>12} | {'ReLU':>12} | {'Step':>10}")
print("-" * 60)
for x in x_values:
    s = sigmoid(x)
    t = tanh(x)
    r = relu(x)
    st = step(x)
    print(f"{x:>4} | {s:>12.4f} | {t:>12.4f} | {r:>12.4f} | {st:>10.0f}")

服务器真实输出

    x |    Sigmoid |        Tanh |        ReLU |      Step
------------------------------------------------------------
   -2 |     0.1192 |    -0.9640 |     0.0000 |          0
   -1 |     0.2689 |    -0.7616 |     0.0000 |          0
    0 |     0.5000 |     0.0000 |     0.0000 |          1
    1 |     0.7311 |     0.7616 |     1.0000 |          1
    2 |     0.8808 |     0.9640 |     2.0000 |          1
可视化:激活函数对比

在这里插入图片描述

(图2:4种常见激活函数的曲线对比)

2.3 神经网络的起源

神经网络的灵感来自于生物大脑:

生物神经元                        人工神经元
───────                        ─────────
  Dendrite ───► 树突         输入 x1, x2, ..., xn
       │                        │
       ▼                        ▼
  Cell Body ───► 细胞体      加权求和 + 偏置
       │                        │
       ▼                        ▼
  Axon ───► 轴突            激活函数
       │                        │
       ▼                        ▼
  Synapse ───► 突触         输出 y

人工神经元的数学模型:

y = activation(Σ(w_i × x_i) + b)

2.4 神经网络的结构

三层神经网络
输入层          隐藏层           输出层
(3个节点)      (3个节点)        (2个节点)

  x1 ──w11──→ h1 ──w'11──→ o1
    ╲    ╱       ╲    ╱
     ╲╱           ╲╱
     ╱╲           ╱╲
    ╱    ╲       ╱    ╲
  x2 ──w22──→ h2 ──w'22──→ o2
    ╲    ╱       ╱    ╲
     ╲╱         ╱      ╲
     ╱╲         ╲      ╱
    ╱    ╲       ╲    ╱
  x3 ──w33──→ h3 ──w'33──→

  每个连接都有一个权重 w
  全连接(Fully Connected): 每个节点与下一层所有节点相连
参数数量计算

对于网络结构 3-3-2

输入层 -> 隐藏层:3 × 3 = 9 个权重
隐藏层 -> 输出层:3 × 2 = 6 个权重
偏置:3(隐藏层)+ 2(输出层)= 5 个
总参数:9 + 6 + 5 = 20 个

通用公式:对于网络 n_0 - n_1 - n_2 - ... - n_L

总参数 = Σ(n_i × n_{i+1}) + Σ(n_i)   (i从0到L-1)
         ↑                    ↑
   层间权重            每层的偏置

2.5 模型训练的本质

训练的本质调整权重和偏置,使得网络的输出尽可能接近目标输出。

训练流程
1. 初始化权重(随机或小值)
   ↓
2. 正向传播(Forward Propagation)
   - 输入 -> 隐藏层 -> 输出层
   - 计算当前输出
   ↓
3. 计算误差(Loss)
   - Loss = target - output
   ↓
4. 反向传播(Backward Propagation)
   - 将误差从输出层传回输入层
   - 计算每个权重对误差的贡献
   ↓
5. 更新权重
   - w_new = w_old - η × ∂Loss/∂w
   ↓
6. 重复步骤2-5(多轮训练)

2.6 全连接的意义

全连接(Fully Connected) 意味着上一层每个节点都与下一层每个节点相连

为什么全连接?
  1. 信息最大化:每个节点都能接收到上一层所有节点的信息
  2. 表达能力最强:理论上可以拟合任意函数(万能近似定理)
  3. 梯度传播充分:误差可以传播到每一个权重
计算量分析

全连接层的计算复杂度:

对于层A(n个节点)-> 层B(m个节点):
  - 权重矩阵大小:m × n
  - 一次前向传播:O(m × n) 次乘法
  - 一次反向传播:O(m × n) 次乘法

示例:MNIST网络 784-100-10

输入层 -> 隐藏层:784 × 100 = 78,400 个权重
隐藏层 -> 输出层:100 × 10 = 1,000 个权重
总权重:79,400 个

总结

在本篇博客中,我们学习了:

  1. 预测器:用线性回归模型根据输入预测输出
  2. 分类器:用阈值将连续输出转换为类别标签
  3. 线性分类器的局限:XOR问题无法用一条直线解决
  4. 激活函数:Sigmoid、Tanh、ReLU等引入非线性
  5. 神经网络结构:多层神经元,全连接
  6. 训练的本质:通过调整权重最小化误差

关键公式回顾

预测器:y = w × x + b
神经元:y = activation(Σ(w_i × x_i) + b)
Sigmoid:σ(x) = 1 / (1 + e^(-x))
参数数量:Σ(n_i × n_{i+1}) + Σ(n_i)

下一篇预告

第2篇:神经网络的正向传播与误差的反向传播

你将学习:

  • 矩阵运算在神经网络中的应用
  • 信号如何在多层网络中传播
  • 误差如何反向传播到每一层
  • 每个权重对误差的贡献如何计算

参考文献

  1. Tariq Rashid, 《Python神经网络编程》
  2. Ian Goodfellow 等, 《深度学习》
  3. MNIST数据库:http://yann.lecun.com/exdb/mnist/

代码仓库:本文所有代码可在服务器 /root/nn_blog/ 目录下找到。


作者:腾讯DevOps工程师 | 最后更新:2026年7月

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐