首页 > 技术文章 > 12-1 Minist 手写字体识别-LeNet-5-序贯模型

ailex 2018-09-07 16:14 原文

【基础要点】

  1-加载Minist数据,并变形

  2-数据信息图形化显示

  3-可视化训练过程

  4-可视化预测

  4-误差矩阵显示【混淆矩阵】

【代码实现】

  1-超级参数定义

 1 #输入图像数据信息
 2 IMG_WIDTH = 28
 3 IMG_HEIGHT =28
 4 IMG_CHANNEL = 1
 5 
 6 #第一层卷积层参数
 7 CONV_1_DEEP = 32
 8 CONV_1_SIZE = 5
 9 CONV_1_STEP = 1
10 CONV_1_PADDING = 'same'
11 
12 #第二层池化层参数
13 CONV_2_SIZE = 2
14 CONV_2_STEP = 2
15 
16 #第三层卷积层参数
17 CONV_3_DEEP = 64
18 CONV_3_SIZE = 5
19 CONV_3_STEP = 1
20 CONV_3_PADDING = 'same'
21 
22 #第四层池化参数
23 CONV_4_SIZE = 2
24 CONV_4_STEP = 2
25 
26 #第五层全连接层参数
27 CONV_5_NODES = 120
28 
29 #第六层全连接层参数
30 CONV_6_NODES = 10

  2-全部代码

  1 %matplotlib inline 
  2 import numpy as np #导入 numpy 
  3 import matplotlib.pyplot as plt #与 matplotlib 库
  4 
  5 from keras import utils
  6 from keras.datasets import mnist #导入Minist数据文件
  7 
  8 from keras.models import Sequential #导入序贯模型
  9 from keras.layers import Flatten, Dense, Dropout
 10 from keras.layers import Conv2D, Activation, MaxPooling2D
 11 
 12 #from keras.optimizers import SGD #导入SGD 随机梯度下降优化器模块
 13 
 14 # 引入Tensorboard,训练可视化用
 15 from keras.callbacks import TensorBoard
 16 from keras.utils import plot_model
 17 
 18 #下载测试数据到本地
 19 (x_train, y_train),(x_test, y_test) = mnist.load_data(); 
 20 print(x_train.shape) #60000组数据作为训练数据,输出训练数据形状
 21 print(x_test.shape)  #10000组数据作文测试数据,输出测试数据形状
 22 print(y_train.shape) #输出训练标签形状
 23 print(y_test.shape)  #输出测试标签形状
 24 
 25 #图形化显示测试数据
 26 fig = plt.gcf()
 27 fig.set_size_inches(12, 6)
 28 for i in range(10):
 29     ax=plt.subplot(2,5,i+1) #绘制子图
 30     ax.set_title("Label:{}".format(y_train[i]),fontsize=10)  # 设置子图的标题
 31     ax.set_xticks([]);ax.set_yticks([])   #不显示x轴和y轴坐标     
 32     plt.imshow(x_train[i], cmap='gray', interpolation='none')
 33     #plt.set_xticks([])
 34     #plt.set_yticks([])
 35     #plt.title("Class {}".format(y_train[i]))
 36 
 37 #注意,这里要做一次形状变换
 38 x_train = x_train.reshape(-1, 28, 28,1).astype('float32')  
 39 x_test = x_test.reshape(-1,28, 28,1).astype('float32')
 40 print(x_train.shape) #输出训练标签形状
 41 print(x_test.shape)  #输出测试标签形状
 42 
 43 #对训练标签数据进行独热编码
 44 nb_classes = 10 #类别种类
 45 y_train = utils.to_categorical(y_train, nb_classes)
 46 y_test = utils.to_categorical(y_test, nb_classes)
 47 print(y_train[0])
 48 print(y_test[0])
 49 
 50 #创建 LeNet-5 模型
 51 model = Sequential()
 52 
 53 #第一层卷积层 
 54 #深度为32,过滤器大小为5*5,步长为(1,1),padding=same 第一层必须指定输入的形状,use_bias=True,激活函数为ReLu
 55 model.add(Conv2D(32, (5, 5), padding ='same',activation='relu',input_shape=(28, 28, 1),name="first_layer")) #name参数为了图形化显示模型结构时使用
 56 
 57 #第二层池化层,减小体积
 58 #选用最大池化层,过滤器边长为2,全零填充,步长为2, 输出尺寸为
 59 model.add(MaxPooling2D(pool_size=2, strides=2, padding='same'))
 60 
 61 #第三层卷积层 
 62 #深度为64,过滤器大小为5*5,步长为(1,1),padding=same 第一层必须指定输入的形状,use_bias=True,,激活函数为ReLu
 63 model.add(Conv2D(64, (5, 5), padding ='same',activation='relu'))
 64 
 65 #第四层池化层,减小体积
 66 #选用最大池化层,过滤器边长为2,全零填充,步长为2, 输出尺寸为
 67 model.add(MaxPooling2D(pool_size=2, strides=2, padding='same'))
 68 
 69 #进入全连接层之前将张量扁平化,即把多维的输入一维化
 70 model.add(Flatten())
 71 #第五层全连接层
 72 #输出维度512
 73 model.add(Dense(120,activation='relu'))
 74 model.add(Dropout(0.5))#引入 Drouptout,防止过拟合
 75 
 76 #第六层输出层
 77 model.add(Dense(10,activation='softmax'))
 78 
 79 #图形化显示模型结构
 80 #plot_model(model,to_file='model.png')  #报错:OSError: `pydot` failed to call GraphViz.Please install GraphViz (https://www.graphviz.org/) and ensure that its executables are in the $PATH.
 81 
 82 #编译:书中损失函数为0.6-0.8
 83 model.compile(loss='categorical_crossentropy', optimizer="sgd")#[*]adam损失函数下降很慢,使用sgd后损失函数快速下降
 84 
 85 #进行训练
 86 #设置TensorBoard回调函数
 87 tb = TensorBoard(log_dir='E:\log',  # log 目录
 88                  histogram_freq=1,  # 按照何等频率(epoch)来计算直方图,0为不计算
 89                  batch_size=32,     # 用多大量的数据计算直方图
 90                  write_graph=True,  # 是否存储网络结构图
 91                  write_grads=False, # 是否可视化梯度直方图
 92                  write_images=False,# 是否可视化参数
 93                  embeddings_freq=0, 
 94                  embeddings_layer_names=None, 
 95                  embeddings_metadata=None)
 96 callbacks = [tb]
 97 
 98 #训练
 99 model.fit(x_train,y_train,epochs=2,batch_size=128,
100           verbose=1,validation_data=(x_test,y_test),
101           callbacks=callbacks)
102 
103 # 输出训练好的模型在测试集上的表现
104 score_history = model.evaluate(x_test, y_test, batch_size=128)
105 print('Test accuracy:', score_history)

  

  3-可视化模型结构:

    Keras的utils里面专门有一个plot_model()函数是用来可视化网络结构的,为了保证格式美观,我们在定义模型的时候给每个层都加了一个名字。

  3-可视化训练过程

    1-在model的fit函数中加入TensorBoard的回调函数即可,训练数据就会自动保存在log_dir指定的目录内

    2-打开相同环境下的命令窗口,执行命令 tensorboard –logdir= log_dir (参数保存的目录)

    3-根据命令行的提示,在浏览器内输入网址,例如我的网址为:http://microwin10-1735:6006

    TensorBoard会记录loss及model.metrics里面的值,本例中即acc,loss,val_acc,val_loss四个值,每个epoch更新一次。

    除了这些SCALARS,还会记录网络的GRAPH,直接可视化网络结构,但是相比用原生TensorFlow生成的图而言,相差还是比较大的,比较难看,所以不推荐在Keras中使用TensorBoard查看网络结构。 

【遇到的问题】

1-报错-数据格式不对,解决办法,对数据变形处理

2-损失过大,解决办法,优化方法为sgd

 

推荐阅读