2021-06-01 Keras 多元感知器识别MNIST手写数字

Keras 多元感知器识别MNIST手写数字

一、进行数据预处理

  1. 导入所需的模块
#步骤1、导入所需模块
from keras.utils import np_utils
import numpy as np
np.random.seed(10)#设置seed可以产生的随机数据
  1. 读取MNIST数据
#步骤2、读取MNIST数据
from keras.datasets import mnist
(x_train_image,y_train_label),(x_test_image,y_test_label)=mnist.load_data()
  1. 用reshape处理features
#步骤3、将features(数字图像特征值)使用reshape转换(将原本28*28的数字图像以reshape转换成784个float数)
x_Train=x_train_image.reshape(60000,784).astype('float32')
x_Test=x_test_image.reshape(10000,784).astype('float32')
  1. 将features标准化
#步骤4、将features(数字图像特征值)标准化(标准化可以提高模型预测的准确度,并且更快收敛)
x_Train_normalize=x_Train/255
x_Test_normalize=x_Test/255
  1. 将label转换为One-Hot Encoding
#步骤5、label(数字真实的值)以One-Hot Encoding 进行转换(使用np_utils.to_categorical将训练和测试的数据的label进行转换)
y_Train_OneHot=np_utils.to_categorical(y_train_label)
y_Test_OneHot=np_utils.to_categorical(y_test_label)

二、建立模型
1、导入所需模块

#步骤1、导入所需模块
import tensorflow as tf
from tensorflow import keras
from keras.models import Sequential
from keras.layers import Dense

2、建立Sequence模型

#步骤2、建议Sequential模型
model=tf.keras.Sequential()

3、建立“输入层”和“隐藏层”

#步骤3、建立“输入层”与“隐藏层”
model.add(tf.keras.layers.Dense(
                units=256,#定义“隐藏层”神经元个数为256
                input_dim=784,#设置“输入层”神经元个数为784(因为原本28*28的二维图像,以reshape转换为一维的向量,也就是784个float数)
                kernel_initializer='normal',#使用normal distribution 正态分布的随机数来初始化 weight (权重)和bias(偏差)
                activation='relu'))#定义激活函数为relu

4、建立“输出层”

#步骤4、建立“输出层”
model.add(tf.keras.layers.Dense(units=10,#定义“输出层”神经元个数为10
                                kernel_initializer='normal',#使用normal distribution 正态分布的随机数来初始化weight与bias
                                activation='softmax'#定义激活函数为softmax
                               ))

5、查看模型摘要

#步骤5、查看模型的摘要
print(model.summary())

模型摘要
模型摘要说明:查看模型的摘要Param(以上每一层的Param都是超参数(Hyper-Parameters)我们需要通过反向传播算法更新神经元连接的权重与偏差)
1、建立输入层与隐藏层的公式:h1=relu(xw1+b1)
2、建立隐藏层与输出层的公式:y=softmax(h1w2+b2)
3、每一层的Param计算方式:Param=(上一层神经元数量)(本层的神经元数量)+(本层的神经元数量) ·
3.1、隐藏层的Param是200960:784256+256 ·
3.2、输出层的Param是2570:256
10+10 所以全部必须训练的超参数(Train Params)是每一层的Param的总和,计算方法:输入层+隐藏层+输出层(200960+65792+2570)。通常Trainable Param 数值越大,代表此模型越复杂,需要更多时间进行训练*
三、进行训练
1、定义训练方式

#1、定义训练方式
model.compile(loss='categorical_crossentropy',#loos:设置损失函数,在深度学习中使用cross_entropy(交叉熵)训练的效果比较好
              optimizer='adam',#optimizer:设置训练时,在深度学习中使用adam优化器可以让训练更快收敛,并提高准确率
              metrics=['accuracy'])#metrics:设置评估模型的方法是准确率

2、开始训练

#2、开始训练(使用model.fit进行训练,训练过程会存储在train_history变量中)
train_history=model.fit(x=x_Train_normalize,#输入训练数据参数(features数字图像的特征值)
                        y=y_Train_OneHot,#label数字图像真实的值
                        validation_split=0.2,#设置训练与验证数据比例。训练之前Keras会自动将数据分成:80%作为训练数据,20%作为验证数据。训练数据:60000*0.8=48000 验证数据:60000*0.2=12000
                        epochs=10,#设置epoch(训练周期)次数与每一批次项数。epoch=10:执行10个训练周期
                        batch_size=200,#每一批次200项数据(48000/200=240)
                        verbose=2)#显示训练过程

注:训练的误差越来越小,准确率越来越高,这样的模型才是可用的
3、显示训练过程图像

#3、建立show_train_history显示训练过程(之前的训练步骤会将每一个训练周期的准确率与误差记录在train_history变量中,可以写函数以图表显示训练过程)
#%matplotlib inline #设置matplotlib在jupyter note网页内显示图形,如果没有这个指令,就会另开一个窗口显示图形
import matplotlib.pyplot as plt#导入matplotlib.pyplot模块,后续会使用plt来引用
def show_train_history(train_history,train,validation):#定义show_train_history函数,输入参数:之前训练过程所产生的train_history,训练数据的执行结果,验证数据的执行结果
    plt.plot(train_history.history[train])
    plt.plot(train_history.history[validation])
    plt.title('Train History')#显示图的标题
    plt.ylabel(train)#显示y轴的标签
    plt.xlabel('Epoch')#设置x轴标签是'Epoch'
    plt.legend(['train','validation'],loc='upper left')#设置图例是显示'train''validation',位置在左上角
    plt.show()

4、画出准确率的执行结果

#4、画出准确率执行结果
show_train_history(train_history,'accuracy','val_accuracy')

准确率的执行结果
*图表分析:
1、“训练的准确率”比“验证的准确率”要高
2、无论是训练还是验证,准确率都越来越高
3、在epoch训练后期,“accuracy训练的准确率”比“val_accuracy验证的准确率高

原因:计算准确率的数据不同

accuracy训练的准确率:以训练的数据来计算准确率,因为相同的数据已经训练过了,又拿来计算准确率,所以准确率比较高

val_accuracy验证的准确率:以验证数据来计算准确率,这些验证数据在之前训练时并未拿来训练,所以计算的准确率会比较低,但是,这样计算出来的准确率会比较客观,比较符合真实情况。

如果“accuracy训练的准确率”一直增加,但是“val_accuracy验证的准确率”一直没有增加,就可能是过拟合(overfitting)的现象

过拟合现象: 训练过程太久或者范例太少会导致虚线过度适应训练数据中特化且随机的特征。其结果是虽然在训练时准确率高,但是使用未知数据时的准确率低。

以测试数据评估模型准确率:在完成所有训练周期后,我们还会以测试数据评估模型准确率,这是另一组独立的数据,所以计算准确率会更客观。*
5、画出误差执行结果

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

误差执行结果
由图可知:
1、无论是训练还是验证,验证的误差都越来越低
2、在Epoch训练后期,“loss训练的误差”比“val_loss验证 的误差”小

四、以测试数据评估模型准确率
1、评估模型准确率

#步骤1、评估模型准确率
scores=model.evaluate(x_Test_normalize,y_Test_OneHot)
print()
print('accuracy=',scores[1])

*程序代码说明:

#1、scores=model.evaluate(—>使用model.evaluate 评估模型的准确率,评估后的准确率会存储在scores中

#2、x=x_Test_normalize,----->测试数据的features(数字图像的特征值)

#3、y=y_Test_OneHot)-------->测试数据的label(数字图像真实的值)

#4、print(‘accuracy=’,scores[1])----->显示准确率*
五、进行预测
1、执行预测

#1、执行预测
prediction=np.argmax(model.predict(x_Test), axis=-1)

2、预测结果

#2、预测结果(预测结果的前10项数据)
prediction[:10]

3、创建函数显示预测结果

#创建plot_images_labels_prediction()函数
import matplotlib.pyplot as plt #导入pyplot模块,后续会使用plt来引用
def plot_images_labels_prediction(images,labels,prediction,idx,num=10):#定义plot_images_labels_prediction()函数(参数:images(数字图像)、label(真实值)、prediction(预测结果)、idx(开始显示的数据index)、num(要显示的数据项数,默认是10,不超过25))
    fig=plt.gcf()             #设置显示图形大小
    fig.set_size_inches(12,14)#设置显示图形大小
    if num>25:#如果显示项数参数大于25,就设置为25,以免发生错误
        num=25
        pass
    for i in range(0,num):#for循环执行程序块内的程序代码,画出num个数字图形
        ax=plt.subplot(5,5,1+i)#建立subgraph 子图形为5行5列
        ax.imshow(images[idx],cmap='binary')#画出subgraph 子图形
        title="label="+str(labels[idx])#设置子图形title,显示便签(label)字段
        if len(prediction)>0:#如果传入了预测结果
            title+=",predict="+str(prediction[idx])#标题 title加入预测结果
            pass
        ax.set_title(title,fontsize=10)#设置子图形的标题 title与大小
        ax.set_xticks([]);ax.set_yticks([])#设置不显示刻度
        idx+=1#读取下一项
        pass
    plt.show()

4、显示前10项预测结果

#3、显示10项预测结果(使用plot_images_labels_prediction函数显示预测结果,输入参数:x_test_image(测试数据图像)、y_test_label(测试数据真实的值)、prediction(预测结果)和idx=340(显示第340到349共10项))。
plot_images_labels_prediction(x_test_image,y_test_label,prediction,idx=340)

六、显示混淆矩阵
*如果我们想要进一步知道在所建立的模型中哪些数字的预测准确率最高,哪些数字最容易混淆,就可以使用混淆矩阵来显示

在机器学习领域,特别是统计分类的问题,混淆矩阵也称为误差矩阵,是一种特定的表格显示方式,可以让我们以可视化的方式了解有监督学习算法的结果,看出算法模型是否混淆了两个类(将某一个标签预测成为另一个标签)*
1、建立混淆矩阵

#1、使用pandas crosstab 建立混淆矩阵
import pandas as pd#导入pandas模块,后续会以pd来引用
pd.crosstab(y_test_label,prediction,rownames=['label'],colnames=['predict'])
#使用pd.crosstab 建立混淆矩阵,输入参数:测试数据数字图像的真实值、测试数据数字图像的预测结果、设置行的名称是label、设置列的名称是predict

混淆矩阵
*###从混淆矩阵中,可得出结果:

#1、对角阵是预测正确的数字,我们发现:真实值是“1”,被正确预测为“1”的项数有1124项,预测准确率最高,最不容易混淆。真实值是“5”,被正确预测为“5”的项数有861项最低,也就是说最容易混淆。

#2、其他非对角线的数字代表将某一个标签预测错误,成为另一个标签,我们发现:真实值是“5”,但是预测值是“3”*
2、建立真实值与预测DataFrame

#2、建立真实值与预测DataFrame(找出真实值是"5",但预测值是"3"的数据)
df=pd.DataFrame({'label':y_test_label,'predict':prediction})
df[:2]

3、查询真实值是“5”但预测值是“3”的数据

#3、查询真实值是“5”但预测值是“3”的数据(DataFrame 可以很方便地让我们查询数据)
df[(df.label==5)&(df.predict==3)]

4、查看第340项数据

#4、查看第340项数据
plot_images_labels_prediction(x_test_image,y_test_label,prediction,idx=340,num=1)

查看数据就可以知道为什么模型把它给识别错误的原因了
总结
1、为了增加模型精度可以把隐藏层增加为1000个神经元
2、可以加入Dropout功能,避免过度拟合

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值