【转载】使用Tensorflow和MNIST识别自己手写的数字

原文链接:blog.csdn.net/sparta_117/article/details/66965760

使用Tensorflow和MNIST识别自己手写的数字

最近在学习神经网络相关的东西,发现有很多资料是Tensorflow教程上的内容,但是教程很多只是一个验证官方程序的过程。如何将官方程序变成自己可以利用的程序,网上似乎资料比较少,所以我就来介绍一下如何使用Tensorflow和MNIST搭建自己的手写识别算法,识别自己写的数字(比如下面我写的这个苍劲有力的3~~)。本文也参考了国外大神博客的内容。纯新手,之前在博客上收益良多,也希望能帮助和我一样刚刚起步的童鞋,大家多多指教。

内容如下:

-Tensorflow和MNIST简介

-CNN算法

-训练程序

-写数字,并用Opencv进行预处理

-将图片输入网络进行识别

Tensorflow和MNIST简介

TensorFlow™ 是一个采用数据流图,用于数值计算的开源软件库。它是一个不严格的“神经网络”库,可以利用它提供的模块搭建大多数类型的神经网络。它可以基于CPU或GPU运行,可以自动使用GPU,无需编写分配程序。主要支持Python编写,但是官方说也有C++使用界面。

MNIST是一个巨大的手写数字数据集,被广泛应用于机器学习识别领域。MNIST有60000张训练集数据和10000张测试集数据,每一个训练元素都是28*28像素的手写数字图片。作为一个常见的数据集,MNIST经常被用来测试神经网络,也是比较基本的应用。

CNN算法

识别算法主要使用的是卷积神经网络算法(CNN)。

主要结构为:输入-卷积层-池化层-卷积层-池化层-全连接层-输出

卷积

卷积其实可以看做是提取特征的过程。如果不使用卷积的话,整个网络的输入量就是整张图片,处理就很困难。

(这里使用了参考了别人博客中的内容,来源记不清了TAT)

假设图中绿色5*5矩阵为原图片,黄色的3*3矩阵就是我们的过滤器,即卷积核。将黄色矩阵和绿色矩阵被覆盖的部分进行卷积计算,即每个元素相乘求和,便可得到这一部分的特征值,即图中的卷积特征。

然后,向右滑动黄色的矩阵,便可继续求下一部分的卷积特征值。而滑动的距离就是步长。

池化

池化是用来把卷积结果进行压缩,进一步减少全连接时的连接数。

池化有两种:

一种是最大池化,在选中区域中找最大的值作为抽样后的值;

一种是平均值池化,把选中的区域中的平均值作为抽样后的值。

实现过程

1.训练程序

这里我就先把程序贴出来,主体和tensorflow教程上大致相同。值得注意的是其中的saver部分,将训练的权重和偏置保存下来,在评价程序中可以再次使用。


2.写数字,并用Opencv进行预处理

训练好了网络,下一步就要测试它了。自己写一个数字,然后用Opencv预处理一下再扔到评价程序里,看看能不能准确识别。

我们先来识别这张我开头写的3吧:(可以写得再奇怪一些,检测一下识别能力)

下面我们就要对它进行预处理,缩小它的大小为28*28像素,并转变为灰度图,进行二值化处理。我使用的是Opencv对图像进行处理,也可以使用MATLAB等进行预处理。

图片预处理程序如下:(程序改编自http://blog.csdn.net/skeeee/article/details/16844937,可以使用鼠标拖动选取框,对选取框中的图像进行处理)


完成预处理程序后,我们得到了这样的图片:

这就是28*28的二值化后的图片,这样的格式和我们MNIST数据集中的图片格式相同。只有这样,我们才能将图片输入到网络中进行识别。

3.将图片输入网络进行识别

这里我是编写了一个前向传播的程序,最后softmax层分类的结果就是最后的识别结果啦。

程序如下:(这里参考了一个外网的博客,地址不记得了。。。)

from PIL import Image, ImageFilter

import tensorflow as tf

import matplotlib.pyplot as plt

import cv2

def imageprepare():

"""

This function returns the pixel values.

The imput is a png file location.

"""

file_name='/home/mzm/MNIST_recognize/p_num2.png'#导入自己的图片地址

#in terminal 'mogrify -format png *.jpg' convert jpg to png

im = Image.open(file_name).convert('L')

im.save("/home/mzm/MNIST_recognize/sample.png")

plt.imshow(im)

plt.show()

tv = list(im.getdata()) #get pixel values

#normalize pixels to 0 and 1. 0 is pure white, 1 is pure black.

tva = [ (255-x)*1.0/255.0 for x in tv]

#print(tva)

return tva

"""

This function returns the predicted integer.

The imput is the pixel values from the imageprepare() function.

"""

# Define the model (same as when creating the model file)

result=imageprepare()

x = tf.placeholder(tf.float32, [None, 784])

W = tf.Variable(tf.zeros([784, 10]))

b = tf.Variable(tf.zeros([10]))

def weight_variable(shape):

initial = tf.truncated_normal(shape, stddev=0.1)

return tf.Variable(initial)

def bias_variable(shape):

initial = tf.constant(0.1, shape=shape)

return tf.Variable(initial)

def conv2d(x, W):

return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')

def max_pool_2x2(x):

return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')

W_conv1 = weight_variable([5, 5, 1, 32])

b_conv1 = bias_variable([32])

x_image = tf.reshape(x, [-1,28,28,1])

h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)

h_pool1 = max_pool_2x2(h_conv1)

W_conv2 = weight_variable([5, 5, 32, 64])

b_conv2 = bias_variable([64])

h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)

h_pool2 = max_pool_2x2(h_conv2)

W_fc1 = weight_variable([7 * 7 * 64, 1024])

b_fc1 = bias_variable([1024])

h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])

h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)

keep_prob = tf.placeholder(tf.float32)

h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)

W_fc2 = weight_variable([1024, 10])

b_fc2 = bias_variable([10])

y_conv=tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)

init_op = tf.initialize_all_variables()

"""

Load the model2.ckpt file

file is stored in the same directory as this python script is started

Use the model to predict the integer. Integer is returend as list.

Based on the documentatoin at

https://www.tensorflow.org/versions/master/how_tos/variables/index.html

"""

saver = tf.train.Saver()

with tf.Session() as sess:

sess.run(init_op)

saver.restore(sess, "/home/mzm/MNIST_recognize/form/model2.ckpt")#这里使用了之前保存的模型参数

#print ("Model restored.")

prediction=tf.argmax(y_conv,1)

predint=prediction.eval(feed_dict={x: [result],keep_prob: 1.0}, session=sess)

print(h_conv2)

print('recognize result:')

print(predint[0])

通过这个程序,得到最后的识别结果截图如下:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,902评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,037评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,978评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,867评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,763评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,104评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,565评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,236评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,379评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,313评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,363评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,034评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,637评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,719评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,952评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,371评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,948评论 2 341

推荐阅读更多精彩内容