没有更好的例子了,人工智能入门Mnist是必经之路,经典中的经典,必须从这里开始。
识别数字技术在深度学习领域已经非常成熟,常见的解决方案是OpenCV+Keras+TensorFlow,例如Github上有比较完善的车牌识别项目,我们先从最基础的手写数字识别开始机器学习实战之路吧。本文先介绍如何调用已经训练好的模型来识别图片数字,后续的文章再用全连接层和卷积神经网络来分别实现网络模型和训练代码。通过对比能更好的理解卷积神经网络共用权值、逐层抽象的概念。
我把代码,模型,测试图片一起打包
下载地址:https://download.csdn.net/download/askmeaskyou/12876950
1.概念介绍:
图像识别(Image Recognition)是指利用计算机对图像进行处理、分析和理解,以识别各种不同模式的目标和对像的技术。
图像识别的发展经历了三个阶段:文字识别、数字图像处理与识别、物体识别。机器学习领域一般将此类识别问题转化为分类问题。
手写识别是常见的图像识别任务。计算机通过手写体图片来识别出图片中的字,与印刷字体不同的是,不同人的手写体风格迥异,大小不一, 造成了计算机对手写识别任务的一些困难。
数字手写体识别由于其有限的类别(0~9共10个数字)成为了相对简单 的手写识别任务。
2.数据介绍:
MNIST的下载链接:http://yann.lecun.com/exdb/mnist/。
MNIST是一个包含数字0~9的手写体图片数据集,图片已归一化为以手写数 字为中心的28*28规格的图片。
MNIST由训练集与测试集两个部分组成,各部分 规模如下:
训练集:60,000个手写体图片及对应标签
测试集:10,000个手写体图片及对应标签
2.调用模型:
先学会使用科技成果才是“调包侠”的首要任务。
import tensorflow as tf
import numpy as np
import cv2 as cv
if __name__ == '__main__':
img = cv.imread("6.bmp", cv.IMREAD_GRAYSCALE)
img = np.asarray(img)
img = img.reshape(1, 28, 28, 1)
img_tensor = tf.convert_to_tensor(img, tf.float32)
loaded = tf.saved_model.load('tf_mnist/1/')
infer = loaded.signatures['serving_default']
result = infer(img_tensor)['dense_1']
print("before :", result)
result = np.argmax(result)
print("after :", result)
下面是运行结果:
before : tf.Tensor(
[[9.1685351e-08 1.9940728e-16 6.5213286e-12 1.0845345e-15 1.0123441e-11
7.6148967e-13 9.9999988e-01 1.7070938e-15 1.2981356e-11 8.4709163e-14]], shape=(1, 10), dtype=float32)
after : 6
为了照顾刚入门的读者,只能啰啰嗦嗦逐行解读下。
import tensorflow as tf
import numpy as np
import cv2 as cv
这里引入了三个Python库,tensorflow是机器学习的主流平台,神经网络的模型建立、训练、测试、导入、导出都有功能完整的实现和简洁的调用接口。numpy是科学计算库,大规模矩阵运算配合tensorflow使用。cv2是opencv-python,OpenCV的全称是:Open Source Computer Vision Library。OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux、Windows、Android和Mac OS操作系统上。实现了图像处理和计算机视觉方面的很多通用算法。
如果遇到错误“ImportError: No module named cv2”,没有找到cv2应该安装opencv-python 安装命令:pip install opencv-python
img = cv.imread("test6.bmp", cv.IMREAD_GRAYSCALE)
img = np.asarray(img)
这里是用opencv的库函数接口读取测试图片“6.bmp”并且转换成numpy的数组形式。位图分辨率是28*28=728位的单通道黑白图片,每一个位上的数字范围是0到255。
这样就把图片转换成了numpy的数组格式。如果图片不是28*28的分辨率就需要使用opencv的库对图片先进行预处理。
img = img.reshape(1, 28, 28, 1)
img_tensor = tf.convert_to_tensor(img, tf.float32)
这里的代码是将numpy的数组转换形式然后调用tensorflow的库函数convert_to_tensor将numpy数组转换成了tensorflow的变量。
reshape也是经常使用概念,就是将一长串数字做不同的分割理解,并不改变存储格式。如果对此不熟悉的需要先系统的学习下tensorflow2的相关知识。
loaded = tf.saved_model.load('tf_mnist/1/')
infer = loaded.signatures['serving_default']
这里的代码是调用tensorflow的库函数加载训练好的pb模型,接着调用模型对外提供的接口。模型如何建立、训练、导出留在后面的文章详述,这里先学会使用前人的科技成果。
result = infer(img_tensor)['dense_1']
print("before :", result)
result = np.argmax(result)
print("after :", result)
我们将图片转换出来的tensorflow变量传给训练好的模型,进行一次前向传播,就能得到模型给出来的反馈结果。使用所有神经网络模型就是这样一个套路,是不是很简单。
总结下步骤:
(1.数据预处理,2.转换成tensorflow的变量,3.传给训练好的神经网络模型,4.得到结果,5.将结果转换成明确的答案)
看下神经网络返回的结果
before : tf.Tensor(
[[9.1685351e-08 1.9940728e-16 6.5213286e-12 1.0845345e-15 1.0123441e-11
7.6148967e-13 9.9999988e-01 1.7070938e-15 1.2981356e-11 8.4709163e-14]], shape=(1, 10), dtype=float32)
表示的是0到9十个数字的概率,我们选择概率最大的作为返回结果输出。这样就把手写数字图片的数字解读了出来。