Keras 卷积神经网络识别手写数字 2021-07-10

Keras 卷积神经网络识别手写数字

一、卷积神经网络的简单介绍

  1. 多层感知器与卷积神经网络的主要区别:卷积神经网络增加了卷积层1、池化层1、卷积层2、池化层2的处理来提取特征。
  2. 卷积神经网络的介绍:
    2.1 图像的特征提取:通过卷积层1(16层)、池化层1(16层)、卷积层2(36层)、池化层2(36层)提取图像特征。
    2.2完全连接的神经网络:包括平坦层、隐藏层、输出层,所组成的类神经网络。
  3. 卷积运算:(1)、先以随机的方式产生,filter weight大小是33 。(2)、要转换的图像从左到右,自上而下,按序选取33的矩阵。(3)、图像选取的矩阵(33)与filter weight(33)乘积,计算产生第一行、第一列的数字。(4)、用用一个ff的过滤器卷积另一个nn的图像,padding的值为p,步幅为s,输出图像的大小为[(n+2p-f)/s]+1(如果不是整数,则向下取整)。
  4. 使用单个filter weight 卷积运算产生图像:卷积运算并不会改变图像大小,卷积后的效果很类似滤镜效果,这可以帮助我们提取输入的不同特征,例如边缘、线条和角等。
  5. 使用多个filter weight卷积运算产生多个图像:接下来,将随机产生16个filter weight,也就是16个滤镜。卷积运算使用16个滤镜(filter weight)产生16个图像,每个图像提取不同的特征。
  6. Max-Pool运算说明:成倍缩减,对图像缩减采样。
  7. 使用Max-Pool转换手写数字图像:使用Max-Pool缩减采样,进行手写数字图像转换,将16个2828的图像缩减为16个1414的图像,但是不会改变图像的数量(仍然是16个)。
    缩减采样会缩小图像,好处:(1)、减少需处理的数据点:减少后续运算所需的时间。(2)、让图像位置差异变小:例如手写数字7,位置上下左右可能不同,位置的不同可能会影响识别。减少图像大小,让数字的位置差异变小。(3)、参数的数量和计算量下降:这在一定程度上也控制了过度拟合。
  8. 建立卷积神经网络识别MNIST数据集的步骤:数据预处理,建立模型,训练模型,评估模型准确率,进行预测。

二、进行数据预处理

卷积神经网络与多层感知器进行数据预处理的方式不同

多层感知器 image.reshape(60000,784) 说明:多层感知器因为直接送进神经元处理,所以reshape转换为60000项,每一项有784个数字,作为784个神经元的输入

卷积神经网络 image.reshape(60000,28,28,1) 说明:卷积神经网络因为必须先进行卷积与池化运算,所以必须保持图像的位数,所以reshape转换为60000项,每一项是28281的图像,分别是28(宽)28(高)1(单色)

#步骤1、导入所需模块
from keras.datasets import mnist
from keras.utils import np_utils
import numpy as np
np.random.seed(10)
#步骤2、读取MNIST数据
(x_Train,y_Train),(x_Test,y_Test)=mnist.load_data()
#步骤3、将features(数字图像特征值)转换为四维矩阵(将features以reshape转换为60000*28*28*1的4维矩阵)
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')
#步骤4、将features(数字图像特征值)标准化(标准化可以提高模型预测的准确率,并且更快收敛)
x_Train4D_normalize=x_Train4D/255
x_Test4D_normalize=x_Test4D/255
#步骤5、label(数字真实值)以One-Hot Encoding进行转换(使用np_utils_categorical将训练数据与测试数据的label进行One-Hot Encoding(一位有效编码)转换
y_TrainOneHot=np_utils.to_categorical(y_Train)
y_TestOneHot=np_utils.to_categorical(y_Test)

三、建立模型

#步骤1、导入所需模块
import tensorflow as tf
from tensorflow import keras
from keras.models import Sequential
from keras.layers import Dense,Dropout,Flatten,Conv2D,MaxPooling2D
#步骤2、建立Keras的Sequential模型
model=tf.keras.Sequential()
#步骤3、建立卷积层1与池化层1(一个完整的卷积运算包含一个卷积层与一个池化层)
#建立卷积层1:
model.add(tf.keras.layers.Conv2D(filters=16,#建立16个滤镜
                 kernel_size=(5,5),#每个滤镜5*5大小
                 padding='same',#此设置让卷积运算产生的卷积运算图像大小不变
                 input_shape=(28,28,1),#第一、二维:代表输入的图像形状为28*28,第三维:因为是单色灰度图像,所以最后维数值是1
                 activation='relu'))#设置ReLU激活函数
#建立池化层1:
model.add(tf.keras.layers.MaxPool2D(pool_size=(2,2)))#输入参数pool_size=(2,2),执行第一次缩减采样,将16个28*28的图像缩小为16个14*14的图像
#步骤4、建立卷积层2与池化层2
#建立卷积层2:
model.add(tf.keras.layers.Conv2D(filters=36,
                                 kernel_size=(5,5),
                                 padding='same',
                                 activation='relu'))
#建立池化层2,并且加入Dropout避免过度拟合
model.add(tf.keras.layers.MaxPool2D(pool_size=(2,2)))
model.add(tf.keras.layers.Dropout(0.25))#把Dropout(0.25)层加入模型中,其功能是,每次训练迭代时,会随机在神经网络中放弃25%的神经元,以避免过度拟合。
#步骤5、建立神经网络(平坦层、隐藏层、输出层)
#建立平坦层(将36个7*7的图像转换为一维向量,长度是36*7*7=1764,也就是1764个float数)
model.add(tf.keras.layers.Flatten())
#建立隐藏层(共128个神经元)
model.add(tf.keras.layers.Dense(128,activation='relu'))
#把Dropout层加入模型中。(随机放弃x%的神经元,以避免过度拟合)
model.add(tf.keras.layers.Dropout(0.5))
#建立输出层(10个神经元,对于0-9共10个数字。使用softmax激活函数进行转换,softmax可以将神经元的输出转换为预测每一个数字的概率)
model.add(tf.keras.layers.Dense(10,activation='softmax'))
#步骤6、查看模型摘要
print(model.summary())

四、进行训练

#1、定义训练方式
model.compile(loss='categorical_crossentropy',
              optimizer='adam',
              metrics=['accuracy'])
#2、开始训练
train_history=model.fit(x=x_Train4D_normalize,#输入训练数据参数(features数字图像的特征值)
                       y=y_TrainOneHot,#输入训练数据参数(label数字图像真实的值)
                       validation_split=0.2,#80%作为训练数据,20%作为验证数据
                       epochs=10,#训练10个周期
                       batch_size=300,#每一批次训练300项数据(48000/300=160)
                       verbose=2)#显示训练过程
#3、show_train_history函数的实现
%matplotlib inline
import matplotlib.pyplot as plt
def show_train_history(train_history,train,validation):
    plt.plot(train_history.history[train])
    plt.plot(train_history.history[validation])
    plt.title('Train History')
    plt.ylabel(train)
    plt.xlabel('Epoch')
    plt.legend(['train','validation'],loc='upper left')
#4、画出准确率执行结果(每一个训练周期的准确率与误差记录在train_history中)
show_train_history(train_history,'accuracy','val_accuracy')

准确率执行结果

#5、画出误差执行结果
show_train_history(train_history,'loss','val_loss')

误差执行结果

五、评估模型准确率

scores=model.evaluate(x_Test4D_normalize,y_TestOneHot)
scores[1]

六、进行预测

#1、执行预测
prediction=np.argmax(model.predict(x_Test4D_normalize), axis=-1)
#2、预测结果
prediction[:10]
#3、plot_images_labels_prediction函数的实现
import matplotlib.pyplot as plt
def plot_images_labels_prediction(images,labels,prediction,idx,num=10):
    fig=plt.gcf()
    fig.set_size_inches(12,14)
    if num>25: num=25
        
    for i in range(0,num):
        ax=plt.subplot(5,5,1+i)
        ax.imshow(images[idx],cmap='binary')
        title='label='+str(labels[idx])
        if len(prediction)>0:
            title+=",predict="+str(prediction[idx])
            
        ax.set_title(title,fontsize=10)
        ax.set_xticks([])
        ax.set_yticks([])
        idx+=1
        
    plt.show()
#4、显示前10项预测结果
plot_images_labels_prediction(x_Test,y_Test,prediction,idx=10)

前十项的预测结果

七、显示混淆矩阵

#Pandas提供了建立混淆矩阵的功能
import pandas as pd
pd.crosstab(y_Test,prediction,#测试数字图像的预测结果
            rownames=['label'],colnames=['predict'])#设置行名称、列名称

混淆矩阵
*观察以上混淆矩阵的结果如下:

(1)、对角线是预测正确的数字,我们发现,真实值是“1”,被正确预测的概率最高,真实值为“5”被正确预测的概率最小。

(2)、其他非对角线的数字代表将某一个标签错误预测为另一个标签,我们发现真实值为“9”,但预测值为“4”的概率最大,也就是最容易混淆*

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值