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曲线: