Tensorflow学习笔记:基础篇(6)——Mnist手写集改进版(Optimizer与Tensorboard)

Tensorflow学习笔记(6)——Mnist手写集改进版(Optimizer优化器与Tensorboard)


前序

— 前文中,我们将三层全连接神经网络的方差代价函数(二次代价函数)替换成交叉熵函数来完成MNIST数据的分类问题,最终迭代计算20次,准确率接近0.97,离我们预期的0.98甚至0.99依旧有差距。
— 本文我们在此基础上继续修改,主要有两个目标:
(1)选用合适的优化器进行梯度下降,观察准确率的变化~~
(2)开始使用Tensorboard
Reference:Tensorflow优化器比较


Tensorflow的优化器

Tensorflow中包含如下几个优化器:
tf.train.GradientDescentOptimizer
tf.train.AdadeltaOptimizer
tf.train.AdagradOptimizer
tf.train.AdagradDAOptimizer
tf.train.MomentumOptimizer
tf.train.AdamOptimizer
tf.train.FtrlOptimizer
tf.train.ProximalGradientDescentOptimizer
tf.train.ProximalAdagradOptimizer
tf.train.RMSPropOptimizer
这里写图片描述
Momentum:当前权值的改变会受到上一次权值改变的影响,类似于小球向下滚动的时候带上了惯性。这样可以加快小球的向下的速度。

NAG:在TF中跟Momentum合并在同一个函数tf.train.MomentumOptimizer中,可以通过参数配置启用。在Momentun中小球会盲目地跟从下坡的梯度,容易发生错误,所以我们需要一个更聪明的小球,这个小球提前知道它要去哪里,它还要知道走到坡底的时候速度慢下来而不是又冲上另一个坡,知道下一个位置大概在哪里。从而我们可以提前计算下一个位置的梯度,然后使用到当前位置。

Adagrad:它是基于SGD的一种算法,它的核心思想是对比较常见的数据给予它比较小的学习率去调整参数,对于比较罕见的数据给予它比较大的学习率去调整参数。它很适合应用于数据稀疏的数据集(比如一个图片数据集,有10000张狗的照片,10000张猫的照片,只有100张大象的照片)。Adagrad主要的优势在于不需要人为的调节学习率,它可以自动调节。它的缺点在于,随着迭代次数的增多,学习率也会越来越低,最终会趋向于0。

RMSprop:借鉴了一些Adagrad的思想,不过这里RMSprop只用到了前t-1次梯度平方的平均值加上当前梯度的平方的和的开平方作为学习率的分母。这样RMSprop不会出现学习率越来越低的问题,而且也能自己调节学习率,并且可以有一个比较好的效果。

Adadelta:我们甚至不需要设置一个默认学习率,在Adadelta不需要使用学习率也可以达到一个非常好的效果。

Adam:像Adadelta和RMSprop一样,Adam会存储之前衰减的平方梯度,同时它也会保存之前衰减的梯度。经过一些处理之后再使用类似Adadelta和RMSprop的方式更新参数。

本文采用的AdamOptimizer,同时会控制学习率的衰减,一开始速度很快,当越接近终点时,速度越来越慢。


Tensorboard

— 可视化是深度学习神经网络开发、调试、应用中极为重要的手段。当我们使用TensorFlow搭建深层神经网络时,我们希望能够了解整个网络的结构,信息是如何传递,想了解每次训练后权重值W与偏置值B是如何变化的,损失值、准确率的变化趋势,等等。如果有一个工具能够将这些数据直观的表现出来,是不是方便我们进行观察与调试呢,对模型有更深的理解呢~~
— Google推出的可视化工具Tensorboard,可以帮助我们实现以上功能,它可以将模型训练过程中的各种数据汇总起来保存在日志文件中,然后在指定的web端可视化地展现这些信息。
— 本文将带领大家完成日志文件的保存与成功打开Tensorboard。


代码示例

1、数据准备

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

# 载入数据集
mnist = input_data.read_data_sets("MNIST_data", one_hot=True)

# 每个批次送100张图片
batch_size = 100
# 计算一共有多少个批次
n_batch = mnist.train.num_examples // batch_size

2、准备好placeholder

这次我们在placeholder中加入name这项参数,这当然是为Tenseorboard做准备啦~~
这里为了刚才说的,实现学习率逐渐衰减的AdamOptimizer,这里我们建一个 lr 这一变量,命名为learning_rate,初始值设为0.01

x = tf.placeholder(tf.float32, [None, 784], name='x_input')
y = tf.placeholder(tf.float32, [None, 10], name='y_input')
lr = tf.Variable(0.001, dtype=tf.float32, name='learning_rate')

3、初始化参数/权重

这里我将所有的权重与偏置也都命名,可以尝试一下,如果不命名会发生什么~~

W1 = tf.Variable(tf.truncated_normal([784, 500], stddev=0.1), name='W1')
b1 = tf.Variable(tf.zeros([500]) + 0.1, name='b1')
L1 = tf.nn.tanh(tf.matmul(x, W1) + b1, name='L1')

W2 = tf.Variable(tf.truncated_normal([500, 300], stddev=0.1), name='W2')
b2 = tf.Variable(tf.zeros([300]) + 0.1, name='b2')
L2 = tf.nn.tanh(tf.matmul(L1, W2) + b2, name='L2')

W3 = tf.Variable(tf.truncated_normal([300, 10], stddev=0.1), name='W3')
b3 = tf.Variable(tf.zeros([10]) + 0.1, name='b3')

4、计算预测结果

prediction = tf.nn.softmax(tf.matmul(L2, W3) + b3)

5、计算损失值

# 二次代价函数
# loss = tf.reduce_mean(tf.square(y - prediction))
# 交叉熵代价函数
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=prediction))

6、初始化optimizer

这里我们用tf.train.AdamOptimizer() 替代tf.train.GradientDescentOptimizer()

#learning_rate = 0.2
#optimizer =  tf.train.GradientDescentOptimizer(learning_rate).minimize(loss)
optimizer = tf.train.AdamOptimizer(lr).minimize(loss)

# 结果存放在一个布尔型列表中
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(prediction, 1))  

# 求准确率
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

7、指定迭代次数,并在session执行graph

Tensorboard的可视化需要建立一个graph,你想从这个graph中获取某些数据的信息,之后,我们使用tf.summary.FileWriter()将运行后输出的数据文件都保存到本地磁盘(自己设定的文件路径)中,我这里选择的是在这个程序文件的同目录下,生成一个graphs文件夹,其中又会个名为mnist的文件夹,生成的数据文件将保存在mnist文件夹中。

init = tf.global_variables_initializer()

with tf.Session() as sess:
    sess.run(init)
    writer = tf.summary.FileWriter('./graphs/mnist', sess.graph)

    for epoch in range(21):
        sess.run(tf.assign(lr, 0.001 * (0.95 ** epoch)))
        #这句语句,就是实现每次迭代后,学习率逐渐衰减,在最初开始的0.01基础上,乘以0.95的迭代次数epoch次幂
        for batch in range(n_batch):
            batch_xs, batch_ys = mnist.train.next_batch(batch_size)
            sess.run(optimizer, feed_dict={x: batch_xs, y: batch_ys})

        test_acc = sess.run(accuracy, feed_dict={x: mnist.test.images, y: mnist.test.labels})
        learning_rate = sess.run(lr)
        if epoch % 2 == 0:
            print("Iter" + str(epoch) + ", Testing accuracy:" + str(test_acc) + ", Learning rate:" + str(learning_rate))
            #这里我们每次输出准确率的同时,输出学习率

    writer.close()#最后别忘了将写入文件操作关闭

运行结果

迭代计算依旧为20次,准确率首次踏上了0.98,同时学习率按照我们的预期想法,随迭代次数衰减,越接近结果时,学习率越来越慢。
这里写图片描述
同时我们在graphs/mnist文件夹中生成了一个数据文件,顺便说一下,这次我是用Macbook写的,之前都是windows,大家不要觉得奇怪~~
这里写图片描述
接下来我们要做的就是打开Tensorboard,在Macbook中打开终端输入tensorboard –logdir=(logdir是两个短横!!!,不是一长横
随后将数据文件拖进终端页面中,就会自动生成文件路径,就像这样:
这里写图片描述
之后,我们将文件名删除,只留下文件夹路径即可,然后敲回车,就会出现这个画面:
这里写图片描述
将其中的http://appledeMacBook-Pro-3.local:6006 复制到你的谷歌浏览器中即可(其他浏览器可能会出错,毕竟这是google家的,你懂得~~,)
这里写图片描述
恭喜你,你已经成功打开了Tensorboard,好了下一篇我将重点讲述Tensorboard的使用。


完整代码

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

mnist = input_data.read_data_sets("MNIST_data", one_hot=True)

# 每个批次的大小
batch_size = 100
# 计算一共有多少个批次
n_batch = mnist.train.num_examples // batch_size

x = tf.placeholder(tf.float32, [None, 784], name='x_input')
y = tf.placeholder(tf.float32, [None, 10], name='y_input')
lr = tf.Variable(0.001, dtype=tf.float32, name='learning_rate')


W1 = tf.Variable(tf.truncated_normal([784, 500], stddev=0.1), name='W1')
b1 = tf.Variable(tf.zeros([500]) + 0.1, name='b1')
L1 = tf.nn.tanh(tf.matmul(x, W1) + b1, name='L1')

W2 = tf.Variable(tf.truncated_normal([500, 300], stddev=0.1), name='W2')
b2 = tf.Variable(tf.zeros([300]) + 0.1, name='b2')
L2 = tf.nn.tanh(tf.matmul(L1, W2) + b2, name='L2')

W3 = tf.Variable(tf.truncated_normal([300, 10], stddev=0.1), name='W3')
b3 = tf.Variable(tf.zeros([10]) + 0.1, name='b3')
prediction = tf.nn.softmax(tf.matmul(L2, W3) + b3)

loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=prediction))


# 梯度下降
#optimizer = tf.train.GradientDescentOptimizer(0.2).minimize(loss)
optimizer = tf.train.AdamOptimizer(lr).minimize(loss)


correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(prediction, 1))

accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

init = tf.global_variables_initializer()

with tf.Session() as sess:
    sess.run(init)
    writer = tf.summary.FileWriter('./graphs/mnist', sess.graph)

    for epoch in range(21):
        sess.run(tf.assign(lr, 0.001 * (0.95 ** epoch)))

        for batch in range(n_batch):
            batch_xs, batch_ys = mnist.train.next_batch(batch_size)
            sess.run(optimizer, feed_dict={x: batch_xs, y: batch_ys})

        test_acc = sess.run(accuracy, feed_dict={x: mnist.test.images, y: mnist.test.labels})
        learning_rate = sess.run(lr)

        if epoch % 2 == 0:
            print("Iter" + str(epoch) + ", Testing accuracy:" + str(test_acc) + ", Learning rate:" + str(learning_rate))

    writer.close()

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章