【Keras学习笔记】11:CNN识别MNIST手写数字

CNN架构

卷积层 layers.Conv2D

  • data-format: 输入图像的格式,当为"channels_last"时为(batch, height, width, channels);当为"channels_first"时为(batch, channels, height, width)
  • filters: 生成多少个卷积核(要得到的图像的厚度),即变换后的图像通道数
  • kernel_size: 卷积核大小
  • strides: 卷积核移动跨度,是一个二元组表示两个方向上移动的跨度
  • padding: 边缘填充
  • use_bias: 是否添加偏置
  • kernel_initializer: 权重的初始化方式
  • bias_initializer: 偏置的初始化方式
  • kernel_regularizer: 权重的正则化系数
  • bias_regularizer: 偏置的正则化系数

非线性变换层 relu/sigmoid/tanh

  • 在卷积层中设置activation即可

池化层(如最大池化) layers.MaxPooling2D 注意池化核本来就是不重叠的下采样,所以一般不添加strides

  • pool_size: 池化核的大小
  • strides: 池化核移动跨度
  • padding: 边缘填充

以上的结构反复几次,将图像的厚度不断变大(抽象出特征),图像的尺寸变小,最后接若干全连接层 layers.Dense

识别MNIST手写数字

读取数据和预处理

import keras
from keras import layers
import numpy as np
from matplotlib import pyplot as plt
import pandas as pd
%matplotlib inline
Using TensorFlow backend.
from keras.datasets import mnist as mn
(train_img, train_lab), (test_img, test_lab) = mn.load_data()
train_img.shape, train_lab.shape, test_img.shape, test_lab.shape
((60000, 28, 28), (60000,), (10000, 28, 28), (10000,))

MNIST的通道数是1,但在CNN输入时候需要有这个维度,变换一下,例如:

a = np.array([1, 2, 3])
a, a.shape
(array([1, 2, 3]), (3,))
a = np.expand_dims(a, axis=-1) # -1表示在最后一个维度上扩增
a, a.shape
(array([[1],
        [2],
        [3]]), (3, 1))
# 扩增出channels维度
tr_img = np.expand_dims(train_img, axis=-1)
tt_img = np.expand_dims(test_img, axis=-1)
tr_img.shape, tt_img.shape
((60000, 28, 28, 1), (10000, 28, 28, 1))

模型搭建和训练

model = keras.Sequential()
# 添加卷积层
model.add(layers.Conv2D(filters=16, kernel_size=(3, 3), activation='relu', input_shape=(28, 28, 1)))
model.add(layers.Conv2D(filters=16, kernel_size=(3, 3), activation='relu'))
# 添加最大池化
model.add(layers.MaxPooling2D())
# 接下来为了训练特征,输出分类,添加全连接层,但现在的输出是四个维度(batch ,height, width, channels)
# 而全连接层的输入要求是两个维度(batch, data),所以这里进行flatten
model.add(layers.Flatten())
model.add(layers.Dense(256, activation='relu'))
model.add(layers.Dropout(rate=0.5)) # 添加Dropout抑制过拟合
model.add(layers.Dense(10, activation='softmax')) # 为了分类到10个类别,使用Softmax激活
model.summary()
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_7 (Conv2D)            (None, 26, 26, 16)        160       
_________________________________________________________________
conv2d_8 (Conv2D)            (None, 24, 24, 16)        2320      
_________________________________________________________________
max_pooling2d_4 (MaxPooling2 (None, 12, 12, 16)        0         
_________________________________________________________________
flatten_4 (Flatten)          (None, 2304)              0         
_________________________________________________________________
dense_7 (Dense)              (None, 256)               590080    
_________________________________________________________________
dropout_4 (Dropout)          (None, 256)               0         
_________________________________________________________________
dense_8 (Dense)              (None, 10)                2570      
=================================================================
Total params: 595,130
Trainable params: 595,130
Non-trainable params: 0
_________________________________________________________________
# 编译模型
model.compile(
    optimizer='adam',
    loss='sparse_categorical_crossentropy', # 针对顺序编码的多分类label
    metrics=['acc']
)
# 训练模型,电脑太差就跑4个epoch快一点
history = model.fit(tr_img, train_lab, epochs=4, batch_size=521)
Epoch 1/4
60000/60000 [==============================] - 46s 775us/step - loss: 1.6004 - acc: 0.8400
Epoch 2/4
60000/60000 [==============================] - 48s 796us/step - loss: 0.1524 - acc: 0.9560
Epoch 3/4
60000/60000 [==============================] - 47s 785us/step - loss: 0.0956 - acc: 0.9712
Epoch 4/4
60000/60000 [==============================] - 48s 804us/step - loss: 0.0717 - acc: 0.9784
model.evaluate(tt_img, test_lab)
10000/10000 [==============================] - 4s 366us/step





[0.04885944698239182, 0.9854]

模型的优化思路

增加卷积核的个数,或增加卷积层的个数。电脑不行就不优化了。

你可能感兴趣的:(#,Keras)