基于MLP完成CIFAR-10数据集和UCI wine数据集的分类,使用到了sklearn和tensorflow,并对图片分类进行了数据可视化展示
数据集介绍
UCI wine数据集:
http://archive.ics.uci.edu/dataset/109/wine
这些数据是对意大利同一地区种植的葡萄酒进行化学分析的结果,但来自三个不同的品种。该分析确定了三种葡萄酒中每一种中发现的13种成分的数量。
CIFAR-10数据集:
https://www.cs.toronto.edu/~kriz/cifar.html
CIFAR-10 数据集由 10 类 60000 张 32x32 彩色图像组成,每类 6000 张图像。有 50000 张训练图像和 10000 张测试图像。
数据集分为 5 个训练批次和 1 个测试批次,每个批次有 10000 张图像。测试批次正好包含从每个类中随机选择的 1000 张图像。训练批次以随机顺序包含剩余的图像,但某些训练批次可能包含来自一个类的图像多于另一个类。在它们之间,训练批次正好包含来自每个类的 5000 张图像
MLP算法
MLP 代表多层感知器(Multilayer Perceptron),是一种基本的前馈神经网络(Feedforward Neural Network)模型。它由一个输入层、一个或多个隐藏层和一个输出层组成,其中每个层都包含多个神经元(或称为节点)。MLP 是一种强大的模型,常用于解决分类和回归问题。
MLP 的基本组成部分如下:
- 输入层(Input Layer): 接收原始数据的输入层,每个输入节点对应输入特征。
- 隐藏层(Hidden Layer):
位于输入层和输出层之间的一层或多层神经元。每个神经元通过权重与前一层的所有节点相连接,并通过激活函数进行非线性变换。隐藏层的存在使得网络能够学习输入数据的复杂特征。 - 输出层(Output Layer): 提供最终的网络输出。对于不同的问题,输出层的激活函数可能不同。例如,对于二分类问题,可以使用
sigmoid 激活函数;对于多分类问题,可以使用 softmax 激活函数。
模型构建
UCI wine:
我们加载 sklearn.datasets 中的 load_wine作为训练数据,划分为数据集和测试集,并进行标准化操作
接着调用 MLPClassifier(hidden_layer_sizes=(100,), max_iter=1000, random_state=42) 创建模型
训练后在测试集上预测,最后评估模型
from sklearn.neural_network import MLPClassifier from sklearn.datasets import load_iris from sklearn.datasets import load_wine from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score, classification_report, confusion_matrix from sklearn.preprocessing import StandardScaler # 加载Iris数据集 # iris = load_iris() # X = iris.data # y = iris.target wine = load_wine() X = wine.data y = wine.target # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 数据标准化 scaler = StandardScaler() X_train_scaled = scaler.fit_transform(X_train) X_test_scaled = scaler.transform(X_test) # 构建MLP模型 mlp = MLPClassifier(hidden_layer_sizes=(100,), max_iter=1000, random_state=42) # 训练模型 mlp.fit(X_train_scaled, y_train) # 在测试集上进行预测 y_pred = mlp.predict(X_test_scaled) # 评估模型性能 accuracy = accuracy_score(y_test, y_pred) conf_matrix = confusion_matrix(y_test, y_pred) class_report = classification_report(y_test, y_pred) # 打印结果 print("Accuracy:", accuracy) print("\nConfusion Matrix:\n", conf_matrix) print("\nClassification Report:\n", class_report)
CIFAR-10:
我们使用 tf.keras.datasets.cifar10中自带的数据进行训练
使用 tf.keras.Sequential() 这个函数创建模型,设置四层网络
接着对代码进行批量训练,评估和保留模型后对结果进行可视化处理
########cifar10数据集########## ###########保存模型############ ########卷积神经网络########## #train_x:(50000, 32, 32, 3), train_y:(50000, 1), test_x:(10000, 32, 32, 3), test_y:(10000, 1) #60000条训练数据和10000条测试数据,32x32像素的RGB图像 #第一层两个卷积层16个3*3卷积核,一个池化层:最大池化法2*2卷积核,激活函数:ReLU #第二层两个卷积层32个3*3卷积核,一个池化层:最大池化法2*2卷积核,激活函数:ReLU #隐含层激活函数:ReLU函数 #输出层激活函数:softmax函数(实现多分类) #损失函数:稀疏交叉熵损失函数 #隐含层有128个神经元,输出层有10个节点 import tensorflow as tf import matplotlib.pyplot as plt import numpy as np import time print('--------------') nowtime = time.strftime('%Y-%m-%d %H:%M:%S') print(nowtime) #指定GPU #import os #os.environ["CUDA_VISIBLE_DEVICES"] = "0" # gpus = tf.config.experimental.list_physical_devices('GPU') # tf.config.experimental.set_memory_growth(gpus[0],True) #初始化 plt.rcParams['font.sans-serif'] = ['SimHei'] #加载数据 cifar10 = tf.keras.datasets.cifar10 (train_x,train_y),(test_x,test_y) = cifar10.load_data() print('\n train_x:%s, train_y:%s, test_x:%s, test_y:%s'%(train_x.shape,train_y.shape,test_x.shape,test_y.shape)) #数据预处理 X_train,X_test = tf.cast(train_x/255.0,tf.float32),tf.cast(test_x/255.0,tf.float32) #归一化 y_train,y_test = tf.cast(train_y,tf.int16),tf.cast(test_y,tf.int16) #建立模型 model = tf.keras.Sequential() ##特征提取阶段 #第一层 model.add(tf.keras.layers.Conv2D(16,kernel_size=(3,3),padding='same',activation=tf.nn.relu,data_format='channels_last',input_shape=X_train.shape[1:])) #卷积层,16个卷积核,大小(3,3),保持原图像大小,relu激活函数,输入形状(28,28,1) model.add(tf.keras.layers.Conv2D(16,kernel_size=(3,3),padding='same',activation=tf.nn.relu)) model.add(tf.keras.layers.MaxPool2D(pool_size=(2,2))) #池化层,最大值池化,卷积核(2,2) #第二层 model.add(tf.keras.layers.Conv2D(32,kernel_size=(3,3),padding='same',activation=tf.nn.relu)) model.add(tf.keras.layers.Conv2D(32,kernel_size=(3,3),padding='same',activation=tf.nn.relu)) model.add(tf.keras.layers.MaxPool2D(pool_size=(2,2))) ##分类识别阶段 #第三层 model.add(tf.keras.layers.Flatten()) #改变输入形状 #第四层 model.add(tf.keras.layers.Dense(128,activation='relu')) #全连接网络层,128个神经元,relu激活函数 model.add(tf.keras.layers.Dense(10,activation='softmax')) #输出层,10个节点 print(model.summary()) #查看网络结构和参数信息 #配置模型训练方法 #adam算法参数采用keras默认的公开参数,损失函数采用稀疏交叉熵损失函数,准确率采用稀疏分类准确率函数 model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['sparse_categorical_accuracy']) #训练模型 #批量训练大小为64,迭代5次,测试集比例0.2(48000条训练集数据,12000条测试集数据) print('--------------') nowtime = time.strftime('%Y-%m-%d %H:%M:%S') print('训练前时刻:'+str(nowtime)) history = model.fit(X_train,y_train,batch_size=64,epochs=5,validation_split=0.2) print('--------------') nowtime = time.strftime('%Y-%m-%d %H:%M:%S') print('训练后时刻:'+str(nowtime)) #评估模型 model.evaluate(X_test,y_test,verbose=2) #每次迭代输出一条记录,来评价该模型是否有比较好的泛化能力 #保存整个模型 model.save('CIFAR10_CNN_weights.h5') #结果可视化 print(history.history) loss = history.history['loss'] #训练集损失 val_loss = history.history['val_loss'] #测试集损失 acc = history.history['sparse_categorical_accuracy'] #训练集准确率 val_acc = history.history['val_sparse_categorical_accuracy'] #测试集准确率 plt.figure(figsize=(10,3)) plt.subplot(121) plt.plot(loss,color='b',label='train') plt.plot(val_loss,color='r',label='test') plt.ylabel('loss') plt.legend() plt.subplot(122) plt.plot(acc,color='b',label='train') plt.plot(val_acc,color='r',label='test') plt.ylabel('Accuracy') plt.legend() #暂停5秒关闭画布,否则画布一直打开的同时,会持续占用GPU内存 #根据需要自行选择 #plt.ion() #打开交互式操作模式 #plt.show() #plt.pause(5) #plt.close() #使用模型 plt.figure() for i in range(10): num = np.random.randint(1,10000) plt.subplot(2,5,i+1) plt.axis('off') plt.imshow(test_x[num],cmap='gray') demo = tf.reshape(X_test[num],(1,32,32,3)) y_pred = np.argmax(model.predict(demo)) plt.title('标签值:'+str(test_y[num])+'\n预测值:'+str(y_pred)) #y_pred = np.argmax(model.predict(X_test[0:5]),axis=1) #print('X_test[0:5]: %s'%(X_test[0:5].shape)) #print('y_pred: %s'%(y_pred)) #plt.ion() #打开交互式操作模式 plt.show() #plt.pause(5) #plt.close()