全连接神经网络(FCN)在MNIST手写数字识别中的应用
2025-07-10 04:20:38作者:沈韬淼Beryl
概述
全连接神经网络(Fully Connected Neural Network, FCN)是最基础的神经网络结构之一,在TheAlgorithms-Python项目中提供了一个使用Keras实现FCN进行MNIST手写数字识别的完整示例。本文将详细解析这个实现,帮助读者理解FCN的工作原理及其在图像分类任务中的应用。
MNIST数据集简介
MNIST是一个经典的手写数字数据集,包含60,000张训练图像和10,000张测试图像,每张图像都是28×28像素的灰度图,代表0-9中的一个数字。
from keras.datasets import mnist
(X_train, Y_train), (X_test, Y_test) = mnist.load_data()
数据预处理
数据可视化
首先我们可以查看数据集中的部分样本:
import matplotlib.pyplot as plt
n = 10 # 显示10个数字
plt.figure(figsize=(20, 4))
for i in range(n):
ax = plt.subplot(2, n, i + 1)
plt.imshow(X_test[i].reshape(28, 28))
plt.gray()
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
plt.show()
数据重塑与归一化
FCN需要将二维图像展平为一维向量,并进行归一化处理:
X_train = X_train.reshape(60000, 784) # 28*28=784
X_test = X_test.reshape(10000, 784)
X_train = X_train.astype('float32')
X_test = X_test.astype('float32')
X_train /= 255 # 归一化到0-1范围
X_test /= 255
标签编码
将数字标签转换为one-hot编码:
from keras.utils import np_utils
classes = 10
Y_train = np_utils.to_categorical(Y_train, classes)
Y_test = np_utils.to_categorical(Y_test, classes)
构建全连接神经网络模型
网络结构
示例中构建了一个三层的FCN:
- 输入层:784个神经元(对应28×28像素)
- 隐藏层1:400个神经元,ReLU激活函数
- 隐藏层2:20个神经元,ReLU激活函数
- 输出层:10个神经元,Softmax激活函数(对应10个数字类别)
from keras.models import Sequential
from keras.layers.core import Dense, Activation
input_size = 784
hidden1 = 400
hidden2 = 20
classes = 10
model = Sequential()
model.add(Dense(hidden1, input_dim=input_size, activation='relu'))
model.add(Dense(hidden2, activation='relu'))
model.add(Dense(classes, activation='softmax'))
模型编译
使用分类交叉熵作为损失函数,SGD优化器:
model.compile(loss='categorical_crossentropy',
metrics=['accuracy'], optimizer='sgd')
model.summary()
模型训练
设置批量大小为200,训练10个epoch:
batch_size = 200
epochs = 10
model.fit(X_train, Y_train, batch_size=batch_size, epochs=epochs, verbose=2)
模型评估
在测试集上评估模型性能:
score = model.evaluate(X_test, Y_test, verbose=1)
print('\nTest accuracy:', score[1])
预测示例
可视化部分测试样本及其预测结果:
mask = range(10,20)
X_valid = X_test[mask]
y_pred = model.predict_classes(X_valid)
print(y_pred)
plt.figure(figsize=(20, 4))
for i in range(n):
ax = plt.subplot(2, n, i + 1)
plt.imshow(X_valid[i].reshape(28, 28))
plt.gray()
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
plt.show()
全连接神经网络的优缺点
优点
- 结构简单,易于理解和实现
- 对于小规模数据集表现良好
- 可以作为更复杂模型的基准
缺点
- 参数量大,容易过拟合
- 忽略了图像的空间局部性
- 对于大规模图像数据,不如卷积神经网络(CNN)高效
改进方向
- 使用更先进的优化器(如Adam)替代SGD
- 添加Dropout层防止过拟合
- 尝试不同的激活函数(如LeakyReLU)
- 使用学习率调度策略
- 增加网络深度或调整各层神经元数量
总结
TheAlgorithms-Python项目中的这个FCN实现展示了如何使用Keras构建一个基础的全连接神经网络来解决MNIST手写数字识别问题。虽然FCN不是图像分类任务的最优选择(CNN通常表现更好),但它仍然是理解神经网络工作原理的良好起点。通过调整网络结构和超参数,读者可以进一步探索神经网络的潜力。