tensorflow之实现一个线性回归

线性回归

原理

根据数据建立回归模型f(x)
tensorflow之实现一个线性回归_第1张图片
通过真实值与预测值之间建立误差,使用梯度下降优化得到损失最小对应的权重和偏置。最终确定模型的权重和偏置参数。最后可以用这些参数进行预测。

知识储备

矩阵运算API

  • tf.matmul(x, w) 相乘
  • tf.square(error) 平方
  • tf.reduce_mean(error) 平均值

梯度下降API

梯度下降优化
tf.train.GradientDescentOptimizer(learning_rate)

  • learning_rate:学习率,一般为0~1之间比较小的值
  • method: minimize(loss)
  • return:梯度下降op

代码演示

import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'


def myregression():
    '''
    实现线性回归预测
    :return: None
    '''

    # 准备数据
    # x 特征值[100.1],y 目标值[100]
    x = tf.random_normal([100,1],mean=1.75,stddev=0.5)

    # 矩阵相乘必须是二维的
    y_true = tf.matmul(x,[[0.7]]) + 0.8

    # 建立线性回归模型 1个特征,1个权重,一个偏置
    # y = w * x+b
    # 随机给一个权重和偏置的值,让他去计算损失,然后再当前状态下优化
    # 用变量定义才能优化
    weight = tf.Variable(tf.random_normal([1,1],mean=0.0,stddev=1.0))
    bias = tf.Variable(0.0,name="b")

    # 进行矩阵相乘计算预测值
    y_predict = tf.matmul(x,weight) + bias

    # 建立损失函数,求均分误差
    loss = tf.reduce_mean(tf.square(y_true - y_predict))

    # 梯度下降优化损失
    # learning_rate : 0~1,2,3,4,5,6
    train_op = tf.train.GradientDescentOptimizer(0.1).minimize(loss)

    # 定义一个初始化变量的op
    init_op = tf.global_variables_initializer()

    # 开启会话,运行程序
    with tf.Session() as sess:
        # 初始化变量
        sess.run(init_op)

        # 打印随机最先初始化的权重和偏置
        print("随机初始化参数权重为:%f,偏置为:%f" %(weight.eval(),bias.eval()))

        # 循环训练 运行优化op
        for i in range(300):

            sess.run(train_op)

            print("第%d次参数权重为:%f,偏置为:%f" %(i,weight.eval(),bias.eval()))


    return None

if __name__ == "__main__":
    myregression()

tensorflow之实现一个线性回归_第2张图片

如果更改学习率会怎么样呢?

当把学习率调到0.01,发现一切正常

train_op = tf.train.GradientDescentOptimizer(0.01).minimize(loss)

tensorflow之实现一个线性回归_第3张图片

更改学习率为2时,发现出现了NaN

train_op = tf.train.GradientDescentOptimizer(2).minimize(loss)

tensorflow之实现一个线性回归_第4张图片
由于学习过程中,学习率设置过大,导致梯度指数型增大,最终引起梯度爆炸。

这该怎么办???

关于梯度爆炸/梯度消失

在极端情况下,权重的值变得非常大,以至于溢出,导致NaN值。

如何解决梯度爆炸问题(深度神经网络(如RNN)当中更容易出现)

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

使数据可视化更完善

tensorflow变量作用域

  • tf.variable_scope()创建指定名字的变量作用域

增加变量显示.

目的:观察模型的参数、损失值等变量值的变化

  1. 收集变量
  • tfsummary.scalar(name=’’,tensor) 收集对于损失函数和准确率
    中等单值变量,name为变量的名字,tensor为值
  • tfsummary.histogram(name’’,tensor) 收集高维度的变量参数
  • tfsummary.image(name=",tensor) 收集输入的图片张量能显示图片
  1. 合并变量写入事件文件
  • merged = tf.summary.merge. all)
  • 运行合并: summary=sess.run(merged).每次迭代都需运行
  • 添加: FileWriteradd. summary(summary,i)i表示第几次的值

模型保存和加载

  • tf.train.Saver(var_list=None,max_to_keep=5)
  • var_list:指定将要保存和还原的变量。它可以作为一个dict或一个列表传递.
  • max_to_keep:指示要保留的最近检查点文件的最大数量。创建新文件时,会删除较旧的文件。如果无或0,则保留所有检查点文件。默认为5(即保留最新的5个检查点文件。)
import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'


def myregression():
    '''
    实现线性回归预测
    :return: None
    '''

    with tf.variable_scope("data"):
        # 准备数据
        # x 特征值[100.1],y 目标值[100]
        x = tf.random_normal([100,1],mean=1.75,stddev=0.5)

        # 矩阵相乘必须是二维的
        y_true = tf.matmul(x,[[0.7]]) + 0.8

    with tf.variable_scope("model"):
        # 建立线性回归模型 1个特征,1个权重,一个偏置
        # y = w * x+b
        # 随机给一个权重和偏置的值,让他去计算损失,然后再当前状态下优化
        # 用变量定义才能优化
        # trainable指定这个变量能否跟着梯度下降一起优化
        weight = tf.Variable(tf.random_normal([1,1],mean=0.0,stddev=1.0),name="w",trainable=False)
        bias = tf.Variable(0.0,name="b")

        # 进行矩阵相乘计算预测值
        y_predict = tf.matmul(x,weight) + bias

    with tf.variable_scope("loss"):
        # 建立损失函数,求均分误差
        loss = tf.reduce_mean(tf.square(y_true - y_predict))

    with tf.variable_scope("optimizer"):
        # 梯度下降优化损失
        # learning_rate : 0~1(推荐),2,3,4,5,6
        train_op = tf.train.GradientDescentOptimizer(0.01).minimize(loss)

    # 收集tensor
    tf.summary.scalar("losses",loss)
    tf.summary.histogram("weights",weight)

    # 定义合并tensor的op
    merged = tf.summary.merge_all()

    # 定义一个初始化变量的op
    init_op = tf.global_variables_initializer()

    # 定义个保存模型的实例
    saver = tf.train.Saver()

    # 开启会话,运行程序
    with tf.Session() as sess:
        # 初始化变量
        sess.run(init_op)

        # 打印随机最先初始化的权重和偏置
        print("随机初始化参数权重为:%f,偏置为:%f" %(weight.eval(),bias.eval()))

        # 建立事件文件 文件路径
        filewriter = tf.summary.FileWriter("./tmp/summary/test",sess.graph)

        # 加载模型,覆盖模型当中随机定义的参数,从上次训练的参数结果开始
        if os.path.exists("./tmp/ckpt/checkpoint"):
            saver.restore(sess,"./tmp/ckpt/test.model")

        # 循环训练 运行优化op
        for i in range(500):

            sess.run(train_op)

            #运行合并的tensor
            summary = sess.run(merged)

            filewriter.add_summary(summary,i)

            print("第%d次参数权重为:%f,偏置为:%f" %(i,weight.eval(),bias.eval()))

        # 保存模型 路径+文件名
        # 数据保存在test.model.data-00000-of-00001类似文件中
        saver.save(sess,"./tmp/ckpt/test.model")


    return None

if __name__ == "__main__":
    myregression()

tensorflow之实现一个线性回归_第5张图片

你可能感兴趣的:(人工智能)