【TensorFlow】学习率、迭代次数和初始化方式对准确率的影响

想必学过机器学习的人都知道,学习率、训练迭代次数和模型参数的初始化方式都对模型最后的准确率有一定的影响,那么影响到底有多大呢?

我初步做了个实验,在 TensorFlow 框架下使用 Logistics Regression 对经典的 MNIST 数据集进行分类。

本文所说的 准确率 均指 测试准确率

代码

from tensorflow.examples.tutorials.mnist import input_data

mnist = input_data.read_data_sets("/home/alan/data/", one_hot=True)

from __future__ import print_function
import tensorflow as tf
import matplotlib.pyplot as plt
# 如果运行提示没有seaborn库,可以注释掉这行代码
# 也可以使用 pip install seaborn或者 conda install seaborn安装
import seaborn
# 我是在Jupyter Notebook下运行的
# 如果你是在命令行运行那么就注释掉下面这一行
%matplotlib inline

# 设置模型
# 学习率
learning_rate = 0.01
# 训练迭代次数
training_epochs = 50
# batch大小
batch_size = 100
# 每多少次迭代显示一次损失
display_step = 1

x = tf.placeholder(tf.float32, [None, 784])
y = tf.placeholder(tf.float32, [None, 10])

# 模型参数
# W = tf.Variable(tf.zeros([784, 10]))
# b = tf.Variable(tf.zeros([10]))
W = tf.Variable(tf.truncated_normal([784, 10]))
b = tf.Variable(tf.truncated_normal([10]))

# 建立模型
pred = tf.nn.softmax(tf.matmul(x, W) + b)

# 定义损失函数:交叉熵
cost = tf.reduce_mean(-tf.reduce_sum(y*tf.log(pred), reduction_indices=1))

# 梯度下降
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)

# 初始化所有变量
init = tf.initialize_all_variables()

# 训练模型
with tf.Session() as sess:
    sess.run(init)

    ax1 = plt.subplot(211)
    ax1.set_ylabel("Accuracy")
    ax2 = plt.subplot(212, sharex=ax1)
    ax2.set_ylabel("Cost")
    ax2.set_xlabel("Epoch")
    plt.setp(ax1.get_xticklabels(), visible=False)

    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)
            _, c = sess.run([optimizer, cost], feed_dict={x: batch_xs, y: batch_ys})

            avg_cost += c / total_batch

        if (epoch + 1) % display_step == 0:
             # 计算测试准确率
            correct_prediction = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))
            accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

            ax1.plot(epoch+1, accuracy.eval({x: mnist.test.images, y: mnist.test.labels}), 'mo')
            ax2.plot(epoch+1, avg_cost, 'co') 

            print("Epoch:", '%04d' % (epoch+1), "cost=", '{:.9f}'.format(avg_cost), end=' ')
            print("Accuracy:", accuracy.eval({x: mnist.test.images, y: mnist.test.labels}))

    print("Optimization Finished!")

    print("Accuracy:", accuracy.eval({x: mnist.test.images, y: mnist.test.labels}))
    plt.suptitle("learning rate=%f, training epochs=%i, with tf.truncated_normal()" % (learning_rate, training_epochs), size=14)
    plt.savefig('AC8.png', dpi=300)
    plt.show()

通过修改 learning_ratetraining_epochs来修改学习率和迭代次数,修改

# 所有变量初始化为0
# W = tf.Variable(tf.zeros([784, 10]))
# b = tf.Variable(tf.zeros([10]))

# 所有变量初始化为符合标准截断正态分布的随机数
W = tf.Variable(tf.truncated_normal([784, 10]))
b = tf.Variable(tf.truncated_normal([10]))

来修改变量的初始化方式。程序最终会输出损失和准确率随着迭代次数的变化趋势图。

结果

以下结果的背景是:TensorFlow,Logistics Regression,MNIST数据集,很可能换一个数据集下面的结论中的某一条就不成立啦,所以要具体情况具体分析,找到最优的超参数组合。

多次的更改会输出多个不同的图,我们先来看下最终的准确率比较,然后再看下每种情况的详细的损失和准确率变化。

符号说明

  • lr:Learning Rate,学习率
  • te:Training Epochs,训练迭代次数
  • ztf.zeros(),变量初始化为0
  • ttf.truncated_normal(),变量初始化为标准截断正态分布的随机数

最终准确率比较

可以看到

  • 学习率为0.1,迭代次数为50次,并且采用随机初始化方式时准确率远远低于其他方式,甚至不足90%。而学习率为0.1,迭代次数为50次,并且采用随机初始化的方式时准确率最高。
  • 对于采用随机初始化的方式,在其他参数相同的情况下增大迭代次数会明显的提高准确率。而对于初始化为0的情况则无明显变化。
  • 其他参数相同的情况下,过度增大学习率的确是会导致准确率下降的,查看详细变化过程时可以看到准确率变化波动比较大。
  • 在学习率适中,迭代次数较大时变量初始化方式对最终准确率的影响不大。

每种情况损失和准确率的详细变化趋势

与上图的顺序保持一致,从上至下。 每张图的标题在图的下面,斜体字。

学习率为1,迭代次数为50,随机初始化

学习率为1,迭代次数为50,初始化为0

学习率为0.1,迭代次数为50,随机初始化

学习率为0.1,迭代次数为50,初始化为0

学习率为0.1,迭代次数为25,随机初始化

学习率为0.1,迭代次数为25,初始化为0

学习率为0.01,迭代次数为50,随机初始化

学习率为0.01,迭代次数为50,初始化为0

大部分情况下准确率和损失的变化时单调的,但是当学习率过大(=1)时准确率开始不稳定。

END

暂且就是这么多,我说的难免有不合适的地方,有错误的地方欢迎指出。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏生信小驿站

无监督学习 聚类分析②划分聚类分析

同样是聚类分析,上一次介绍的是层次聚类分法,这种方法输出的聚类树状图是其最大的优点,但是层次分析法的缺点就在于适合的样本数比较小,大概在150个左右。所以,当我...

601
来自专栏杨熹的专栏

神经网络 之 线性单元

本文结构: 什么是线性单元 有什么用 代码实现 ---- 1. 什么是线性单元 线性单元和感知器的区别就是在激活函数: ? 感知器的 f 是阶越函数: ? 线性...

3214
来自专栏红色石头的机器学习之路

台湾大学林轩田机器学习技法课程学习笔记1 -- Linear Support Vector Machine

关于台湾大学林轩田老师的《机器学习基石》课程,我们已经总结了16节课的笔记。这里附上基石第一节课的博客地址: 台湾大学林轩田机器学习基石课程学习笔记1 – Th...

2270
来自专栏MixLab科技+设计实验室

用谷歌新开源的deeplearnJS预测互补颜色

本文翻译自deeplearnJS的示例教程,并结合了我在学习过程中的理解。 deeplearnJS简介: deeplearn.js是用于机器学习的开源WebGL...

2828
来自专栏贾志刚-OpenCV学堂

OpenCV中KMeans算法介绍与应用

一:KMeans算法介绍 ? KMeans算法MacQueen在1967年提出的,是最简单与最常见数据分类方法之一并且最为一种常见数据分析技术在机器学习、数据挖...

32010
来自专栏marsggbo

神经网络权重初始化问题

之前看Andrew大神的视频有介绍到神经网络权重需要随机初始化而不是全初始化为0的问题,其真正深层次的含义没有弄明白,所以结合一些资料(cs231n课程)希望...

4927
来自专栏Soul Joy Hub

《deep learning》学习笔记(4)——数值计算

http://blog.csdn.net/u011239443/article/details/78048424 对于机器学习的问题,有一部分可以通过数学推导的...

2615
来自专栏书山有路勤为径

Batch Normalization怎么加入batch normalization

Batch Normalization 会使你的参数搜索问题变得很容易,使神经网络对超参数的选择更加稳定,超参数的范围会更加庞大,工作效果也很好,也会使你的训练...

632
来自专栏机器之心

教程 | 在Python和TensorFlow上构建Word2Vec词嵌入模型

选自adventuresinmachinelearning 机器之心编译 参与:李诗萌、刘晓坤 本文详细介绍了 word2vector 模型的模型架构,以及 T...

4017
来自专栏小鹏的专栏

02 The TensorFlow Way(3)

Implementing Back Propagation 使用TensorFlow的好处之一是可以跟踪操作,并根据反向传播自动更新模型变量。如下,我们将介绍...

2026

扫码关注云+社区