识别图中模糊手写数字

一 实例
识别图中模糊手写数字

二 代码
import tensorflow as tf #导入tensorflow库
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
import pylab
tf.reset_default_graph()
# tf Graph Input
'''
由于输入图片是个55000X784的矩阵,所所以先创建一个[None, 784]的占位符x和一个[None, 10]的占位符y
然后使用feed机制将图片和标签输入进去
下面两行代码中的None,表示此张量的第一维度可以是任何长度的。x就代表能够输入任意数量的MNIST图像,每一张图展平成784维的向量。
'''
x = tf.placeholder(tf.float32, [None, 784]) # mnist data维度 28*28=784
y = tf.placeholder(tf.float32, [None, 10]) # 0-9 数字=> 10 classes
'''
模型也需要权重值和偏执量,它们被统一叫做学习参数。在TensorFlow里,使用Variable来定义学习参数。
一个Variable代表一个可修改的张量,定义在TensorFlow的图中,其本身也是一种变量。
使用Variable定义的学习参数可以用于计算输入值,也可以在计算中被修改。
这里赋予tf.Variable不同的初值来创建不同的参数。一般将W设为一个随机值,将b设为0.
'''
# Set model weights
W = tf.Variable(tf.random_normal([784, 10]))
b = tf.Variable(tf.zeros([10]))
# 构建模型
'''
首先,用tf.matmul(x, W)表示x乘以W,这里x是一个二维张量,拥有多个输入。然后再加上b,把它们的和输入到softmax函数里。
至此就构建好了正向传播的结构。也就是表面,只要模型中的参数合适,通过具体的数据输入,就能得到我们想要的分类。
'''
pred = tf.nn.softmax(tf.matmul(x, W) + b) # Softmax分类
'''
定义一个反向传播的结构,编译训练模型,以得到合适的参数。
下面这段代码这样理解
1 将生成的pred与样本标签y进行一次交叉熵的运算,然后取平均值。
2 将这个结果作为一次正向传播的误差,通过梯度下降的优化方法找到能够使这个误差最小化的b和W的偏移量。
3 更新b和W,使其调整为合适的参数。
整个过程就是不断让损失值(误差值cost)变小。因为损失值越小,才能表明输出的结果跟标签数据越相近。当cost小到我们需求时,这时的b和W就是训练出来的合适值。
'''
# Minimize error using cross entropy,损失函数
cost = tf.reduce_mean(-tf.reduce_sum(y*tf.log(pred), reduction_indices=1))
#参数设置
'''
这里涉及一个"学习率"的概念。学习率,是指每次改变学习参数的大小。
'''
learning_rate = 0.01
# 使用梯度下降优化器
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)
'''
training_epochs代表要把整个训练样本集迭代25次
batch_size代表在训练过程中一次取100条数据进行训练
display_step每训练一次把具体中间状态显示出来。
session中有两个run,第一个run是运行初始化,第二个run是运行具体的运算模型。
模型之后便是里面的状态。
'''
training_epochs = 25
batch_size = 100
display_step = 1
saver = tf.train.Saver()
model_path = "log/521model.ckpt"
# 启动session
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())# Initializing OP
    # 启动循环开始训练
    for epoch in range(training_epochs):
        avg_cost = 0.
        total_batch = int(mnist.train.num_examples/batch_size)
        # 遍历全部数据集
        for i in range(total_batch):
            batch_xs, batch_ys = mnist.train.next_batch(batch_size)
            # Run optimization op (backprop) and cost op (to get loss value)
            _, c = sess.run([optimizer, cost], feed_dict={x: batch_xs,
                                                          y: batch_ys})
            # Compute average loss
            avg_cost += c / total_batch
        # 显示训练中的详细信息
        if (epoch+1) % display_step == 0:
            print ("Epoch:", '%04d' % (epoch+1), "cost=", "{:.9f}".format(avg_cost))
    print( " Finished!")
    # 测试 model
    correct_prediction = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))
    # 计算准确率
'''
测试错误率的算法是:直接判断预测的结果与真实的标签是否相同,如果相同的就表示是正确的,如果不相同就表示是错误的。然后将正确的个数除以总个数,得到的值即为正确率。由于onehot编码,这里使用了tf.argmax函数返回onehot编码中数值为1元素下标。
测试正确率的算法与损失值的算法略有不同,但代表的意义却很类似。当然,也可以直接拿损失值的交叉熵结果来代表模型测试的错误率。
'''
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    print ("Accuracy:", accuracy.eval({x: mnist.test.images, y: mnist.test.labels})) 
   # Save model weights to disk
    save_path = saver.save(sess, model_path)
    print("Model saved in file: %s" % save_path)
#读取模型
'''
读取模型并将两张图片放进去让模型预测结果,然后将两张图及其对应的标签一并显示出来。
'''
print("Starting 2nd session...")
with tf.Session() as sess:
    # Initialize variables
    sess.run(tf.global_variables_initializer())
    # Restore model weights from previously saved model
    saver.restore(sess, model_path)
     # 测试 model
    correct_prediction = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))
    # 计算准确率
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    print ("Accuracy:", accuracy.eval({x: mnist.test.images, y: mnist.test.labels}))
    
    output = tf.argmax(pred, 1)
    batch_xs, batch_ys = mnist.train.next_batch(2)
    outputval,predv = sess.run([output,pred], feed_dict={x: batch_xs})
    print(outputval,predv,batch_ys)
    im = batch_xs[0]
    im = im.reshape(-1,28)
    pylab.imshow(im)
    pylab.show()
    
    im = batch_xs[1]
    im = im.reshape(-1,28)
    pylab.imshow(im)
三 运行结果
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
Epoch: 0001 cost= 7.858615231
Epoch: 0002 cost= 4.281104081
Epoch: 0003 cost= 2.983453018
Epoch: 0004 cost= 2.376332026
Epoch: 0005 cost= 2.032362357
Epoch: 0006 cost= 1.808627782
Epoch: 0007 cost= 1.649085030
Epoch: 0008 cost= 1.528221663
Epoch: 0009 cost= 1.432857099
Epoch: 0010 cost= 1.354939125
Epoch: 0011 cost= 1.289974567
Epoch: 0012 cost= 1.234893327
Epoch: 0013 cost= 1.187199105
Epoch: 0014 cost= 1.145635491
Epoch: 0015 cost= 1.108765103
Epoch: 0016 cost= 1.075907613
Epoch: 0017 cost= 1.046485638
Epoch: 0018 cost= 1.019601378
Epoch: 0019 cost= 0.995143512
Epoch: 0020 cost= 0.972762282
Epoch: 0021 cost= 0.952079509
Epoch: 0022 cost= 0.932801402
Epoch: 0023 cost= 0.915190343
Epoch: 0024 cost= 0.898526331
Epoch: 0025 cost= 0.882988903
Finished!
Accuracy: 0.8294
Model saved in file: log/521model.ckpt
四 说明
第一个数组是输出的预测结果。
第二个大的数组比较大,是预测出来的真实输出值。
第三个大的数组都是0和1,是标签值onehot编码,表示8和9.

注意:这里恰巧举了一个全部正确的例子,因为还有0.18的错误率,所有有时也会预测错误。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值