tensorflow nmist库手写数字识别

上次写了tensorflow的安装过程,这次就是梳理深度学习的’hello world’–mnist手写数字库,老实说,在家写了不少东西,但是在家一点干劲都没有,不想写博客。挨千刀的病毒:-(

nmist是一个数字库,现在梳理一下用这个库学习手写数字的过程。

导入库

一共三个库

第一个就是关键的tf训练库,为了方便起个别名tf

第二个是数学库numpy用来做一些数字矩阵处理

第三个是matplotlib库,用来做图看手写数字的图片

1
2
3
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

导入nmist库并处理

这里是打算构建卷积神经网络

根据官方文档,导入过程就如下

1
2
3
4
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
print(x_train.shape, y_train.shape)
print(x_test.shape, y_test.shape)

扩充图片

可以看到,(x_train, y_train) 训练集中,有60000个 28X28的图片,这个地方需要做一个填充到32 X 32的步骤,由于是初学,所以并不了解这么做的用意,标注一下,后面求证

扩充方式是图片上下左右各扩充两个单位

1
2
3
x_train = np.pad(x_train, ((0, 0), (2, 2), (2, 2)), 'constant', constant_values=0)
x_test = np.pad(x_test, ((0, 0), (2, 2), (2, 2)), 'constant', constant_values=0)
print(x_train.shape)

归一化

然后就是数值的归一化,这里的数据是灰度图,所以可以直接知道最大值是255.最小值是0

再有就是为了方便训练,在多加一个维度,相当于把每个值再单独计算为一个维度,就是一个通道

1
2
3
4
5
6
7
8
x_train = x_train.astype('float32')
x_train /= 255
x_train = x_train.reshape(x_train.shape[0], 32, 32, 1)
print(x_train.shape)

x_test = x_test.astype('float32')
x_test /= 255
x_test = x_test.reshape(x_test.shape[0], 32, 32, 1)

构造模型

这次学习构造的是一个卷积神经网络,分为以下几层

第一层卷积层,激活函数是relu

1
tf.keras.layers.Conv2D(filters=6, kernel_size=(5, 5), padding='valid', activation=tf.nn.relu, input_shape=(32,32,1))

第二层池化层

1
tf.keras.layers.AveragePooling2D(pool_size=(2, 2), strides=(2,2), padding='same')

其余层同理

总模型如下

1
2
3
4
5
6
7
8
9
10
11
12
model = tf.keras.models.Sequential([
tf.keras.layers.Conv2D(filters=6, kernel_size=(5, 5), padding='valid', activation=tf.nn.relu, input_shape=(32,32,1)),#relu
tf.keras.layers.AveragePooling2D(pool_size=(2, 2), strides=(2,2), padding='same'),
tf.keras.layers.Conv2D(filters=16, kernel_size=(5, 5), padding='valid', activation=tf.nn.relu),
tf.keras.layers.AveragePooling2D(pool_size=(2, 2), strides=(2,2), padding='same'),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(units=120, activation=tf.nn.relu),
# tf.keras.layers.Conv2D(filters=120, kernel_size=(5,5),strides=(1,1),activation='tanh',padding='valid'),
# tf.keras.layers.Flatten(),
tf.keras.layers.Dense(units=84, activation=tf.nn.relu),
tf.keras.layers.Dense(units=10, activation=tf.nn.softmax)
])

训练模型

训练次数是10次,一次训练取64个,学习率是0.001

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
num_epochs = 10
batch_size = 64
learning_rate = 0.001

# 优化器
adam_optimizer = tf.keras.optimizers.Adam(learning_rate)

model.compile(optimizer=adam_optimizer,
loss=tf.keras.losses.sparse_categorical_crossentropy,
metrics=['accuracy'])

import datetime
start_time = datetime.datetime.now()

model.fit(x=x_train,
y=y_train,
batch_size=batch_size,
epochs=num_epochs)
end_time = datetime.datetime.now()
time_cost = end_time - start_time
print ("time_cost = ", time_cost)

总体就是这样了,具体实现我没细说,毕竟机器学习里面的神经网络要求具体实现的,比这个调用详细地多,但是不得不说,机器学习神经网络的快速发展,和这些方便调用的库是离不开关系的,确实是很大地降低了门槛。

下面就是试试测试集

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
print (x_test[image_index].shape)
plt.imshow(x_test[image_index].reshape(32, 32),cmap='Greys')
plt.show()

pred = model.predict(x_test[image_index].reshape(1, 32, 32, 1))
print(pred.argmax())

#模型保存
model.save('lenet_model.h5')

# 评估指标
print(model.evaluate(x_test, y_test)) # loss value & metrics values

# 预测
image_index = 4444
print (x_test[image_index].shape)
plt.imshow(x_test[image_index].reshape(32, 32),cmap='Greys')
plt.show()

pred = model.predict(x_test[image_index].reshape(1, 32, 32, 1))
print(pred.argmax())

准确率还是十分高的,这次就到这里了,再找个经典例子练练手就填以太坊的坑。

初一以为假期还有15天,初四发现还有20天,初十发现还有30天,马萨卡,这就是时间线的变动么orz