上一次第一节的内容是采用基本的神经网络,多层感知机MLP进行手写数据集训练的,这次准备搭建卷积神经网络对MNIST手写数据集进行特征提取,之后在送到MLP中进行训练,关于之前提到的内容这边就不再叙述,如果有对这节部分代码内容有疑问的朋友们可以查看下我博客里第一节的内容。
一.MNIST的数据预处理
1.这里数据的导入部分和之前的一样,唯一不同的是数据集的reshape部分。因为这次使用的是卷积神经网络来提取特征进行识别(卷积神经网络部分可参考网上其它博客,有很多教程),卷积网络因为必须先进行卷积与池化运算,所以必须保持图像的维数。
2.导入相关第三方库
import tensorflow as tf
from tensorflow.keras import layers
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
3.读取MNIST的手写数据
(x_train,y_train),(x_test,y_test) = tf.keras.datasets.mnist.load_data()
4.将图像转为4维矩阵,使其满足卷积神经网络输入要求,其中第一维为batch_size,第二维第三维为图片大小,第四维为图片通道数,因为这里的图像是单色灰度图像,所以值为1,如果是彩色图像,则为3。
#shape[0]代表的就是batch_size
x_train4D = x_train.reshape(x_train.shape[0],28,28,1).astype('float32')
x_test4D = x_test.reshape(x_test.shape[0],28,28,1).astype('float32')
5.对图像进行进行标准化,使取值范围在[0,1]之间。
x_train4D_normalize = x_train4D/255
x_test4D_normalize = x_test4D/255
6.对图像标签进行One-Hot编码(独热编码)。
y_trainOneHot = tf.keras.utils.to_categorical(y_train)
y_testOneHot = tf.keras.utils.to_categorical(y_test)
二.模型的搭建
1.建立Sequential线性堆叠模型。
#建立线性堆叠模型
model = tf.keras.models.Sequential()
2.模型结构:2层卷积层(提取特征)+2层最大池化层(减小图片大小)+1层Dropout层(防止过拟合)+1层平坦层(将提取的所有特征转为一维向量)+ 两层全连接层。
这里蛮提一下池化的作用:/ 减少需要处理的图像数据点,减少运算时间 / 减少图片之间位置的差异 / 参数量减少有益于控制过拟合。
Dropout层主要为了防止过拟合,具体内容上一节有提到。
而平坦层Flatten则是将卷积池化后的所有特征转化为一维向量,以便于神经网络可以输入。
#filter等于是滤镜,对原图像提取生成16个的特征图像,比如有的滤镜是提取边缘,有的提取的是别的特征。kernel_size则是卷积核大小,padding='same'的意思是,卷积层的输出大小与原图像大小一样,用0值补全。
model.add(layers.Conv2D(filters=16,kernel_size=(5,5),padding='same',input_shape=(28,28,1),activation='relu'))
model.add(layers.MaxPooling2D(pool_size=(2,2))) #最大池化,此时图像大小为14x14
model.add(layers.Conv2D(filters=32,kernel_size=(5,5),padding='same',activation='relu'))
model.add(layers.MaxPooling2D(pool_size=(2,2))) #此时图像大小为7x7
model.add(layers.Dropout(0.3)) #使百分30的神经元失活
model.add(layers.Flatten()) #转一维向量输入
model.add(layers.Dense(128,activation='relu'))
model.add(layers.Dropout(0.5)) #使百分50神经元失活
model.add(layers.Dense(10,activation='softmax'))
3.模型概要查看
print(model.summary())
三.模型的训练
1.相关参数设置及训练,具体参数意义可参照上节内容。
model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy'])
train_history = model.fit(x=x_train4D_normalize,y=y_trainOneHot,validation_split=0.2,epochs=5,batch_size=300,verbose=2)
2.查看参数保存内容。
print(train_history.history)
3.调用上节编写的show_train_history函数查看曲线变化。
show_train_history(train_history,'accuracy','val_accuracy')
四.模型的预测
1.用测试集进行预测。
scores = model.evaluate(x_test4D_normalize,y_testOneHot)
print(scores[1])
prediction = model.predict_classes(x_test4D_normalize)
print(prediction[:10]) #显示前10个数字预测结果
2.调用pandas的混淆矩阵查看结果。
pd.crosstab(y_test,prediction,rownames=['label'],colnames=['predict'])
以上是这一节的笔记和内容,下节会对更难一点的CIFAR-10的10类彩色图像进行识别分类。谢谢大家的观看支持。