当前位置:   article > 正文

一、keras CNN卷积神经网络------搭建mnist手写数字识别网络_使用keras构建和训练卷积神经网络,实现对mnist手写数字数据集的识别,并测试模型性

使用keras构建和训练卷积神经网络,实现对mnist手写数字数据集的识别,并测试模型性

MNIST是一个手写体数字的图片数据集,包含 7 万张黑底白字手写数字图片,每张图片大小为 28x28 像素,图片中纯黑色像素值为 0,纯白色像素值为 1;数据集的标签是长度为 10 的一维数组。该数据集来由美国国家标准与技术研究所[ National Institute of Standards and Technology (NIST) ] 发起整理,一共统计了来自250个不同的人手写数字图片(其中50%是高中生,50%来自人口普查局的工作人员)。

该数据集包括训练集(一共包含了 60,000 张图像和标签)和测试集(一共包含了 10,000 张图像和标签)。该数据集的收集目的是希望通过算法,实现对手写数字的识别。

目录

1. 首先我们先导入需要的库

2.下载手写数据集

3.图形化数据集(查看前10个数据集)

4.数据预处理

5.建立模型

6.训练模型

7.查看、评估和预测模型

8.总代码


在开始之前我们先了解:CNN结构

1. 首先我们先导入需要的库

这里我们使用的是keras版本是2.15.0,所以我们这样导入我们需要的库

from keras.utils import to_categorical

如果是旧版本,导入的是:from keras.utils import np_utils

  1. from keras.datasets import mnist
  2. #from keras.utils import np_utils#旧版本
  3. from keras.utils import to_categorical#2.15.0版本以上
  4. import numpy as np
  5. import matplotlib.pyplot as plt
  6. from keras.models import Sequential
  7. from keras.layers import Dense,Dropout,Flatten,Conv2D,MaxPooling2D

2.下载手写数据集

函数load_data()会返回两个元组,每个元组中包含两个数组。x_train和x_test是图像数据,y_train和y_test是对应的标签

  1. (x_Train,y_Train),(x_Test,y_Test)=mnist.load_data()
  2. print('x_Train:',x_Train.shape)
  3. print('y_Train:',y_Train.shape)
  4. print('x_Test:',x_Test.shape)
  5. print('y_Test:',y_Test.shape)

3.图形化数据集(查看前10个数据集)

  1. ''' 图形化数据集,查看前10个数据集'''
  2. def polt_images_label_prediction(images,labels,idx,num=10):
  3. fig=plt.gcf()
  4. fig.set_size_inches(12,14)#创建一个画布12x14
  5. for i in range(num):
  6. ax=plt.subplot(5,2,1+i)#在之前的画布上创建 5 行 2 列的子图网格
  7. ax.imshow(images[idx],cmap='binary')
  8. title='label='+str(labels[idx])
  9. ax.set_title(title,fontsize=10)
  10. ax.set_xticks([])#移除当前子图的xy轴刻度线
  11. ax.set_yticks([])
  12. plt.show()
  13. polt_images_label_prediction(x_Train,y_Train,0)

输出结果如下: 

 

4.数据预处理

  1. ''' 数据预处理:
  2. 将features以reshape转化为6000*28*28*1的4维矩阵,并将其标准化。'''
  3. x_Train4D=x_Train.reshape(x_Train.shape[0],28,28,1).astype('float32')#图像的数量、宽、高和通道数(因为是灰度图,所以通道数为1)
  4. x_Test4D = x_Test.reshape(x_Test.shape[0], 28, 28, 1).astype('float32')#将数据类型转换为32位浮点数
  5. x_Train4D_normalize = x_Train4D / 255#将图像数据进行标准化,因为原始的MNIST图像数据的像素值是介于0到255之间的整数(表示灰度值),所以除以255可以将它们标准化到0到1之间
  6. x_Test4D_normalize = x_Test4D / 255
  1. ''' 对标签进行one-hot编码处理 '''
  2. #未转化第一个数是 5
  3. print('未转化第一个数是 5:',y_Train[:1])#以原始形式打印出y_Train的第一个标签
  4. y_TrainOneHot = to_categorical(y_Train)#转换为one-hot编码格式。每个标签都被转换为一个二进制向量,其中只有一个元素是1,其余元素都是0。例如,如果一个标签是5,那么它将被转换为[0, 0, 0, 0, 0, 1]。
  5. y_TestOneHot = to_categorical(y_Test)
  6. #转化 One-Hot Encoding 都是以0 1 表示,5 在第六个位置
  7. print('转化 One-Hot Encoding:',y_TrainOneHot[:1])#以one-hot编码形式打印出y_Train的第一个标签

输出结果如下: 

5.建立模型

Sequential()是Keras中的一个模型,它允许我们线性地堆叠不同的网络层。这意味着每一层都会接收前一层的输出作为输入

  1. ''' 建立模型 '''
  2. #建立一个 Sequential 线性堆叠模型,Sequential是Keras中的一个模型,它允许我们线性地堆叠不同的网络层。这意味着每一层都会接收前一层的输出作为输入
  3. model=Sequential()
  4. #建立第一个卷积层,input_shape 输入数字图像大小为 28*28*1, filters 卷积核个数 16 个,kernel_size 卷积核大小 3*3
  5. #padding 是否零填充 same 表示填充, activation 激活函数 relu
  6. model.add(Conv2D(filters = 16,
  7. kernel_size = (3, 3),
  8. padding = 'same',
  9. input_shape = (28, 28, 1),
  10. activation = 'relu'))
  11. #建立第一个池化层 pool_size 池化窗口 2
  12. model.add(MaxPooling2D(pool_size = (2, 2)))
  13. #因为Keras会自动推断输入形状。当在Sequential模型中添加一个层时,Keras会记住前一层的输出形状,并将该形状作为下一层的输入形状。因此,第二个卷积层会接收第一个卷积层的输出作为输入,而不需要手动指定input_shape
  14. #建立第二个卷积层, filters 卷积核个数 36 个,kernel_size 卷积核大小 3*3
  15. #padding 是否零填充 same 表示填充, activation 激活函数 relu
  16. model.add(Conv2D(filters = 36,
  17. kernel_size = (3, 3),
  18. padding = 'same',
  19. activation = 'relu'))#还有其他多种激活函数可供选择,取决于具体需求和网络设计(Sigmoid、Tanh、Leaky ReLU、Parametric ReLU、ELU、SELU )
  20. #建立第二个池化层 pool_size 池化窗口 2
  21. model.add(MaxPooling2D(pool_size = (2, 2)))
  22. ''' #建立第三个卷积层, filters 卷积核个数 64 个,kernel_size 卷积核大小 3*3
  23. #padding 是否零填充 same 表示填充, activation 激活函数 relu
  24. model.add(Conv2D(filters = 64,
  25. kernel_size = (3, 3),
  26. padding = 'same',
  27. activation = 'relu'))
  28. #建立第三个池化层 pool_size 池化窗口 2
  29. model.add(MaxPooling2D(pool_size = (2, 2))) '''

 避免过度拟合

 Dropout()层用于减少过拟合,它随机将一部分神经元的输出设置为0

  1. #加入Dropout避免过度拟合
  2. model.add(Dropout(0.25))
  3. #建立平坦层,将多维向量转化为一维向量
  4. model.add(Flatten())#将数据从(样本数,高度,宽度)转换为(样本数, 高度*宽度)
  5. #建立隐藏层,隐藏层有 128 个神经元, activation 激活函数用 relu
  6. model.add(Dense(128, activation = 'relu'))
  7. #加入Dropout避免过度拟合
  8. model.add(Dropout(0.25))
  9. #建立输出层,一共有 10 个神经元,因为 0 到 9 一共有 10 个类别, activation 激活函数用 softmax 这个函数用来分类
  10. model.add(Dense(10, activation = 'softmax'))
  11. ''' 查看模型摘要 '''
  12. print('查看模型摘要:',model.summary())

 输出:每一层的名字、类型、输出形状和参数数量。

            模型的输入形状和输出形状。

            模型的总结信息,如总参数数量、可训练参数数量等。

6.训练模型

'categorical_crossentropy'通常用于多类分类问题

 optimizer = 'adam'用于优化模型权重的算法

metrics = ['accuracy']在训练过程中跟踪的额外指标。在这里,准确率被用作度量标准

  1. #定义训练模型, loss 损失函数用 categorical_crossentropy, optimizer 优化器用 adam, metrics 度量用 accuracy
  2. model.compile(loss = 'categorical_crossentropy', optimizer = 'adam', metrics = ['accuracy'])
  3. #开始训练模型, x 是训练数据集, y 是训练数据集的标签, validation_split 是把训练数据集分为 8 份训练数据集 2 份验证集
  4. #epochs 是迭代次数 20, batch_size 是批量 256, verbose 为 2 显示训练过程
  5. train_history = model.fit(x = x_Train4D_normalize,#训练数据集,通常是缩放到平均值为0,标准差为1
  6. y = y_TrainOneHot,#训练数据的标签,通常以one-hot编码的形式表示
  7. validation_split = 0.2,#从训练数据中随机选择20%作为验证集,剩下的80%作为训练集
  8. epochs = 20,
  9. batch_size = 256,
  10. verbose = 2)

7.查看、评估和预测模型

train_history:训练历史对象

train:训练数据的标签

validation:验证数据的标签

  1. ''' 查看训练模型loss和accuracy '''
  2. def show_train_history(train_history, train, validation):
  3. plt.plot(train_history.history[train])
  4. plt.plot(train_history.history[validation])
  5. plt.title('Train History')#Train History
  6. plt.ylabel(train)
  7. plt.xlabel('Epoch')
  8. plt.legend(['train', 'validation'], loc = 'upper left')
  9. plt.show()
  10. show_train_history(train_history, 'loss', 'val_loss')
  11. show_train_history(train_history, 'accuracy', 'val_accuracy')

 

使用模型的 evaluate 方法来评估模型在测试数据集上的性能。 x_Test4D_normalize 是经过预处理和归一化的测试输入数据,y_TestOneHot 是相应的经过one-hot编码的测试标签数据

  1. scores = model.evaluate(x_Test4D_normalize, y_TestOneHot)
  2. print('评估模型:',scores[1])
预测测试集第一个数字
  1. prediction = np.argmax(model.predict(x_Test4D_normalize[:1]))
  2. print('预测值:', prediction)
  3. print('真实值:', np.argmax(y_TestOneHot[:1]))

最后输出结果:

8.总代码

  1. from keras.datasets import mnist
  2. #from keras.utils import np_utils
  3. from keras.utils import to_categorical
  4. import numpy as np
  5. import matplotlib.pyplot as plt
  6. from keras.models import Sequential
  7. from keras.layers import Dense,Dropout,Flatten,Conv2D,MaxPooling2D
  8. ''' 下载手写数据集 '''
  9. (x_Train,y_Train),(x_Test,y_Test)=mnist.load_data()
  10. print('x_Train:',x_Train.shape)
  11. print('y_Train:',y_Train.shape)
  12. print('x_Test:',x_Test.shape)
  13. print('y_Test:',y_Test.shape)
  14. ''' 图形化数据集,查看前10个数据集'''
  15. def polt_images_label_prediction(images,labels,idx,num=10):
  16. fig=plt.gcf()
  17. fig.set_size_inches(12,14)
  18. for i in range(num):
  19. ax=plt.subplot(5,2,1+i)
  20. ax.imshow(images[idx],cmap='binary')
  21. title='label='+str(labels[idx])
  22. ax.set_title(title,fontsize=10)
  23. ax.set_xticks([])
  24. ax.set_yticks([])
  25. plt.show()
  26. polt_images_label_prediction(x_Train,y_Train,0)
  27. ''' 数据预处理:
  28. 将features以reshape转化为6000*28*28*1的4维矩阵,并将其标准化。'''
  29. x_Train4D=x_Train.reshape(x_Train.shape[0],28,28,1).astype('float32')
  30. x_Test4D = x_Test.reshape(x_Test.shape[0], 28, 28, 1).astype('float32')
  31. x_Train4D_normalize = x_Train4D / 255
  32. x_Test4D_normalize = x_Test4D / 255
  33. ''' 对标签进行one-hot编码处理 '''
  34. #未转化第一个数是 5
  35. print('未转化第一个数是 5:',y_Train[:1])
  36. y_TrainOneHot = to_categorical(y_Train)
  37. y_TestOneHot = to_categorical(y_Test)
  38. #转化 One-Hot Encoding 都是以0 1 表示,5 在第六个位置
  39. print('转化 One-Hot Encoding:',y_TrainOneHot[:1])
  40. ''' 建立模型 '''
  41. model=Sequential()
  42. #建立第一个卷积层
  43. model.add(Conv2D(filters = 16,
  44. kernel_size = (3, 3),
  45. padding = 'same',
  46. input_shape = (28, 28, 1),
  47. activation = 'relu'))
  48. model.add(MaxPooling2D(pool_size = (2, 2)))
  49. #建立第二个卷积层
  50. model.add(Conv2D(filters = 36,
  51. kernel_size = (3, 3),
  52. padding = 'same',
  53. activation = 'relu'))
  54. model.add(MaxPooling2D(pool_size = (2, 2)))
  55. """"""
  56. #建立第三个卷积层
  57. model.add(Conv2D(filters = 64,
  58. kernel_size = (3, 3),
  59. padding = 'same',
  60. activation = 'relu'))
  61. model.add(MaxPooling2D(pool_size = (2, 2)))
  62. #加入Dropout避免过度拟合
  63. model.add(Dropout(0.25))
  64. model.add(Flatten())
  65. model.add(Dense(128, activation = 'relu'))
  66. #加入Dropout避免过度拟合
  67. model.add(Dropout(0.25))
  68. model.add(Dense(10, activation = 'softmax'))
  69. ''' 查看模型摘要 '''
  70. print('查看模型摘要:',model.summary())
  71. ''' 训练模型 '''
  72. #定义训练模型, loss 损失函数用 categorical_crossentropy, optimizer 优化器用 adam, metrics 度量用 accuracy
  73. model.compile(loss = 'categorical_crossentropy', optimizer = 'adam', metrics = ['accuracy'])
  74. #开始训练模型, x 是训练数据集, y 是训练数据集的标签, validation_split 是把训练数据集分为 8 份训练数据集 2 份验证集
  75. #epochs 是迭代次数 20, batch_size 是批量 256, verbose 为 2 显示训练过程
  76. train_history = model.fit(x = x_Train4D_normalize,
  77. y = y_TrainOneHot,
  78. validation_split = 0.2,
  79. epochs = 20,
  80. batch_size = 256,
  81. verbose = 2)
  82. ''' 查看训练模型loss和accuracy '''
  83. def show_train_history(train_history, train, validation):
  84. plt.plot(train_history.history[train])
  85. plt.plot(train_history.history[validation])
  86. plt.title('Train History')#Train History
  87. plt.ylabel(train)
  88. plt.xlabel('Epoch')
  89. plt.legend(['train', 'validation'], loc = 'upper left')
  90. plt.show()
  91. show_train_history(train_history, 'loss', 'val_loss')
  92. show_train_history(train_history, 'accuracy', 'val_accuracy')
  93. ''' 评估模型 '''
  94. scores = model.evaluate(x_Test4D_normalize, y_TestOneHot)
  95. print('评估模型:',scores[1])
  96. ''' 预测模型 '''
  97. #预测测试集第一个数字
  98. prediction = np.argmax(model.predict(x_Test4D_normalize[:1]))
  99. print('预测值:', prediction)
  100. print('真实值:', np.argmax(y_TestOneHot[:1]))

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/爱喝兽奶帝天荒/article/detail/789948
推荐阅读
相关标签
  

闽ICP备14008679号