原理
根据数据建立回归模型f(x)
通过真实值与预测值之间建立误差,使用梯度下降优化得到损失最小对应的权重和偏置。最终确定模型的权重和偏置参数。最后可以用这些参数进行预测。
知识储备
梯度下降优化
tf.train.GradientDescentOptimizer(learning_rate)
代码演示
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()
当把学习率调到0.01,发现一切正常
train_op = tf.train.GradientDescentOptimizer(0.01).minimize(loss)
更改学习率为2时,发现出现了NaN
train_op = tf.train.GradientDescentOptimizer(2).minimize(loss)
由于学习过程中,学习率设置过大,导致梯度指数型增大,最终引起梯度爆炸。
关于梯度爆炸/梯度消失
在极端情况下,权重的值变得非常大,以至于溢出,导致NaN值。
使数据可视化更完善
目的:观察模型的参数、损失值等变量值的变化
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()