Tensorflow基本结构练习-实现简单的线性回归

       根据数据建立回归模型,w1x1+w2x2+…..+b = y,通过真实值与预测值之间建立误差,使用梯度下降优化得到损失最小对应的权重和偏置。最终确定模型的权重和偏置参数。最后可以用这些参数进行预测。

二、案例:实现线性回归的训练

1 .案例确定

  • 假设随机指定100个点,只有一个特征
  • 数据本身的分布为 y = 0.7 * x + 0.8

这里将数据分布的规律确定,是为了使我们训练出的参数跟真实的参数(即0.7和0.8)比较是否训练准确

2.API

运算

  • 矩阵运算
    • tf.matmul(x, w)
  • 平方
    • tf.square(error)
  • 均值
    • tf.reduce_mean(error)

梯度下降优化

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

3.步骤分析

  • 1 准备好数据集:y = 0.8x + 0.7 100个样本
  • 2 建立线性模型
    • 随机初始化W1和b1
    • y = W·X + b,目标:求出权重W和偏置b
  • 3 确定损失函数(预测值与真实值之间的误差)-均方误差
  • 4 梯度下降优化损失:需要指定学习率(超参数)

4.实现完整功能


  
  
  1. import tensorflow as tf
  2. import os
  3. def linear_regression():
  4. """
  5. 自实现线性回归
  6. :return: None
  7. """
  8. # 1)准备好数据集:y = 0.8x + 0.7 100个样本
  9. # 特征值X, 目标值y_true
  10. X = tf.random_normal(shape=( 100, 1), mean= 2, stddev= 2)
  11. # y_true [100, 1]
  12. # 矩阵运算 X(100, 1)* (1, 1)= y_true(100, 1)
  13. y_true = tf.matmul(X, [[ 0.8]]) + 0.7
  14. # 2)建立线性模型:
  15. # y = W·X + b,目标:求出权重W和偏置b
  16. # 3)随机初始化W1和b1
  17. weights = tf.Variable(initial_value=tf.random_normal(shape=( 1, 1)))
  18. bias = tf.Variable(initial_value=tf.random_normal(shape=( 1, 1)))
  19. y_predict = tf.matmul(X, weights) + bias
  20. # 4)确定损失函数(预测值与真实值之间的误差)-均方误差
  21. error = tf.reduce_mean(tf.square(y_predict - y_true))
  22. # 5)梯度下降优化损失:需要指定学习率(超参数)
  23. # W2 = W1 - 学习率*(方向)
  24. # b2 = b1 - 学习率*(方向)
  25. optimizer = tf.train.GradientDescentOptimizer(learning_rate= 0.01).minimize(error)
  26. # 初始化变量
  27. init = tf.global_variables_initializer()
  28. # 开启会话进行训练
  29. with tf.Session() as sess:
  30. # 运行初始化变量Op
  31. sess.run(init)
  32. print( "随机初始化的权重为%f, 偏置为%f" % (weights.eval(), bias.eval()))
  33. # 训练模型
  34. for i in range( 100):
  35. sess.run(optimizer)
  36. print( "第%d步的误差为%f,权重为%f, 偏置为%f" % (i, error.eval(), weights.eval(), bias.eval()))
  37. return None

5.学习率的设置、步数的设置与梯度爆炸

学习率越大,训练到较好结果的步数越小;学习率越小,训练到较好结果的步数越大。

但是学习过大会出现梯度爆炸现象。关于梯度爆炸/梯度消失 ?


  
  
  1. 在极端情况下,权重的值变得非常大,以至于溢出,导致 NaN
  2. 如何解决梯度爆炸问题(深度神经网络当中更容易出现)
  3. 1、重新设计网络
  4. 2、调整学习率
  5. 3、使用梯度截断(在训练过程中检查和限制梯度的大小)
  6. 4、使用激活函数

6.变量的trainable设置观察

trainable的参数作用,指定是否训练

weight = tf.Variable(tf.random_normal([1, 1], mean=0.0, stddev=1.0), name="weights", trainable=False)

  
  

三、增加其他功能

  • 增加命名空间
  • 变量Tensorboard显示
  • 模型保存与加载
  • 命令行参数设置

1.增加命名空间

是代码结构更加清晰,Tensorboard图结构清楚

with tf.variable_scope("lr_model"):

  
  

2.增加变量显示

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

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

  
  
  1. def linear_regression():
  2. # 1)准备好数据集:y = 0.8x + 0.7 100个样本
  3. # 特征值X, 目标值y_true
  4. with tf.variable_scope( "original_data"):
  5. X = tf.random_normal(shape=( 100, 1), mean= 2, stddev= 2, name= "original_data_x")
  6. # y_true [100, 1]
  7. # 矩阵运算 X(100, 1)* (1, 1)= y_true(100, 1)
  8. y_true = tf.matmul(X, [[ 0.8]], name= "original_matmul") + 0.7
  9. # 2)建立线性模型:
  10. # y = W·X + b,目标:求出权重W和偏置b
  11. # 3)随机初始化W1和b1
  12. with tf.variable_scope( "linear_model"):
  13. weights = tf.Variable(initial_value=tf.random_normal(shape=( 1, 1)), name= "weights")
  14. bias = tf.Variable(initial_value=tf.random_normal(shape=( 1, 1)), name= "bias")
  15. y_predict = tf.matmul(X, weights, name= "model_matmul") + bias
  16. # 4)确定损失函数(预测值与真实值之间的误差)-均方误差
  17. with tf.variable_scope( "loss"):
  18. error = tf.reduce_mean(tf.square(y_predict - y_true), name= "error_op")
  19. # 5)梯度下降优化损失:需要指定学习率(超参数)
  20. # W2 = W1 - 学习率*(方向)
  21. # b2 = b1 - 学习率*(方向)
  22. with tf.variable_scope( "gd_optimizer"):
  23. optimizer = tf.train.GradientDescentOptimizer(learning_rate= 0.01, name= "optimizer").minimize(error)
  24. # 2)收集变量
  25. tf.summary.scalar( "error", error)
  26. tf.summary.histogram( "weights", weights)
  27. tf.summary.histogram( "bias", bias)
  28. # 3)合并变量
  29. merge = tf.summary.merge_all()
  30. # 初始化变量
  31. init = tf.global_variables_initializer()
  32. # 开启会话进行训练
  33. with tf.Session() as sess:
  34. # 运行初始化变量Op
  35. sess.run(init)
  36. print( "随机初始化的权重为%f, 偏置为%f" % (weights.eval(), bias.eval()))
  37. # 1)创建事件文件
  38. file_writer = tf.summary.FileWriter(logdir= "./summary", graph=sess.graph)
  39. # 训练模型
  40. for i in range( 100):
  41. sess.run(optimizer)
  42. print( "第%d步的误差为%f,权重为%f, 偏置为%f" % (i, error.eval(), weights.eval(), bias.eval()))
  43. # 4)运行合并变量op
  44. summary = sess.run(merge)
  45. file_writer.add_summary(summary, i)
  46. return None

3.模型的保存与加载

  • tf.train.Saver(var_list=None,max_to_keep=5)
    <ul><li>保存和加载模型(保存文件格式:checkpoint文件)</li>
    	<li>var_list:指定将要保存和还原的变量。它可以作为一个dict或一个列表传递.</li>
    	<li>max_to_keep:指示要保留的最近检查点文件的最大数量。创建新文件时,会删除较旧的文件。如果无或0,则保留所有检查点文件。默认为5(即保留最新的5个检查点文件。)</li>
    </ul></li>
    

使用


  
  
  1. 例如:
  2. 指定目录+模型名字
  3. saver.save(sess, '/tmp/ckpt/test/myregression.ckpt')
  4. saver.restore(sess, '/tmp/ckpt/test/myregression.ckpt')

如要判断模型是否存在,直接指定目录


  
  
  1. checkpoint = tf.train.latest_checkpoint( "./tmp/model/")
  2. saver.restore(sess, checkpoint)

4.命令行参数使用

  • 1.

  • 2.tf.app.flags.,在flags有一个FLAGS标志,它在程序中可以调用到我们

前面具体定义的flag_name

  • 3.通过tf.app.run()启动main(argv)函数

  
  
  1. # 定义一些常用的命令行参数
  2. # 训练步数
  3. tf.app.flags.DEFINE_integer( "max_step", 0, "训练模型的步数")
  4. # 定义模型的路径
  5. tf.app.flags.DEFINE_string( "model_dir", " ", "模型保存的路径+模型名字")
  6. # 定义获取命令行参数
  7. FLAGS = tf.app.flags.FLAGS
  8. # 开启训练
  9. # 训练的步数(依据模型大小而定)
  10. for i in range(FLAGS.max_step):
  11. sess.run(train_op)

完整代码


  
  
  1. import tensorflow as tf
  2. import os
  3. tf.app.flags.DEFINE_string( "model_path", "./linear_regression/", "模型保存的路径和文件名")
  4. FLAGS = tf.app.flags.FLAGS
  5. def linear_regression():
  6. # 1)准备好数据集:y = 0.8x + 0.7 100个样本
  7. # 特征值X, 目标值y_true
  8. with tf.variable_scope( "original_data"):
  9. X = tf.random_normal(shape=( 100, 1), mean= 2, stddev= 2, name= "original_data_x")
  10. # y_true [100, 1]
  11. # 矩阵运算 X(100, 1)* (1, 1)= y_true(100, 1)
  12. y_true = tf.matmul(X, [[ 0.8]], name= "original_matmul") + 0.7
  13. # 2)建立线性模型:
  14. # y = W·X + b,目标:求出权重W和偏置b
  15. # 3)随机初始化W1和b1
  16. with tf.variable_scope( "linear_model"):
  17. weights = tf.Variable(initial_value=tf.random_normal(shape=( 1, 1)), name= "weights")
  18. bias = tf.Variable(initial_value=tf.random_normal(shape=( 1, 1)), name= "bias")
  19. y_predict = tf.matmul(X, weights, name= "model_matmul") + bias
  20. # 4)确定损失函数(预测值与真实值之间的误差)-均方误差
  21. with tf.variable_scope( "loss"):
  22. error = tf.reduce_mean(tf.square(y_predict - y_true), name= "error_op")
  23. # 5)梯度下降优化损失:需要指定学习率(超参数)
  24. # W2 = W1 - 学习率*(方向)
  25. # b2 = b1 - 学习率*(方向)
  26. with tf.variable_scope( "gd_optimizer"):
  27. optimizer = tf.train.GradientDescentOptimizer(learning_rate= 0.01, name= "optimizer").minimize(error)
  28. # 2)收集变量
  29. tf.summary.scalar( "error", error)
  30. tf.summary.histogram( "weights", weights)
  31. tf.summary.histogram( "bias", bias)
  32. # 3)合并变量
  33. merge = tf.summary.merge_all()
  34. # 初始化变量
  35. init = tf.global_variables_initializer()
  36. # 创建saver对象
  37. saver = tf.train.Saver()
  38. # 开启会话进行训练
  39. with tf.Session() as sess:
  40. # 运行初始化变量Op
  41. sess.run(init)
  42. # 未经训练的权重和偏置
  43. print( "随机初始化的权重为%f, 偏置为%f" % (weights.eval(), bias.eval()))
  44. # 当存在checkpoint文件,就加载模型
  45. if os.path.exists( "./linear_regression/checkpoint"):
  46. saver.restore(sess, FLAGS.model_path)
  47. # 1)创建事件文件
  48. file_writer = tf.summary.FileWriter(logdir= "./summary", graph=sess.graph)
  49. # 训练模型
  50. for i in range( 100):
  51. sess.run(optimizer)
  52. print( "第%d步的误差为%f,权重为%f, 偏置为%f" % (i, error.eval(), weights.eval(), bias.eval()))
  53. # 4)运行合并变量op
  54. summary = sess.run(merge)
  55. file_writer.add_summary(summary, i)
  56. if i % 10 == 0:
  57. saver.save(sess, FLAGS.model_path)
  58. return None
  59. def main(argv):
  60. print( "这是main函数")
  61. print(argv)
  62. print(FLAGS.model_path)
  63. linear_regression()
  64. if __name__ == "__main__":
  65. tf.app.run()

作业:将面向过程改为面向对象

参考代码


  
  
  1. # 用tensorflow自实现一个线性回归案例
  2. # 定义一些常用的命令行参数
  3. # 训练步数
  4. tf.app.flags.DEFINE_integer( "max_step", 0, "训练模型的步数")
  5. # 定义模型的路径
  6. tf.app.flags.DEFINE_string( "model_dir", " ", "模型保存的路径+模型名字")
  7. FLAGS = tf.app.flags.FLAGS
  8. class MyLinearRegression(object):
  9. """
  10. 自实现线性回归
  11. """
  12. def __init__(self):
  13. pass
  14. def inputs(self):
  15. """
  16. 获取特征值目标值数据数据
  17. :return:
  18. """
  19. x_data = tf.random_normal([ 100, 1], mean= 1.0, stddev= 1.0, name= "x_data")
  20. y_true = tf.matmul(x_data, [[ 0.7]]) + 0.8
  21. return x_data, y_true
  22. def inference(self, feature):
  23. """
  24. 根据输入数据建立模型
  25. :param feature:
  26. :param label:
  27. :return:
  28. """
  29. with tf.variable_scope( "linea_model"):
  30. # 2、建立回归模型,分析别人的数据的特征数量--->权重数量, 偏置b
  31. # 由于有梯度下降算法优化,所以一开始给随机的参数,权重和偏置
  32. # 被优化的参数,必须得使用变量op去定义
  33. # 变量初始化权重和偏置
  34. # weight 2维[1, 1] bias [1]
  35. # 变量op当中会有trainable参数决定是否训练
  36. self.weight = tf.Variable(tf.random_normal([ 1, 1], mean= 0.0, stddev= 1.0),
  37. name= "weights")
  38. self.bias = tf.Variable( 0.0, name= 'biases')
  39. # 建立回归公式去得出预测结果
  40. y_predict = tf.matmul(feature, self.weight) + self.bias
  41. return y_predict
  42. def loss(self, y_true, y_predict):
  43. """
  44. 目标值和真实值计算损失
  45. :return: loss
  46. """
  47. # 3、求出我们模型跟真实数据之间的损失
  48. # 均方误差公式
  49. loss = tf.reduce_mean(tf.square(y_true - y_predict))
  50. return loss
  51. def merge_summary(self, loss):
  52. # 1、收集张量的值
  53. tf.summary.scalar( "losses", loss)
  54. tf.summary.histogram( "w", self.weight)
  55. tf.summary.histogram( 'b', self.bias)
  56. # 2、合并变量
  57. merged = tf.summary.merge_all()
  58. return merged
  59. def sgd_op(self, loss):
  60. """
  61. 获取训练OP
  62. :return:
  63. """
  64. # 4、使用梯度下降优化器优化
  65. # 填充学习率:0 ~ 1 学习率是非常小,
  66. # 学习率大小决定你到达损失一个步数多少
  67. # 最小化损失
  68. train_op = tf.train.GradientDescentOptimizer( 0.1).minimize(loss)
  69. return train_op
  70. def train(self):
  71. """
  72. 训练模型
  73. :param loss:
  74. :return:
  75. """
  76. g = tf.get_default_graph()
  77. with g.as_default():
  78. x_data, y_true = self.inputs()
  79. y_predict = self.inference(x_data)
  80. loss = self.loss(y_true, y_predict)
  81. train_op = self.sgd_op(loss)
  82. # 收集观察的结果值
  83. merged = self.merge_summary(loss)
  84. saver = tf.train.Saver()
  85. with tf.Session() as sess:
  86. sess.run(tf.global_variables_initializer())
  87. # 在没训练,模型的参数值
  88. print( "初始化的权重:%f, 偏置:%f" % (self.weight.eval(), self.bias.eval()))
  89. # 加载模型
  90. checkpoint = tf.train.latest_checkpoint( "./tmp/model/")
  91. # print(checkpoint)
  92. if checkpoint:
  93. print( 'Restoring', checkpoint)
  94. saver.restore(sess, checkpoint)
  95. # 开启训练
  96. # 训练的步数(依据模型大小而定)
  97. for i in range(FLAGS.max_step):
  98. sess.run(train_op)
  99. # 生成事件文件,观察图结构
  100. file_writer = tf.summary.FileWriter( "./tmp/summary/", graph=sess.graph)
  101. print( "训练第%d步之后的损失:%f, 权重:%f, 偏置:%f" % (
  102. i,
  103. loss.eval(),
  104. self.weight.eval(),
  105. self.bias.eval()))
  106. # 运行收集变量的结果
  107. summary = sess.run(merged)
  108. # 添加到文件
  109. file_writer.add_summary(summary, i)
  110. if i % 100 == 0:
  111. # 保存的是会话当中的变量op值,其他op定义的值不保存
  112. saver.save(sess, FLAGS.model_dir)
  113. if __name__ == '__main__':
  114. lr = MyLinearRegression()
  115. lr.train()
原创文章 28 获赞 34 访问量 2986

猜你喜欢

转载自blog.csdn.net/weixin_42134034/article/details/105767768