基于Keras+Tensorflow,利用Lenet-5模型的mnist手写数字识别的完整程序和代码分析。适合想要入门Keras的新手。
博主由于很久没碰Tensorflow,很多代码都报了类似WARNING:tensorflow:From /someplace/xx.py:xxx: xxx is deprecated and will be removed in a future version.
的问题。深感领域发展之快,重新点开了Tensorflow官方文档,发现官方在入门学习文档中大量介绍了Keras的用法Tensorflow官方文档Keras入门。本文给出完整的Tensorflow+Keras程序,配合官方文档,能方便进行Keras入门第一步。
运行结果见本文最后一个模块
# -*- coding: utf-8 -*-
# 导入这两个是为了获取mnist数据集
import tensorflow as tf
mnist=tf.keras.datasets.mnist
# 下面三行是常规导入
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras import models
#导入mnist数据集,需要保持网络畅通
(X_train, Y_train), (X_test, Y_test) = mnist.load_data()
img_rows, img_cols = 28, 28 # 图像的尺寸
# 训练数据;X_train是60000张28*28的数据,所以尺寸是60000*28*28,Y_train是对应的数字,尺寸是60000*1,X_test和Y_test同理
X_train, X_test = X_train / 255.0, X_test / 255.0 # 将图像像素转化为0-1的实数
# 将标准答案通过one-hot编码转化为需要的格式(这两个函数不懂见下个模块的介绍)
Y_train = keras.utils.to_categorical(Y_train, num_classes=10)
Y_test = keras.utils.to_categorical(Y_test, num_classes=10)
# 将训练所用的图像调整尺寸,由于图像是黑白图像,所以最后一维的值是1
X_train = X_train.reshape(X_train.shape[0], img_rows, img_cols, 1)
X_test = X_test.reshape(X_test.shape[0], img_rows, img_cols, 1)
###############################
### 使用keras API开始定义模型 ###
###############################
model = models.Sequential()
# 向模型中添加层
model.add(layers.Conv2D(32, kernel_size=(5,5), # 添加卷积层,深度32,过滤器大小5*5
activation='relu', # 使用relu激活函数
input_shape=(img_rows, img_cols, 1))) # 输入的尺寸就是一张图片的尺寸(28,28,1)
model.add(layers.MaxPooling2D(pool_size=(2, 2))) # 添加池化层,过滤器大小是2*2
model.add(layers.Conv2D(64, (5,5), activation='relu')) # 添加卷积层,简单写法
model.add(layers.MaxPooling2D(pool_size=(2, 2))) # 添加池化层
model.add(layers.Flatten()) # 将池化层的输出拉直,然后作为全连接层的输入
model.add(layers.Dense(500, activation='relu')) # 添加有500个结点的全连接层,激活函数用relu
model.add(layers.Dense(10, activation='softmax')) # 输出最终结果,有10个,激活函数用softmax
# 定义损失函数、优化函数、评测方法
model.compile(loss=keras.losses.categorical_crossentropy,
optimizer=keras.optimizers.SGD(),
metrics=['accuracy'])
# 自动完成模型的训练过程
model.fit(X_train, Y_train, # 训练集
batch_size=128, # batchsize
epochs=20, # 训练轮数
validation_data=(X_test, Y_test)) # 验证集
# 打印运行结果,即损失和准确度
score = model.evaluate(X_test, Y_test)
print('Test loss:', score[0])
print('Test accuracy:', score[1])
直接用例子说明函数的作用和one-hot编码是什么:
from tensorflow import keras
a1 = keras.utils.to_categorical(0,num_classes=5)
a2 = keras.utils.to_categorical(1,num_classes=5)
a3 = keras.utils.to_categorical(2,num_classes=5)
a4 = keras.utils.to_categorical(3,num_classes=5)
a5 = keras.utils.to_categorical(4,num_classes=5)
print a1
print a2
print a3
print a4
print a5
a1,a2,a3,a4,a5的值分别是0,1,2,3,4,但用one-hot编码就表示为如下形式(以上程序运行结果):
[1. 0. 0. 0. 0.]
[0. 1. 0. 0. 0.]
[0. 0. 1. 0. 0.]
[0. 0. 0. 1. 0.]
[0. 0. 0. 0. 1.]
Process finished with exit code 0
这样以来,对于mnist识别项目,每张图片对应的正确答案(一个数)就被转化成了一个向量,向量非零项的坐标等于这个数的值。
如果少了以下两行:
X_train = X_train.reshape(X_train.shape[0], img_rows, img_cols, 1)
X_test = X_test.reshape(X_test.shape[0], img_rows, img_cols, 1)
将会报错:
ValueError: Error when checking input: expected conv2d_input to have 4 dimensions, but got array with shape (60000, 28, 28)
看到这个,说明程序开始运行了。由于batchsize设置为128,所以以下左侧都是128的倍数;设置一共20轮训练。
/usr/bin/python2.7 /Users/umbrella/Desktop/learn_tensorflow/basic_operation/study_tfkeras.py
Train on 60000 samples, validate on 10000 samples
2019-01-11 17:27:04.308734: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
Epoch 1/20
128/60000 [..............................] - ETA: 1:46 - loss: 2.2964 - acc: 0.0859
384/60000 [..............................] - ETA: 48s - loss: 2.2973 - acc: 0.1042
640/60000 [..............................] - ETA: 36s - loss: 2.2978 - acc: 0.0828
896/60000 [..............................] - ETA: 31s - loss: 2.2964 - acc: 0.0938
1152/60000 [..............................] - ETA: 29s - loss: 2.2932 - acc: 0.0990
1408/60000 [..............................] - ETA: 27s - loss: 2.2908 - acc: 0.1044
1664/60000 [..............................] - ETA: 25s - loss: 2.2878 - acc: 0.1136
1920/60000 [..............................] - ETA: 24s - loss: 2.2857 - acc: 0.1234
2176/60000 [>.............................] - ETA: 23s - loss: 2.2840 - acc: 0.1328
2432/60000 [>.............................] - ETA: 23s - loss: 2.2823 - acc: 0.1419
2688/60000 [>.............................] - ETA: 22s - loss: 2.2802 - acc: 0.1477
2944/60000 [>.............................] - ETA: 22s - loss: 2.2773 - acc: 0.1610
3200/60000 [>.............................] - ETA: 21s - loss: 2.2746 - acc: 0.1728
3456/60000 [>.............................] - ETA: 21s - loss: 2.2716 - acc: 0.1852
3712/60000 [>.............................] - ETA: 20s - loss: 2.2689 - acc: 0.1945
……(这只是第一轮训练,一共20轮,直接跳到最后)
8416/10000 [========================>.....] - ETA: 0s
8800/10000 [=========================>....] - ETA: 0s
9184/10000 [==========================>...] - ETA: 0s
9632/10000 [===========================>..] - ETA: 0s
10000/10000 [==============================] - 1s 126us/step
('Test loss:', 0.04231046433947049)
('Test accuracy:', 0.9865)
Process finished with exit code 0
Tensorflow官方文档Keras入门
《Tensorflow实战Google深度学习框架(第2版)》