tensorflow自主学习入门-从零开始篇(三)tensorflow手写数字识别加入隐藏层提高准确率

上一篇文章完成了简陋版的tensorflow手写数字实现(tensorflow自主学习入门-从零开始篇(二)tensorflow手写数字识别),虽然简陋,但是总的能从中学到一些东西,现在又赶紧将自己前一段时间学习到的关于tensorflow手写数字的东西记录分享出来,以防遗忘。

当然,很大可能你看完上面的一篇文章还是不知所云晕头转向,没关系,接着看下去,这是必须要经过的阶段。当然,开始之前建议你在手机上设置一个30min的闹铃然后全神投入阅读这篇文章之中,相信对你会很有帮助。


本文我将在上一篇文章实现的基础之上对它进行改进,如果你成功的让上一篇的代码在你的机器上跑了起来,你就会发现,无论你怎样设置你的迭代次数,最后的Testing Accuracy(测试准确率)几乎不会超过93%,这也是简单模型的局限所在,本文我将进一步的优化它的代码以将其准确率提高至95%,但是重要的是借由优化代码我所想要表达与解释的东西。

将实现准确率提高的方法先提出来:在代码中加入隐藏层(关于隐藏层的定义目前知道即可)


为了兼顾文章的条理性与易于易理解性,不同于上一篇文章,本文将会分为两个部分,所以希望大家可以在阅读时将思路也分为这两部分作为参考:

  1. 代码部分 相比上篇文章的修改部分
  2. 你需要知道、理解的部分,以及建议你必须完成的部分
  3. 代码汇总

一 、代码部分

经过思考最终决定本文的代码部分将被放置于第一部分,因为想要通过本文学习到东西,绝对需要对比上一篇文章的代码与本文代码的异同,甚至如果有必要可以逐行分析,这一点非常重要


加载MNIST数据,导入所需模块

不同于上一篇文章,你会发现本次额外导入 time 模块,它将被用于记录我们模型训练最终所用时间,为了方便以后不同策略方法之间的对比,time模块将会是标配。

本代码其余部分无变化

from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
import time#用于获取迭代运行时间,比较不同方案
#加载数据
mnist  = input_data.read_data_sets("MNIST_data",one_hot=True)

构建模型添加隐藏层

首先,这里的代码分块的非常清晰,认真分析后你会发现,与上一篇文章的这一部分不同的是,我只在这里定义了x 与 y 两个placeholder,这里x用于传mnist.train.images ,而 y 用于传入 mnist.train.labels

因此在这里的y 相当于上一篇文章的 y_ 理解这一点相当重要,此外这里还有一个kepp_prob,如果你是用的pycharm的话,你就会发现他的最终去向tf.nn.dropout中的一个参数,关于他的作用代码中有解释,详细可以搜索。

第二点,相比于上一篇文章w 和 两个被定义为tf.Variable ,本文中他们被分解为 (W1 、W2 、W3 )和 (b1 、b2 、b3)并最终转化为W3 、 b3 ,进行运算。

第三点,关于这里的2000一定需要进行理解,与他相关的数学知识是矩阵乘法,这里是指2000个 神经元,但是过多的神经元也会造成运算时间变慢以及过拟合的情况,这就用到了我们定义的keep_prob,详细代码注释中会解释。

#定义回归模型
keep_prob=tf.placeholder(tf.float32)
x = tf.placeholder(tf.float32,[None,784])
y = tf.placeholder(tf.float32,[None,10])##输入的真是值的占位符
#创建一个简单的神经网络
#输入层
W1 = tf.Variable(tf.truncated_normal([784,2000],stddev=0.1))#初始化时一个非常重要的环节
b1 = tf.Variable(tf.zeros([2000])+0.1)
L1 = tf.nn.tanh(tf.matmul(x,W1)+b1)#使用双曲正切
L1_drop = tf.nn.dropout(L1,keep_prob) #tensorflow封装好的dropout函数,L1是我们需要控制的神经元,keep_prob是工作的神经元的百分比
#注意使用dropout后会使模型的训练速度下降

W2 = tf.Variable(tf.truncated_normal([2000,1000],stddev=0.1))#增加隐藏层设置2000个神经元,这里是故意定义一个复杂的神经网络
b2 = tf.Variable(tf.zeros([1000])+0.1)#期望其出项过度拟合的情况
L2 = tf.nn.tanh(tf.matmul(L1_drop,W2)+b2)
L2_drop = tf.nn.dropout(L2,keep_prob)
#输出层
W3 = tf.Variable(tf.truncated_normal([1000,10],stddev=0.1))
b3 = tf.Variable(tf.zeros([10])+0.1)
#注意这里的知识点是tensorflow中矩阵相乘的规则
prediction = tf.nn.softmax(tf.matmul(L2_drop,W3)+b3)

loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y,logits=prediction))#损失函数
#tf.nn.softmax_cross_entropy_with_logits(logits, labels, name=None)
#除去name参数用以指定该操作的name,与方法有关的一共两个参数:
#第一个参数logits:就是神经网络最后一层的输出,未经过soft_max
#第二个参数labels:实际的标签,需要是one-hot格式

构建评估模型

这一部分没有变化,我只是将它做的更加的精简,这里的优化器依然使用
tf.train.GradientDescentOptimizer梯度下降法,设置学习率为0.01让loss损失函数最小化


#定义损失函数和优化器
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(loss)
#评估训练好的模型
correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(prediction,1))#计算预测值和真实值
#计算模型在测试集上的准确率
#tf.cast作用:布尔型转化为浮点数,并且取平均值,得到准确率
accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
init = tf.global_variables_initializer()

构建评估模型

这里有两点与上一篇文章不同

  1. 加入time.clock()用于记录程序运行时间
  2. 迭代次数降低至100次,但是准确率大幅上升
start = time.clock()
with tf.Session() as sess:
    sess.run(init)
    for i in range(101):
        bath_xs, bath_ys = mnist.train.next_batch(100)
        #注意这里不同于上一部分的是模型需要传入的参数增加了keep_prob(需要运行的神经元的数量)
        sess.run(train_step, feed_dict={x:bath_xs,y:bath_ys,keep_prob:0.7})
        if i % 10 == 0:
            acc = sess.run(accuracy, feed_dict={x:mnist.test.images, y: mnist.test.labels,keep_prob:1})
            print("Iter " + str(i) + ",Testing Accuracy " + str(acc))
end = time.clock()
print('Running time: %s Seconds'%int(end-start))
print('训练完成')

二 、建议你必须完成的部分

  • 认真读完本文文章后返回上一篇文章再读一遍
  • 将两次的代码分别打开,对比每一部分(建议使用pycharm)
  • 用一张纸列下两次代码的不同点(不是很多,难度不大,但是需要形成自己的思考)
  • 使本文的代码再自己的机器上跑起来
  • 推荐去看看优化器相关知识,学有余力可以开始尝试使用自己的方法提高准确率(Test accuracy)

三 、代码汇总

上代码:


from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
import time#用于获取迭代运行时间,比较不同方案
#加载数据
mnist  = input_data.read_data_sets("MNIST_data",one_hot=True)
#定义回归模型
keep_prob=tf.placeholder(tf.float32)
x = tf.placeholder(tf.float32,[None,784])
y = tf.placeholder(tf.float32,[None,10])##输入的真是值的占位符
#创建一个简单的神经网络

W1 = tf.Variable(tf.truncated_normal([784,2000],stddev=0.1))#初始化时一个非常重要的环节
b1 = tf.Variable(tf.zeros([2000])+0.1)
L1 = tf.nn.tanh(tf.matmul(x,W1)+b1)#使用双曲正切
L1_drop = tf.nn.dropout(L1,keep_prob) #tensorflow封装好的dropout函数,L1是我们需要控制的神经元,keep_prob是工作的神经元的百分比
#注意使用dropout后会使模型的训练速度下降

W2 = tf.Variable(tf.truncated_normal([2000,1000],stddev=0.1))#增加隐藏层设置2000个神经元,这里是故意定义一个复杂的神经网络
b2 = tf.Variable(tf.zeros([1000])+0.1)#期望其出项过度拟合的情况
L2 = tf.nn.tanh(tf.matmul(L1_drop,W2)+b2)
L2_drop = tf.nn.dropout(L2,keep_prob)

W3 = tf.Variable(tf.truncated_normal([1000,10],stddev=0.1))
b3 = tf.Variable(tf.zeros([10])+0.1)
#注意这里的知识点是tensorflow中矩阵相乘的规则
prediction = tf.nn.softmax(tf.matmul(L2_drop,W3)+b3)

loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y,logits=prediction))#损失函数
#tf.nn.softmax_cross_entropy_with_logits(logits, labels, name=None)
#除去name参数用以指定该操作的name,与方法有关的一共两个参数:
#第一个参数logits:就是神经网络最后一层的输出,未经过soft_max
#第二个参数labels:实际的标签,需要是one-hot格式

#定义损失函数和优化器
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(loss)
#评估训练好的模型
correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(prediction,1))#计算预测值和真实值
#计算模型在测试集上的准确率
#tf.cast作用:布尔型转化为浮点数,并且取平均值,得到准确率
accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))


init = tf.global_variables_initializer()

#Train开始训练
start = time.clock()
with tf.Session() as sess:
    sess.run(init)
    for i in range(51):
        bath_xs, bath_ys = mnist.train.next_batch(100)
        #注意这里不同于上一部分的是模型需要传入的参数增加了keep_prob(需要运行的神经元的数量)
        sess.run(train_step, feed_dict={x:bath_xs,y:bath_ys,keep_prob:0.7})
        if i % 10 == 0:
            acc = sess.run(accuracy, feed_dict={x:mnist.test.images, y: mnist.test.labels,keep_prob:1})
            print("Iter " + str(i) + ",Testing Accuracy " + str(acc))
end = time.clock()
print('Running time: %s Seconds'%int(end-start))
print('训练完成')


最后,我希望大家有问题可以私信问我,我会很愿意帮你解答,毕竟,这就是在以一种很有效率的方式帮助我的学习,加深我对它的理解,需要加好友提问的朋友可以留言QQ。

希望本文对你有所帮助,接下来我会更新进一步优化将识别准确率提升到99%以上的文章,以及加入tensorboard可视化的文章,希望对你有所帮助。

发布了18 篇原创文章 · 获赞 18 · 访问量 2854

猜你喜欢

转载自blog.csdn.net/weixin_43745588/article/details/99867942