实战keras搭建CNN实现MNIST手写数字识别

1、准备数据

import tensorflow as tf
import numpy as np
from keras import datasets, layers, models
import matplotlib.pyplot as plt

#任务目标:实现手写数字识别
#数据集:MNIST手写数字数据集


#两种加载方法
# 加载本地MNIST数据集
data= np.load('/Users/code/MNIST_data/mnist.npz', allow_pickle=True)
x_train, y_train = data['x_train'], data['y_train']
x_test, y_test = data['x_test'], data['y_test']
# 下载MNIST手写数字数据集,使用TensorFlow内置的datasets.mnist.load_data()函数
data = datasets.mnist.load_data()
x_train, y_train = data['x_train'], data['y_train']
x_test, y_test = data['x_test'], data['y_test']


# 归一化像素值到0~1之间
x_train = x_train.astype('float32') / 255.  
x_test = x_test.astype('float32') / 255.  

#随机排序
perm = np.random.permutation(x_train.shape[0])  
x_train = x_train[perm]    
y_train = y_train[perm]

# 对label进行one-hot编码 
y_train = tf.keras.utils.to_categorical(y_train, 10)
y_test = tf.keras.utils.to_categorical(y_test, 10)


2、构建模型

#Sequential创建模型容器
model = models.Sequential()
#第一层卷积层
#卷积核个数filters=32
#卷积核大小kernel_size=3=(3, 3)
#激活函数activation=‘relu’
#输入数据的形状input_shape,28行数,28列数,1单通道或者说是1维数组
#padding全零填充为valid为不填充
model.add(layers.Conv2D(filters=32,kernel_size=3,strides=1,padding='valid',activation='relu', input_shape=(28, 28, 1)))
#第二层二维最大值池化层主要用于空间下采样
model.add(layers.MaxPooling2D((2, 2)))
#第三层卷积层
#卷积核个数filters=64
#卷积核大小kernel_size=3=(3, 3)
#激活函数activation=‘relu’
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
#第二层二维最大值池化层主要用于空间下采样
model.add(layers.MaxPooling2D((2, 2)))
#第三层卷积层
#卷积核个数filters=128
#卷积核大小kernel_size=3=(3, 3)
#激活函数activation=‘relu’
model.add(layers.Conv2D(128, (3, 3), activation='relu'))  
#第四层是拉平层将输入张量(多维)压平为一维
model.add(layers.Flatten())
#第五层全连接层将每个输入节点连接至每个输出节点,拥有权重和偏置参数
model.add(layers.Dense(128, activation='relu'))
#第五层全连接层将每个输入节点连接至每个输出节点,拥有权重和偏置参数
#softmax的特点是:1. 将向量映射到(0, 1)区间 2. 归一化为1(和为1) 3. 产生一个概率分布的输出
model.add(layers.Dense(10, activation='softmax'))


3、编译模型

#optimizer优化器
#loss损失函数
#metrics准确率
model.compile(optimizer='adam', 
    loss='categorical_crossentropy',  
    metrics=['accuracy'])


4、训练模型

#_train, y_train输入训练集的特征和标签
#validation_data导入测试集的特征和标签x_test, y_test
#epochs要迭代多少次数据集
#batch_size每批数据多少个
#verbose打印训练过程,verbose=1会显示进度条,verbose=2会显示每轮次的训练损失和验证损失
#callbacks=[callback]回调函数,非必需
history=model.fit(x_train, y_train, validation_data=(x_test, y_test), epochs=5, batch_size=128,verbose=1)


5、显示训练集和验证集的acc和loss曲线

acc=history.history['accuracy']
var_acc = history.history['val_accuracy']
loss = history.history['loss']
var_loss = history.history['val_loss']

plt.subplot(1,2,1)
plt.plot(acc,label='TrainAcc')
plt.plot(var_acc,label='ValAcc')
plt.title('Train and Val Acc')
plt.legend()

plt.subplot(1,2,2)
plt.plot(loss,label='TrainLoss')
plt.plot(var_loss,label='ValLoss')
plt.title('Train and Val Loss')
plt.legend()

plt.show()


6、打印模型

model.summary()

7、保存模型

model_path = '/Users/code/model/mnist.h5'
model.save(model_path)

输出结果:

Epoch 1/5
469/469 [==============================] - 37s 76ms/step - loss: 0.0217 - accuracy: 0.9927 - val_loss: 0.0302 - val_accuracy: 0.9904
Epoch 2/5
469/469 [==============================] - 35s 74ms/step - loss: 0.0163 - accuracy: 0.9946 - val_loss: 0.0319 - val_accuracy: 0.9897
Epoch 3/5
469/469 [==============================] - 35s 74ms/step - loss: 0.0125 - accuracy: 0.9957 - val_loss: 0.0251 - val_accuracy: 0.9931
Epoch 4/5
469/469 [==============================] - 35s 75ms/step - loss: 0.0097 - accuracy: 0.9969 - val_loss: 0.0238 - val_accuracy: 0.9931
Epoch 5/5
469/469 [==============================] - 35s 75ms/step - loss: 0.0083 - accuracy: 0.9974 - val_loss: 0.0308 - val_accuracy: 0.9911
Model: "sequential"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 conv2d (Conv2D)             (None, 26, 26, 32)        320       
                                                                 
 max_pooling2d (MaxPooling2D  (None, 13, 13, 32)       0         
 )                                                               
                                                                 
 conv2d_1 (Conv2D)           (None, 11, 11, 64)        18496     
                                                                 
 max_pooling2d_1 (MaxPooling  (None, 5, 5, 64)         0         
 2D)                                                             
                                                                 
 conv2d_2 (Conv2D)           (None, 3, 3, 128)         73856     
                                                                 
 flatten (Flatten)           (None, 1152)              0         
                                                                 
 dense (Dense)               (None, 128)               147584    
                                                                 
 dense_1 (Dense)             (None, 10)                1290      
                                                                 
=================================================================
Total params: 241,546
Trainable params: 241,546
Non-trainable params: 0

训练集和验证集的acc和loss曲线:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

缘起性空、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值