BP神经网络

系列文章见: 《回忆AI时代-从图灵机到人工智能》

假设你每天都会根据一些因素决定是否骑车,我们希望训练一个BP神经网络来学习你的决策习惯。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
import numpy as np

# ==========================================================
# 1. Sigmoid 激活函数
# ==========================================================
# 神经元输出不能直接使用加权和
# 而是需要经过激活函数
#
# Sigmoid 可以把任意数字压缩到 0~1
#
# 输入:-10 -1 0 1 10
# 输出:0.00 0.27 0.50 0.73 1.00
#
def sigmoid(x):
return 1 / (1 + np.exp(-x))


# ==========================================================
# Sigmoid 导数
# ==========================================================
# BP反向传播需要计算梯度
#
# Sigmoid'(x)=Sigmoid(x)*(1-Sigmoid(x))
#
def sigmoid_derivative(y):
return y * (1 - y)


# ==========================================================
# 2. 训练数据
# ==========================================================
#
# 输入:
# 天气(晴=1 雨=0)
# 是否周末(周末=1 工作日=0)
# 身体状态(好=1 差=0)
#
# 输出:
# 是否去骑车
#
X = np.array([
[1, 1, 1], # 晴天 周末 身体好
[1, 0, 1], # 晴天 工作日 身体好
[0, 1, 1], # 雨天 周末 身体好
[1, 1, 0], # 晴天 周末 身体差
[0, 0, 1], # 雨天 工作日 身体好
[0, 1, 0], # 雨天 周末 身体差
[1, 0, 0], # 晴天 工作日 身体差
[0, 0, 0] # 雨天 工作日 身体差
])

# 标签(真实答案)
Y = np.array([
[1],
[1],
[0],
[0],
[0],
[0],
[0],
[0]
])


# ==========================================================
# 3. 初始化网络参数
# ==========================================================

np.random.seed(0)

# 输入层(3) ------> 隐藏层(4)
#
# W1 大小:
#
# 隐藏1 隐藏2 隐藏3 隐藏4
# 天气
# 周末
# 身体
#
W1 = np.random.randn(3, 4)

# 隐藏层偏置
b1 = np.zeros((1, 4))

# 隐藏层(4) ------> 输出层(1)
W2 = np.random.randn(4, 1)

# 输出层偏置
b2 = np.zeros((1, 1))

# 学习率
learning_rate = 0.5


# ==========================================================
# 4. 开始训练
# ==========================================================
#
# BP神经网络训练流程:
#
# 前向传播
# ↓
# 得到预测值
# ↓
# 计算误差
# ↓
# 反向传播
# ↓
# 更新权重
#
for epoch in range(10000):

# ======================================================
# 第一步:前向传播(Forward)
# ======================================================

# 输入层 -> 隐藏层
#
# hidden_input =
# X × W1 + b1
#
hidden_input = np.dot(X, W1) + b1

# 隐藏层经过激活函数
hidden_output = sigmoid(hidden_input)

# 隐藏层 -> 输出层
final_input = np.dot(hidden_output, W2) + b2

# 输出层激活
prediction = sigmoid(final_input)

# ======================================================
# 第二步:计算误差
# ======================================================
#
# prediction:AI预测
# Y:真实答案
#
error = Y - prediction

# 均方误差(MSE)
loss = np.mean(error ** 2)

# ======================================================
# 第三步:反向传播(Back Propagation)
# ======================================================

# -----------------------------
# 输出层梯度
# -----------------------------
#
# 告诉输出层:
# "你应该修改多少"
#
d_output = error * sigmoid_derivative(prediction)

# -----------------------------
# 隐藏层误差
# -----------------------------
#
# 输出层误差
# ↓
# 传播回隐藏层
#
hidden_error = np.dot(d_output, W2.T)

# 隐藏层梯度
d_hidden = hidden_error * sigmoid_derivative(hidden_output)

# ======================================================
# 第四步:更新权重
# ======================================================

# 更新隐藏层 -> 输出层权重
W2 += learning_rate * np.dot(hidden_output.T, d_output)

# 更新输出层偏置
b2 += learning_rate * np.sum(d_output, axis=0, keepdims=True)

# 更新输入层 -> 隐藏层权重
W1 += learning_rate * np.dot(X.T, d_hidden)

# 更新隐藏层偏置
b1 += learning_rate * np.sum(d_hidden, axis=0, keepdims=True)

# 每1000轮打印一次Loss
if epoch % 1000 == 0:
print(f"Epoch {epoch:5d} Loss={loss:.6f}")


# ==========================================================
# 5. 测试
# ==========================================================

print("\n============== 测试结果 ==============\n")

tests = {
"晴天 周末 身体好": [1, 1, 1],
"晴天 周末 身体差": [1, 1, 0],
"雨天 周末 身体好": [0, 1, 1],
"晴天 工作日 身体好": [1, 0, 1],
}

for name, sample in tests.items():

x = np.array([sample])

# 前向传播
hidden = sigmoid(np.dot(x, W1) + b1)
output = sigmoid(np.dot(hidden, W2) + b2)

print(f"{name:<15} -> 去骑车概率:{output[0,0]:.3f}")

整个训练过程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
       训练开始


输入训练数据(X)


初始化权重(W1、W2)


┌─────────────┐
│ 前向传播 │
│ Input → Hidden → Output │
└─────────────┘


得到预测值 Prediction


与真实值 Y 比较计算 Loss


┌─────────────┐
│ 反向传播 BP │
│ Output → Hidden │
└─────────────┘


更新权重 W1、W2 和偏置 b1、b2


Loss 是否足够小?
│ │
否 是
│ │
└────继续训练┘

输出训练好的模型

2023年,进入多模态时代!

系列文章见: 《回忆AI时代-从图灵机到人工智能》

2023年发生了两件足以改变AI历史的大事“大模型进入多模态时代”和“图片生成进入全民时代”

大模型进入多模态时代

什么是多模态

多模态(Multimodality)顾名思义就是让人工智能能够理解和处理多种类型的数据,包括但不限于文本、图像、音频、视频等。换句话说,人类通过眼睛看图像、耳朵听声音、语言进行交流来获取信息,而AI也开始逐步具备类似的感知与理解能力,不再局限于处理单一的文本数据。

模态的演进

2023年被普遍认为是“大模型多模态时代”的起点,在2023年之前大多数大模型还是单模态,如:

  • GPT-3:只能处理文本
  • ChatGPT(2022年11月发布):主要也是文本对话
  • Stable Diffusion(2022):只能生成图片

2023年3月OpenAI发布了GPT-4,首次赋予大模型强大的视觉理解能力,使其能够同时处理文本与图像,标志着多模态能力正式进入大众视野。

同年Google发布了Gemini,从设计之初便采用原生多模态(Native Multimodal)架构,在训练阶段就将文本、图像、音频、视频等多种数据统一融合,而不是将多个单一模型简单拼接。这意味着AI开始能够像人类一样,对来自不同感官的信息进行综合理解与推理。

多模态应用场景

我们在使用大模型时,不只可以文本聊天,还可以与他语音对话、上传一些图片识别内容,这也带来了很多的应用场景,譬如:

  • 语音: 语音陪聊提供情绪价值、英语口语对话提升英语能力
  • 图片生成: 生成创益的广告图片与文案、个人照片优化
  • OCR: 识别发票、身份证、合同等信息
  • 生成视频:生成视频应用在广告、短视频、个人宣传片和动画等领域

2022年,AI进入了大众时代!

系列文章见: 《回忆AI时代-从图灵机到人工智能》

ChatGPT

2022年11月,一个名叫ChatGPT的产品上线,短短两个月,它突破一亿用户,成为互联网历史上增长最快的应用。许多人第一次感受到机器似乎真的开始“思考”了。

ChatGPT(GPT的全称是Generative Pre-trained Transformer,生成式预训练Transformer模型)是OpenAI公司的产品,目前ChatGPT迭代的版本:

时间 模型 主要突破
2018 GPT-1 提出预训练 + 微调范式
2019 GPT-2 参数大幅增长,生成能力显著提升
2020 GPT-3 1750 亿参数,Few-shot Learning
2022 InstructGPT 引入 RLHF,更好遵循人类指令
2022 ChatGPT 将大语言模型以对话形式带给大众
2023 GPT-4 推理能力增强,支持图像理解
2024 GPT-4o 原生多模态,实时语音与视觉交互
2025 GPT-4.1 提升编程、长上下文和开发者体验
2025 GPT-5 综合推理、工具调用和多模态能力进一步提升

OpenAI成立于2015年总部位于美国旧金山,最初是一家人工智能研究机构,目标是推动人工智能技术的发展并让人工智能能够造福全人类

Read More

感知机

系列文章见: 《回忆AI时代-从图灵机到人工智能》

我们让计算机判断今天适不适合去七骑车?用感知机的案例。在之前的案例中,程序员把权重w = np.array([2.0, 0.8, 3.0])写到程序中,但实际这里不应该由程序员写到程序中,而是需要给计算机大量历史数据,让它自己学习,譬如:

天气 周末 身体 是否骑车
1 1 1 1
1 0 1 1
0 1 1 0
0 0 1 0
1 1 0 0
0 0 0 0

Read More

M-P神经元案例

系列文章见: 《回忆AI时代-从图灵机到人工智能》

M-P神经元案例

假如,我们让计算机判断今天适不适合去七骑车?用M-P神经元的案例,我们给神经元三个输入X1、X2、X3,如果神经元会输出0~1间,譬如0.95 非常适合汽车。以下为Python示例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import numpy as np

# 输入
x = np.array([1, 1, 1])

# 权重
w = np.array([2.0, 0.8, 3.0])

# 阈值
theta = 5

# 计算点积(加权和)
s = np.dot(x, w)

# M-P神经元
if s >= theta:
y = 1
else:
y = 0

print("加权和:", s)
print("输出:", y)

案例解释:

    1. np.array() 创建向量
    1. np.dot() 计算点积
    1. 输入表示:
      输入 含义 当前值
      x1 天气晴 1
      x2 周末 1
      x3 身体状态好 1

结构:

1
2
3
4
5
x1 ----\
\
x2 ------> 神经元 --> <判断> -> 0 不适合骑行
/ |----> 1 适合骑行
x3 ----/
    1. 权重对应的含义:
      输入 权重 含义
      x1 2.0 天气
      x2 0.8 周某
      x3 3.0 身体状态
    1. 阈值(Threshold),当加权和≥5 时输出1否者为0。
    1. 实际计算过程:
1
2
3
4
5
  1 × 2.0
+ 1 × 0.8
+ 1 × 3.0
----------
5.8
    1. 打印结果:
1
2
加权和: 5.8
输出: 1

表示适合骑行。

骑行案例

骑行案例,条件越好,越适合骑车。这里符合一种规律好的因素越多,结果越偏向"适合骑车

天气 周末 身体 是否适合骑车

所以通过神经元画一条分界线就能区分:

1
2
3
4
5
6
7
      适合骑车
● ● ●

----------------- ← 一条直线

● ●
不适合骑车

RNN让计算机学会"记忆"

系列文章见: 《回忆AI时代-从图灵机到人工智能》

什么是RNN

RNN(Recurrent Neural Network,循环神经网络)是一种专门用于处理序列数据的神经网络,它最大的特点就是具有记忆能力,能够利用之前的信息来理解当前的信息。

譬如,我们让计算机理解这句话今天天气很好,对于人来说我们按顺序阅读今天 → 天气 → 很好当看到”很好”时,我们的大脑已经记住了前面的”今天”和”天气”,因此能够理解整句话,如果只看到最后两个字很好你并不知道到底是什么很好。

因此语言的理解依赖上下文,而上下文本质上就是一种”记忆”,RNN正是为了解决这个问题而设计的。

Read More