tensorflow自主学习入门-从零开始篇(三)tensorflow手写数字识别加入隐藏层提高准...
本帖最后由 keepython 于 2019-8-20 19:44 编辑上一篇文章完成了简陋版的tensorflow手写数字实现((https://blog.csdn.net/weixin_43745588/article/details/99733205)),虽然简陋,但是总的能从中学到一些东西,现在又赶紧将自己前一段时间学习到的关于tensorflow手写数字的东西记录分享出来,以防遗忘。
当然,很大可能你看完上面的一篇文章还是不知所云晕头转向,没关系,接着看下去,这是必须要经过的阶段。当然,开始之前建议你在手机上设置一个30min的闹铃然后全神投入阅读这篇文章之中,相信对你会很有帮助。
***
本文我将在上一篇文章实现的基础之上对它进行改进,如果你成功的让上一篇的代码在你的机器上跑了起来,你就会发现,无论你怎样设置你的迭代次数,最后的Testing Accuracy(测试准确率)几乎不会超过93%,这也是简单模型的局限所在,本文我将进一步的优化它的代码以将其准确率提高至95%,但是重要的是借由优化代码我所想要表达与解释的东西。
将实现准确率提高的方法先提出来:在代码中加入隐藏层([关于隐藏层的定义](https://blog.csdn.net/sghgcn/article/details/1726709)目前知道即可)
***
为了兼顾文章的条理性与易于易理解性,不同于上一篇文章,本文将会分为两个部分,所以希望大家可以在阅读时将思路也分为这两部分作为参考:
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,)
y = tf.placeholder(tf.float32,)##输入的真是值的占位符
#创建一个简单的神经网络
#输入层
W1 = tf.Variable(tf.truncated_normal(,stddev=0.1))#初始化时一个非常重要的环节
b1 = tf.Variable(tf.zeros()+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(,stddev=0.1))#增加隐藏层设置2000个神经元,这里是故意定义一个复杂的神经网络
b2 = tf.Variable(tf.zeros()+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(,stddev=0.1))
b3 = tf.Variable(tf.zeros()+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,)
y = tf.placeholder(tf.float32,)##输入的真是值的占位符
#创建一个简单的神经网络
W1 = tf.Variable(tf.truncated_normal(,stddev=0.1))#初始化时一个非常重要的环节
b1 = tf.Variable(tf.zeros()+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(,stddev=0.1))#增加隐藏层设置2000个神经元,这里是故意定义一个复杂的神经网络
b2 = tf.Variable(tf.zeros()+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(,stddev=0.1))
b3 = tf.Variable(tf.zeros()+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('训练完成')
```
***
最后,希望本文对你有所帮助,接下来我会更新进一步优化将识别准确率提升到99%以上的文章,以及加入tensorboard可视化的文章,希望对你有所帮助。
楼主,你这排版怎么弄的,怎么把标题弄到左边{:301_1009:} One小白鼠 发表于 2019-8-20 19:51
楼主,你这排版怎么弄的,怎么把标题弄到左边
我用的markdown写的,再csdn上写的,然后粘贴到52,改掉一些违反版规的东西就好啦 楼主棒棒!学习了
页:
[1]