MNIST 手写识别 + Tensorflow 框架

按着 Tensorflow 中文社区 的步骤,尝试用Tensorflow 框架进行了 mnist 手写识别的测试,算是简单入门了,记录一下。

python: 3.6.0
tensorflow : 1.4.0

1.原版程序

先放出原版的程序:
一共需要两个 python 文件,分别为 input_data.pymyFirstTensorflow.py (这个文件可以自己命名)

input_data.py 代码如下:

# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================

"""Functions for downloading and reading MNIST data."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import gzip
import os
import tempfile

import numpy
from six.moves import urllib
from six.moves import xrange  # pylint: disable=redefined-builtin
import tensorflow as tf
from tensorflow.contrib.learn.python.learn.datasets.mnist import read_data_sets

在 第二个 python 文件 myFirstTensorflow.py 里会引用到这个文件,进行数据导入。如果当前目录下没有数据文件,会从指定连接中先下载数据文件,再进行数据导入,如果当前目录中有相应的数据文件(一共4个,名字分别为:
train-images-idx3-ubyte.gz:训练数据的图像信息
train-labels-idx1-ubyte.gz:训练数据的标签
t10k-images-idx3-ubyte.gz: 测试数据的图像信息
t10k-labels-idx1-ubyte.gz: 测试数据的标签
)则直接进行数据导入。
可能是因为国内有墙的缘故,如果本地没有上面四个数据文件,执行下载的时候会出现无法连接的情况,所以还是先将这四个数据文件下载下来会比较方便,这里提供一个通道 给大家进行文件下载。

myFirstTensorflow.py 代码如下:

import tensorflow as tf
import gzip
import struct
import numpy as np
import input_data
mnist = input_data.read_data_sets('MNIST_data',one_hot=True)

# None表示此张量的第一个维度可以是任何长度的
x = tf.placeholder("float",[None,784])

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

# 计算值
y = tf.nn.softmax(tf.matmul(x,W) + b) # matmul 表示矩阵相乘
# 真实值
y_=tf.placeholder("float",[None,10])
# 计算交叉熵
cross_entropy = -tf.reduce_sum(y_ * tf.log(y))
# 用梯度下降法 以0.01 的学习速度最小化交叉熵
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)

# 初始化所创建的变量
init = tf.initialize_all_variables()

# 在 session 里面启动模型,初始化变量
sess = tf.Session()
sess.run(init)

for i in range(1000):
    batch_xs, batch_ys = mnist.train.next_batch(100)
    sess.run(train_step,feed_dict={x:batch_xs,y_:batch_ys})

correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(y_,1))
# resultList = tf.cast(correct_prediction,"float")
# resultMean = tf.reduce_sum( resultList) / len(val_lbl)
accuracy = tf.reduce_mean(tf.cast(correct_prediction,"float"))
print(sess.run(accuracy,feed_dict={x: mnist.test.images, y_: mnist.test.labels})) 

我是在windows 10 的环境下进行编码和运行 的,执行结果如下:

Extracting MNIST_data\train-images-idx3-ubyte.gz
Extracting MNIST_data\train-labels-idx1-ubyte.gz
Extracting MNIST_data\t10k-images-idx3-ubyte.gz
Extracting MNIST_data\t10k-labels-idx1-ubyte.gz
WARNING:tensorflow:From C:\Users\admin\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow\python\util\tf_should_use.py:107: initialize_all_variables (from tensorflow.python.ops.variables) is deprecated and will be removed after 2017-03-02.
Instructions for updating:
Use `tf.global_variables_initializer` instead.
2018-01-31 15:45:13.495186: I C:\tf_jenkins\home\workspace\rel-win\M\windows\PY\36\tensorflow\core\platform\cpu_feature_guard.cc:137] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX AVX2
0.922

准确率一般在0.91多左后,跟 Tensorflow 中文社区 上面说的差不多。到此,程序的 copy 实现就成功了。下面我将自己对数据进行读入和修改,虽然程序大致跟原版程序相同,但作一些小修改,更能弄懂其中的来龙去脉

2.我的版本

我的版本只有一个python文件,就叫 myFirstTensorflow2.py 吧,代码如下:

import tensorflow as tf
import gzip
import struct
import numpy as np

x = tf.placeholder("float",[None,784])
W = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))

# 计算值
y = tf.nn.softmax(tf.matmul(x,W) + b) # matmul 表示矩阵相乘
# 真实值
y_=tf.placeholder("float",[None,10])
# 计算交叉熵
cross_entropy = -tf.reduce_sum(y_ * tf.log(y))
# 用梯度下降法 以0.01 的学习速度最小化交叉熵
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)

# 初始化所创建的变量
init = tf.initialize_all_variables()

# 在 session 里面启动模型,初始化变量
sess = tf.Session()
sess.run(init)

# 读入数据
def read_data(label_url,image_url):
    with gzip.open(label_url) as flbl:
        magic, num = struct.unpack(">II",flbl.read(8))
        label = np.fromstring(flbl.read(),dtype=np.int8)
    with gzip.open(image_url,'rb') as fimg:
        magic, num, rows, cols = struct.unpack(">IIII",fimg.read(16))
        image = np.fromstring(fimg.read(),dtype=np.uint8).reshape(len(label),rows,cols)
    return (label, image)

# 训练集的数据
(train_lbl, train_img) = read_data('train-labels-idx1-ubyte.gz','train-images-idx3-ubyte.gz')
# 验证集的数据
(val_lbl, val_img) = read_data('t10k-labels-idx1-ubyte.gz','t10k-images-idx3-ubyte.gz')
print("读取数据完成")

def next(batch_id,batch_size,data,labels):
    if batch_id == len(data):
        batch_id = 0
    batch_data =  (data[batch_id:min(batch_id +batch_size, len(data))])
    batch_labels = (labels[batch_id:min(batch_id + batch_size, len(data))])
    batch_id = min(batch_id + batch_size, len(data))
    return batch_data,batch_labels,batch_id

batch_id = 0
for i in range(1000):
    batch_xs , batch_ys,batch_id =next(batch_id,100,train_img,train_lbl)
    batch_xs = batch_xs.reshape(batch_xs.shape[0],784).astype(np.float32)/255
    yt = []
    for p in batch_ys:
        yl = np.zeros(10)
        yl[p] = 1
        yt.append(yl)
    batch_ys = np.array(yt)
    sess.run(train_step,feed_dict={x:batch_xs,y_:batch_ys})

val_img = val_img.reshape(val_img.shape[0],784).astype(np.float32)/255
yt = []
for p in val_lbl:
    yl = np.zeros(10)
    yl[p] = 1
    yt.append(yl)
val_lbl = np.array(yt)

correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction,"float"))
print(sess.run(accuracy,feed_dict={x:val_img,y_:val_lbl})) 

其实改动的地方很小,整理的网络结构是没有变化的,改变的只是数据的读入和数据的变型,都由我自己来控制。原版中有一个 mnist.train.next_batch() 的函数,是从数据集中取出一个 batch 的数据来投入到模型中进行拟合,所以我也要写一个类似的 next 函数实现相应的功能。
运行结果:

Extracting MNIST_data\train-images-idx3-ubyte.gz
Extracting MNIST_data\train-labels-idx1-ubyte.gz
Extracting MNIST_data\t10k-images-idx3-ubyte.gz
Extracting MNIST_data\t10k-labels-idx1-ubyte.gz
WARNING:tensorflow:From C:\Users\admin\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow\python\util\tf_should_use.py:107: initialize_all_variables (from tensorflow.python.ops.variables) is deprecated and will be removed after 2017-03-02.
Instructions for updating:
Use `tf.global_variables_initializer` instead.
2018-01-31 16:04:58.653538: I C:\tf_jenkins\home\workspace\rel-win\M\windows\PY\36\tensorflow\core\platform\cpu_feature_guard.cc:137] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX AVX2
0.9165

准确率也是0.90~0.91 多之间,可以说自己动手实现算法成功了吧(才不是!!只是简单搭建框架的过程弄懂了而已^_^)

上面代码执行结果中有两个警告:

1.

WARNING:tensorflow:From C:\Users\admin\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow\python\util\tf_should_use.py:107: initialize_all_variables (from tensorflow.python.ops.variables) is deprecated and will be removed after 2017-03-02.
Instructions for updating:
Use `tf.global_variables_initializer` instead.

initialize_all_variables 这个函数被取消啦,在2017-3-2 日以后就会被移除啦,之后就不能用啦(但是为什么还是能执行。。。),推荐你使用 tf.global_variables_initializer,所以改成它推荐的函数也就好了。
我在学习的过程中很多时候也遇到,网上的代码已经不能用了的问题,原因可能就是 tensorflow 新的版本的api改变了,所以要注意一下版本的问题。

2.

cpu_feature_guard.cc:137] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX AVX2

这个警告是说 : 你的CPU 支持使用AVX AVX2 ,但这个 Tensorflow 文件没有使用它们 (大概这个意思是吗。。。)
加入一下两行代码在前面就可以忽略这个警告了

import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'

现在这个识别准确率其实很是很差的,一般比较好的识别率都在98%~99%,kaggle 上还有大神能达到100%的识别率的,所以还是要多学习学习啊!!

转载请标明出处: http://blog.csdn.net/gl_4433/article/details/79218579

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值