从mnist手写数据集一步一步带你走进keras这个应用起来极为简单的框架
一般的初学者呢,基本都会对mnist进行入门的学习,我也不例外。学习闲暇之余,也分享一下我的学习过程。
好无聊啊!讲个故事吧。
浅显来讲,深度学习喂给模型(算法)的数据,模型吃了数据就会越来越有经验。就好比你吃遍学校或家里边的小吃街,再去的时候径直走向烤鱿鱼(因为你已经吃过n次了,超酷爱这个东东)
稍微正经点说,啥意思呢。小吃是数据、你是模型、感觉好不好吃也是数据。就是说你吃了小吃很多次,你就有经验了。对应的,深度学习中的模型利用数据训练也具有经验,把这个训练多次的经验保存下来,你就拥有这个算法了,就能于万千商品中,一眼找到你的最爱。
有了一定了解之后,就需要准备数据了。正巧,keras这个框架里面继承了mnist数据集,就不需要我们下载了。还需要模型,这就需要我们自己创建了。
from tensorflow.keras.datasets import mnist # 数据集接口
import matplotlib.pyplot as plt # 绘图接口
from tensorflow.keras.layers import Dense # 全连接层
from tensorflow.keras import models
写代码第一步就是导库,可以直接调用别人写好的接口。避免闭门造车,提升开发效率。
1.通过mnist.load_data()方法读取到数据存在变量中。用print()查看一下读取到的数据。
# 装载数据
(train_image,train_label), (test_image,test_label) = mnist.load_data()
print('train_image.shape:', train_image.shape)
print('test_image.shape:', test_image.shape)
print('train_label.shape', train_label.shape)
print('test_label.shape', test_label.shape)
print('train_label', train_label)
运行结果:
train_image.shape: (60000, 28, 28)
test_image.shape: (10000, 28, 28)
train_label.shape (60000,)
test_label.shape (10000,)
train_label [5 0 4 … 5 6 8]
训练集中有60000张28x28大小的图片,测试集中有10000张28x28大小的图片。
2.查看一下图片和标签(此步用于测试,实际可没有)
cmap即colormaps,图谱。matplotlib.cm是matplotlib库中内置的色彩映射函数。matplotlib.cm.[色彩],即对[数据集]应用对应的内置色彩映射列表(这里是binary)。
# # 打印一下 显示图片
plt.imshow(train_image[0], cmap=plt.cm.binary)
# plt.imshow(test_image[0], cmap=plt.cm.binary)
print('train_label:', train_label)
# print('test_label:', test_label)
plt.show()
运行结果:观察训练集的第一个图片机器它的标签
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iM2vVQvd-1647964044824)(photo/Snipaste_2022-03-21_21-51-22.png)]
train_label: [5 0 4 … 5 6 8]
3.数据预处理
把数据进行预处理,满足训练要求的格式
# 改变shape 满足模型输入
train_image = train_image.reshape(60000, 28*28)
test_image = test_image.reshape(10000, 28*28)
# 归一化 使数据被限定在一定的范围内,消除奇异样本数据导致的不良影响
train_image = train_image.astype('float32')/255
test_image = test_image.astype('float32')/255
from tensorflow.keras.utils import to_categorical
print('before:', train_label[0]) # 5
print('before shape:', train_label.shape) # (60000,)
# 分类算法一般把 label 调用to_categorical进行one-hot处理
train_label = to_categorical(train_label)
test_label = to_categorical(test_label)
print('after:', train_label[0]) # [0,0,0,0,0,1,0,0,0,0]
print('after:', train_label.shape) # (60000, 10)
运行结果:
before: 5
before shape: (60000,)
after: [0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]
after: (60000, 10)
使用序贯模型,好处是可以通过.add()方法堆叠模型。
# 定义序贯模型
model = models.Sequential()
# 添加524个节点的全连接层 激活函数relu 数据输入shape为(28x28)
model.add(Dense(524, activation='relu', input_shape=(28*28,)))
# 添加10个节点的全连接层 激活函数softmax 数据输入系统默认为上一层网络输出
model.add(Dense(10, activation='softmax',))
模型的构建后, 可以使用 .compile() 来配置学习过程。在使用过程中常用的是这三个参数:
model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
准备工作就绪,fit()方法训练。部分参数:
# 训练 fit
model.fit(train_image, train_label, epochs=3, batch_size=200, verbose=2)
evaluate()方法评估,在测试模式下返回模型的误差值和评估标准值。计算是分批进行的。
x: 测试数据的 Numpy 数组
y: 目标(标签)数据的 Numpy 数组
batch_size: 整数或 None。每次评估的样本数。如果未指定,默认为 32。
verbose: 0 或 1。日志显示模式。 0 = 安静模式,1 = 进度条。
返回: 返回了多少个值,是不固定的,如果在complie的时候没有指定metrics的话,默认只有loss一个返回值。可以使用model.metrics_names查看
# 评估模型
loss, acc = model.evaluate(test_image, test_label, verbose=0)
print('loss:{}\nacc:{}'.format(loss, acc))
# 保存模型 保存在同级目录下
model.save('keras.h5' % acc)
运行结果:
Epoch 1/3
60000/60000 - 3s - loss: 0.2879 - acc: 0.9178
Epoch 2/3
60000/60000 - 3s - loss: 0.1184 - acc: 0.9656
Epoch 3/3
60000/60000 - 3s - loss: 0.0791 - acc: 0.9764
loss:0.08860381994713097
acc:0.9726999998092651
模型训练完毕,并且也保存了。让我们来使用吧,这里再次读取数据集,使用刚刚的经验(训练好的模型)来测试一下。
model = models.load_model('keras.h5') # 载入模型
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
# digit = test_images[1]
# plt.imshow(digit, cmap=plt.cm.binary)
# plt.show()
test_images = test_images.reshape((10000, 28*28)) # 预处理
res = model.predict(test_images) # 预测
# NUM = 2
correct_num = 0
total_num = 1000*3
for NUM in range(0, total_num):
for i in range(res[NUM].shape[0]):
if (res[NUM][i] == 1):
correct_num += 1
# print("the number for the picture is : ", i)
break
print('correct rate:', correct_num/total_num)
运行输出
correct rate: 0.9996666666666667
我这里total_num = 100
时,输出的是correct rate: 1.0。这里的预测准确率大家和我不同不用担心,因为训练过程根据电脑配置、软件环境都是有关的。代码跟着我打下来,数据只要差的不是特别多都可以接受。
correct rate: 0.9996666666666667
我这里total_num = 100
时,输出的是correct rate: 1.0。这里的预测准确率大家和我不同不用担心,因为训练过程根据电脑配置、软件环境都是有关的。代码跟着我打下来,数据只要差的不是特别多都可以接受。