tensorflow学习笔记 -- 梯度爆炸/消失和作用域

8. 梯度爆炸/消失

对于学习率来说过高或者过低都不会达到好的训练效果,拿之前的例子来看,之前的是在0.1的学习率前提下训练100次效果很不错,下图是在0.001的学习率得到的结果:

tensorflow学习笔记 -- 梯度爆炸/消失和作用域_第1张图片

可以看到过小的学习率导致训练过程渐渐的就学不动了从而丧失了学习能力,最终训练的结果与预期的相差很远,这就是梯度消失,下面是学习率为2的情况:

tensorflow学习笔记 -- 梯度爆炸/消失和作用域_第2张图片 可以看到学习率过大的话会导致参数增长幅度过大从而使得超出了数字范围,这就是梯度爆炸。

解决梯度爆炸的方法有:

  1.  重新设计网络
  2.  调整学习率
  3.  使用梯度截断(在训练过程中检查和限制梯度的大小)
  4.  使用激活函数

其中1,3,4通常在神经网络中会使用

9. 作用域

作用域可以为数据和代码划区域是代码看起来更加整洁,并且可以让可视化的图形看起来更加的清晰,例如下面代码:

import tensorflow as tf


def regression():
    """
    用Tensorflow实现一个简单的线性回归
    我们预设一个线性函数然后通过线性回归看看能否得到这个函数对应的参数
    预设的函数:y = 0.7 * x + 0.5 (其中0.7和0.5是我们需要通过训练得到的参数,也就是最终需要的得到模型)
    """
    with tf.variable_scope("data"):
        # 1. 自己生成一些训练数据,真实项目中这些数据应该是给定的
        # 1.1 随机生成100个数作为x的训练数据
        x_true = tf.random_normal([100, 1], mean=2.0, stddev=1.5, name="x")
        # 1.2 根据x值和预设好的函数来生成100个数作为y的训练数据
        y_true = tf.matmul(x_true, [[0.7]]) + 0.5
    with tf.variable_scope("model"):
        # 2. 构建线性回归模型,由于我们已经预设了函数模型所以直接知道了模型的大概结构是由一个权重(w)和一个偏置(b)组成
        # 2.1 创建权重变量,由于权重只有一个所以生成1行1列的随机数
        weight = tf.Variable(tf.random_normal([1, 1], mean=0.0, stddev=0.1), name="w")
        # 2.2 创建偏置变量,由于偏置是相加所以不需要创建矩阵类型的数据,直接随便定义一个数即可
        bias = tf.Variable(2.0, name="b")
        # 2.3 创建模型,其实就是写一遍预设函数(实际项目中就是猜想的函数模型)
        y_predict = tf.matmul(x_true, weight) + bias
    with tf.variable_scope("loss"):
        # 3. 构建损失函数,这里取的数均方
        loss = tf.reduce_mean(tf.square(y_true - y_predict))
    with tf.variable_scope("optimizer"):
        # 4. 梯度下降优化误差,梯度下降优化器的API的唯一参数就是学习率
        train_op = tf.train.GradientDescentOptimizer(0.1).minimize(loss)

    # 初始化变量
    init_op = tf.global_variables_initializer()

    with tf.Session() as sess:
        # 执行初始化变量
        sess.run(init_op)
        # 创建事件文件
        filewriter = tf.summary.FileWriter("./summary/learning/", graph=sess.graph)
        # 循环100次训练,相当于用10000个训练数据来训练
        for i in range(100):
            sess.run(train_op)
            print("第%d次训练后的权重参数为:%f,偏置参数为:%f" % (i+1, weight.eval(), bias.eval()))


if __name__ == "__main__":
    regression()

代码中四个模块用作用域的名称区分开看起来非常的整洁,接下来是可视化图形的区别,先看没有加作用域的可视化图形:

tensorflow学习笔记 -- 梯度爆炸/消失和作用域_第3张图片

上面只标注了各个数据的名称错综复杂线条相对比较混乱,下图是加了作用域的可视化图形:

tensorflow学习笔记 -- 梯度爆炸/消失和作用域_第4张图片

可以看到分了模块后相对的清晰了很多。 

你可能感兴趣的:(人工智能,学习笔记)