基于keras训练mnist数据集--卷积神经网络

—简述

上篇博客基于keras训练MNIST数据集-全连接网络已经详细介绍了只用全连接层训练MNIST数据集的步骤,本文将介绍使用卷积神经网络来训练MNIST数据集步骤。

1、加载MNIST数据集

MNIST数据集是由 60000 张训练图像和 10000 张测试图像组成,图像大小是 28 x 28 的灰度图像,已经预先加载在了Keras库中,其中包括4个Numpy数组。这一步同上篇全连接网络。

# 加载Keras中的MNIST数据集
from keras.datasets import mnist
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()

打印数据集,如下

>> train_image.shape
(6000, 28, 28)
>> train_labels
array([5, 0, 4, ..., 6, 8], dtype=uint8)

2、图像数据预处理

要对加载的数据进行预处理,以适应网络模型要求的形状,并将所有值缩放到[ 0, 1] 之间,由于我们训练的图像是 28 x 28 的灰度图,被保存在 uint8 类型的数组中,也就是值的范围在 [0, 255] 之间,形状为 (60000, 28, 28),所以最后要转换为一个 float32 数组, 其形状变为(60000, 28, 28,1),取值范围为 0~1。其中 1 代表灰度图,RGB图像是 3。

# 准备图像数据
train_images = train_images.reshape((60000, 28, 28, 1))
train_images = train_images.astype('float32') / 255

test_images = test_images.reshape((10000, 28, 28, 1))
test_images = test_images.astype('float32') / 255

# 准备标签,需要对标签进行分类编码转换成二进制格式
train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)

3、模型定义

模块 layers 可以看作是构建网络层的工具,模块 models 可以看作是创建网络模型的一个容器,可以把创建的网络层加入到这个容器中。

# 导入数据处理模块,可以看作
from keras import models
from keras import layers

# 先定义一个空的网络结构
model = models.Sequential()

#添加卷积层,这里把卷积和池化统称为卷积层
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))
model.add(layers.MaxPooling2D((2, 2)))

model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))

model.add(layers.Conv2D(64, (3, 3), activation='relu'))

#平铺,展平数据
model.add(layers.Flatten())

#添加1个Dropout层
model.add(layers.Dropout(0.5))

# 添加两个全连接层
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10, activation='softmax'))

4、编译模型

代码很短只需一行,但需要设置三个参数,其中

  • loss: 所代表的是损失函数,使网络模型训练数据朝向正确的方向前进。
  • optimizer: 基于训练数据和损失函数来更新网络的机制。
  • metric: 在训练和测试过程中需要监控的指标,本例只关心精度,即正确分类的图像所占的比例。
# 设置训练网络的必要参数,如果要用到其他优化器还需要导入模块 optimizers
model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])

5、训练模型

也就是在训练数据上拟合模型,其中前两个参数为训练数据,即,包含图像和标签的数据。

  • epochs 为迭代次数,即训练整个数据集要迭代的次数,可根据机器性能设置参数,详细调参后续文章会叙述。
  • batch_size 表示每次训练数据按此批量大小进行训练,也可以是其它参数,但是最好取 2 的整数倍。

注意: 这里并没有加入验证集, 因为经过测试发现加入验证集反而测试精度降低,可能是验证模型时,由于验证集的加入使得网络对输入的图像产生了“记忆”,虽然最后训练精度会提高,但会导致训练出的模型泛化能力降低。

history = model.fit(train_images, train_labels, epochs=5, batch_size=64)
					
# 评估模型,即在测试集上的性能
test_loss, test_acc = model.evaluate(test_images, test_labels)

可以对上述数据进行打印,如

>>print('test_acc:', test_acc)
test_acc: 0.9915
>>history_dict = history.history
>>history_dict.keys()
dict_keys(['loss', 'acc'])

训练过程如下:

6、预测图像

现在我们来预测未训练的原始图像(测试集)并显示出来,首先重新加载 MNIST 数据集,因为前面过程预处理使得图像数据格式变化。

(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
predictions = model.predict(test_images)

可以将数据打印出来,得到是一个张量的形式,每个向量中包含有 10 数据,代表是 0~9 某个数字的概率。结果如下

>>print(predictions)
[[2.53999460e-10 3.13443649e-09 1.13098464e-08 ... 1.00000000e+00
  1.14483745e-09 3.00820311e-08]
 [7.86611736e-08 3.69769464e-06 9.99996185e-01 ... 8.06958056e-09
  2.84115362e-08 4.13955599e-13]
 [1.14044463e-09 9.99811947e-01 4.80392437e-09 ... 1.12551425e-04
  2.76754099e-06 5.21817753e-07]
 ...
 [9.88247845e-16 1.55450704e-11 3.51570395e-16 ... 2.98323484e-11
  4.88785012e-10 6.33079411e-09]
 [9.11740905e-09 1.08507071e-10 6.55652290e-13 ... 3.31231287e-09
  2.15885734e-06 1.69374251e-10]
 [1.36937910e-08 5.68056935e-10 1.15511334e-09 ... 1.53420720e-13
  2.79600870e-10 3.93418353e-11]]
>> import numpy as np
>> np.argmax(predictions[19]) 
4

上述测试了测试集 test_images 中第10个图像的数字是0,为了验证是不是准确的我们将 test_images 中
第10个图像打印出来,结果如下

>> tes = test_images[19]
>> plt.imshow(tes, cmap=plt.cm.binary)
>> plt.show()

在这里插入图片描述
结果显示我们预测的结果是准确的。
完整代码如下:

from keras.datasets import mnist
from keras import models
from keras import layers
from keras.utils import to_categorical

#定义网络模型
model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))

model.add(layers.Flatten())
model.add(layers.Dropout(0.5))
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10, activation='softmax'))

#加载数据集
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()

train_images = train_images.reshape((60000, 28, 28, 1))
train_images = train_images.astype('float32') / 255

test_images = test_images.reshape((10000, 28, 28, 1))
test_images = test_images.astype('float32') / 255

train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)

#准备验证集
#x_val = train_images[:20000]
#partial_x_train = train_images[20000:]

#y_val = train_labels[:20000]
#partial_y_train = train_labels[20000:]

#编译
model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
history = model.fit(train_images, train_labels, epochs=5, batch_size=64)

#训练,拟合
#history = model.fit(partial_x_train, partial_y_train, epochs=5, batch_size=64, validation_data=(x_val, y_val))
test_loss, test_acc = network.evaluate(test_images, test_labels)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值