第9集:神经网络基础——从感知机到多层感知机
在机器学习中,神经网络(Neural Networks) 是一种强大的工具,能够解决复杂的分类和回归问题。从简单的感知机到复杂的多层感知机(MLP),神经网络已经成为深度学习的核心技术之一。今天我们将深入探讨神经网络的基本结构,并通过实践部分使用 TensorFlow/Keras 构建一个多层感知机(MLP)来解决 MNIST 手写数字识别问题。
神经网络的基本结构
1. 感知机
感知机是神经网络的基本单元,其核心思想是通过加权求和和激活函数对输入数据进行非线性变换。公式如下:
y
=
f
(
∑
i
=
1
n
w
i
x
i
+
b
)
y = f(\sum_{i=1}^{n} w_i x_i + b)
y=f(i=1∑nwixi+b)
其中:
- x i 是输入特征。 x_i 是输入特征。 xi是输入特征。
- w i 是权重。 w_i 是权重。 wi是权重。
- b 是偏置。 b 是偏置。 b是偏置。
- f 是激活函数。 f 是激活函数。 f是激活函数。
图1:感知机示意图
(图片描述:一个简单的感知机模型,包含输入节点、权重、偏置和激活函数。)
2. 多层感知机(MLP)
多层感知机由多个感知机组成,通常包括以下几层:
- 输入层:接收原始数据。
- 隐藏层:通过非线性变换提取特征。
- 输出层:生成预测结果。
每一层的输出作为下一层的输入,形成前向传播过程。
激活函数
激活函数为神经网络引入非线性能力,使其能够拟合复杂的数据分布。以下是几种常见的激活函数:
1. ReLU(Rectified Linear Unit)
公式:
f
(
x
)
=
max
(
0
,
x
)
f(x) = \max(0, x)
f(x)=max(0,x)
特点:计算简单,避免梯度消失问题。
2. Sigmoid
公式:
f
(
x
)
=
1
1
+
e
−
x
f(x) = \frac{1}{1 + e^{-x}}
f(x)=1+e−x1
特点:将输出压缩到 [0, 1] 区间,适用于概率输出。
3. Tanh
公式:
f
(
x
)
=
tanh
(
x
)
=
e
x
−
e
−
x
e
x
+
e
−
x
f(x) = \tanh(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}}
f(x)=tanh(x)=ex+e−xex−e−x
特点:将输出压缩到 [-1, 1] 区间,比 Sigmoid 更适合隐藏层。
图2:激活函数对比
(图片描述:折线图展示了 Sigmoid 、Tanh、ReLU和 Leaky ReLu 的形状,ReLU 和 Leaky ReLu 在正区间为线性增长,Sigmoid 和 Tanh 分别压缩到 [0, 1] 和 [-1, 1]。)
反向传播算法
反向传播是训练神经网络的核心算法,其目标是最小化损失函数。具体步骤如下:
- 前向传播:计算预测值。
- 计算损失:评估预测值与真实值之间的误差。
- 反向传播:根据链式法则计算梯度。
- 参数更新:使用梯度下降法更新权重和偏置。
公式如下:
Δ
w
=
−
η
∂
L
∂
w
\Delta w = -\eta \frac{\partial L}{\partial w}
Δw=−η∂w∂L
其中:
- η 是学习率。 \eta 是学习率。 η是学习率。
- L 是损失函数。 L 是损失函数。 L是损失函数。
使用 TensorFlow/Keras 构建简单的神经网络
Keras 是一个高级神经网络 API,支持快速构建和训练模型。我们使用 Keras 来实现一个多层感知机(MLP)。
实践部分:构建 MLP 解决 MNIST 手写数字识别问题
数据集简介
MNIST 数据集包含 70,000 张 28x28 像素的手写数字图像(0-9)。每张图像被展平为 784 维向量。目标是构建一个神经网络模型,能够准确识别手写数字。
完整代码
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten
from tensorflow.keras.utils import to_categorical
# 加载 MNIST 数据集
(X_train, y_train), (X_test, y_test) = mnist.load_data()
# 数据预处理
X_train = X_train.astype('float32') / 255.0 # 归一化到 [0, 1]
X_test = X_test.astype('float32') / 255.0
y_train = to_categorical(y_train, 10) # 将标签转换为 one-hot 编码
y_test = to_categorical(y_test, 10)
# 构建多层感知机模型
model = Sequential([
Flatten(input_shape=(28, 28)), # 展平输入图像
Dense(128, activation='relu'), # 隐藏层,128 个神经元,使用 ReLU 激活函数
Dense(64, activation='relu'), # 隐藏层,64 个神经元,使用 ReLU 激活函数
Dense(10, activation='softmax') # 输出层,10 个神经元,使用 Softmax 激活函数
])
# 编译模型
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
# 训练模型
history = model.fit(X_train, y_train, epochs=10, batch_size=128, validation_split=0.2)
# 评估模型
test_loss, test_accuracy = model.evaluate(X_test, y_test)
print(f"Test Accuracy: {test_accuracy:.2f}")
# 绘制训练过程中的损失和准确率曲线
plt.figure(figsize=(12, 5))
# 损失曲线
plt.subplot(1, 2, 1)
plt.plot(history.history['loss'], label='Training Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.title('Loss Curve', fontsize=16)
plt.xlabel('Epochs', fontsize=12)
plt.ylabel('Loss', fontsize=12)
plt.legend()
plt.grid()
# 准确率曲线
plt.subplot(1, 2, 2)
plt.plot(history.history['accuracy'], label='Training Accuracy')
plt.plot(history.history['val_accuracy'], label='Validation Accuracy')
plt.title('Accuracy Curve', fontsize=16)
plt.xlabel('Epochs', fontsize=12)
plt.ylabel('Accuracy', fontsize=12)
plt.legend()
plt.grid()
plt.show()
运行结果
输出结果
Test Accuracy: 0.97
训练过程可视化
图3:损失与准确率曲线
(图片描述:左侧子图展示了训练和验证损失随 epoch 的变化,右侧子图展示了训练和验证准确率的变化,两条曲线均趋于平稳。)
总结
本文介绍了神经网络的基本结构、激活函数和反向传播算法,并通过实践部分展示了如何使用 TensorFlow/Keras 构建一个多层感知机(MLP)来解决 MNIST 手写数字识别问题。希望这篇文章能帮助你更好地理解神经网络的基础知识!
下集预告:机器学习实战(10):深度学习初探——卷积神经网络(CNN)
参考资料
- TensorFlow 文档: https://www.tensorflow.org/
- MNIST 数据集: http://yann.lecun.com/exdb/mnist/