0、前言
关于神经网络和卷积神经网络的理论部分,我在前面写了两篇博客已经详细介绍了:
这里也就不再重复造轮子,这篇旨在借着人工智能实验,了解一下python里sklearn
这个机器学习库,当然神经网络部分都是直接封装好的,直接调用就好,看看如何在应用方面,调用库来训练一个模型,来进行预测。
一、实验目的
(1)探究多层神经网络在模式分类识别任务中的有效性和适用性。
(2)利用多层神经网络对手写体数字进行识别,评估网络在处理高维度、高复杂度的模式识别问题时的准确度和泛化能力。
(3)了解多层神经网络程序的程序框架与处理流程,同时,掌握多层神经网络的训练技巧,包括比较不同网络结构(如层数、神经元数量等)和不同训练参数(如学习率、迭代次数等)对分类性能的影响,从而优化网络结构。
二、概要设计
-
本次实验采用多层神经网络(MLP)作为机器学习算法,如下图,神经网络的设计思想就是通过模拟人脑中神经元的连接以及电信号的传输。
其基本原理是通过多个神经元层的组合,实现对输入数据的非线性映射和特征学习。MLP包括输入层、隐藏层和输出层,通过前向传播和反向传播两个阶段进行训练,其中前向传播用于计算输出值,反向传播用于更新网络参数以减小预测误差。通过梯度下降法优化损失函数,不断调整网络参数以提高模型性能。
-
数据集介绍:
- 使用的数据集是MNIST手写数字数据集,包含60000个训练样本和10000个测试样本。
- 每个样本都是由28x28像素组成的图像,表示手写数字0到9。
- 特征属性为图像像素的灰度值,标签为对应的手写数字。
- 数据来源是MNIST数据库,被广泛用于测试机器学习算法的性能。
-
程序流程
- 数据加载与预处理:将MNIST数据集加载到程序中,并进行预处理,如归一化处理、数据集划分等。
- 网络构建:设计多层神经网络结构,包括输入层、隐藏层和输出层,确定神经元数量、激活函数等。
- 模型训练:使用训练集对神经网络进行训练,通过反向传播算法更新网络参数,优化损失函数。
- 模型评估:使用测试集评估模型的性能,包括准确率、混淆矩阵等指标。
- 参数调优:根据实验结果,调整网络结构和训练参数,优化模型性能。
三、详细设计(实现代码)
1.数据加载与预处理:
- 首先,通过文件路径指定训练集和测试集的标签文件路径,利用
os.path.join()
函数拼接路径字符串。 - 读取训练集的标签数据,使用
open()
函数以二进制只读方式打开文件,然后使用struct.unpack()
函数解析文件头,获取魔数和样本数量等信息。 - 将标签数据读入到
y_train
变量中,使用np.fromfile()
函数将文件中的二进制数据转换成NumPy数组。 - 读取训练集的图像数据,同样使用
open()
函数打开文件,解析文件头获取图像的相关信息。 - 使用
np.fromfile()
函数读取图像数据,得到二维数组images
,再通过reshape将其整形成合适的形状,保存在X_train
中。 - 进行数据归一化处理,将像素值从0-255缩放到-1到1之间,以便神经网络更好地处理数据。
- 打印出训练集和测试集的样本数量
import os
import struct
import numpy as np
from sklearn.neural_network import MLPClassifier
from sklearn.metrics import classification_report
import matplotlib.pyplot as plt
path = ''
'''读入训练集的标签'''
train_labels_path = os.path.join(path, 'train-labels.idx1-ubyte')
lbpath = open(train_labels_path, 'rb')
magic, n = struct.unpack('>II', lbpath.read(8))#读取缓存中的前8个字节,相当于前0-7个字节是说明性文中,与具体标签无关
y_train = np.fromfile(lbpath, dtype=np.uint8)#把缓存中的标签数据直接转成np数据格式并保存到labels变量中
'''读入训练集的数据'''
train_images_path = os.path.join(path, 'train-images.idx3-ubyte')
imgpath = open(train_images_path, 'rb')
magic, num, rows, cols = struct.unpack(">IIII", imgpath.read(16))# '>I'表示以4字节位单位,读取缓存中的前16个字节,需要读取4次,所以用4个I
images = np.fromfile(imgpath, dtype=np.uint8).reshape(len(y_train), 784)#reshape(len(labels), 784)相当于把一维数组整形成二维数组,
X_train = ((images / 255.) - .5) * 2 # 此处的归一化,变成一个取值为从[-1,+1]的数,归一化并不影响结果,原因是只有一个属性“像素值”
# 统计训练集中标签为1的个数
ones_count = np.count_nonzero(y_train == 1)
print(f"训练集中数字为1的个数: {ones_count}")
print('Train:Rows: %d, columns: %d' % (X_train.shape[0], X_train.shape[1]))#打印数据形状
'''读入测试集的标签'''
test_labels_path = os.path.join(path, 't10k-labels.idx1-ubyte')
with open(test_labels_path, 'rb') as lbpath:
magic, num = struct.unpack('>II', lbpath.read(8))
y_test = np.fromfile(lbpath, dtype=np.uint8)
'''读入测试集的数据'''
test_images_path = os.path.join(path, 't10k-images.idx3-ubyte')
with open(test_images_path, 'rb') as imgpath:
magic, num, rows, cols = struct.unpack(">IIII", imgpath.read(16))
test_images = np.fromfile(imgpath, dtype=np.uint8).reshape(len(y_test), 784)
X_test = ((test_images / 255.) - .5) * 2
print('Test:Rows: %d, columns: %d' % (X_test.shape[0], X_test.shape[1]))#打印数据形状
2.神经网络模型构建
- 创建了一个多层感知机模型(MLPClassifier),其中隐藏层的结构是(100, 50),使用relu激活函数(activation=‘relu’),最大迭代次数为300。
mlp = MLPClassifier(hidden_layer_sizes=(100, 70, 40), activation='logistic', max_iter=150)
3.训练和测试:
- 调用
mlp.fit()
方法对模型进行训练,传入训练集的特征数据X_train
和对应的标签y_train
。 - 利用训练好的模型对测试集进行预测,调用
mlp.predict()
方法,传入测试集特征数据X_test
,得到预测结果predictions
。 - 使用
classification_report()
函数输出模型的性能评估报告,包括精确率、召回率、F1-score等指标,以及每个类别的表现情况。
# 训练
mlp.fit(X_train, y_train)
# 使用模型对测试数据进行预测
predictions = mlp.predict(X_test)
# 输出模型的性能评估
print(classification_report(y_test, predictions))