Tensorflow实现线性回归
2018-11-19 本文已影响152人
Daily_Note
Tensorflow实现线性回归
记录,成为更好的自己
线性回归:w1x1+w2x2+....+w_nx_n+bias
一个特征一个权值,100个特征100个权值
算法 | 策略 | 优化 |
---|---|---|
线性回归 | 均方误差 | 梯度下降 |
-
准备好一个特征和一个目标值。
-
建立模型 随机初始化准备一个权重w,一个偏置b。
y_predict=x*w+b
模型的参数必须用变量定义,若用张量定义,不会改变 -
求损失函数,误差
均方误差((y1-y1')^2+...+(y_100 - y_100')^2)/100
-
梯度下降去优化损失过程
指定学习率
矩阵相乘:(m行,n列)*(n行,1)=(m行, 1)
- 相关API
-
矩阵运算
tf.matmul(x, w)
-
平方
tf.square(error)
-
均值
tf.reduce_mean(error)
-
梯度下降优化
tf.train.GradientDescentOptimizer(learning_rate)
- learning_rate:学习率,
- return:梯度下降的op
-
自己实现一个线性回归预测
def myregression():
"""
自实现一个线性回归预测
:return: None
"""
# 1.准备数据, x特征值[100,1],100个样本1个特征;y目标值
x = tf.random_normal([100, 1], mean=1.75, stddev=0.75, name="x_data")
# 矩阵相乘必须是二维的
# 自己先给一个真实值
y_true = tf.matmul(x, [[0.7]])+0.8
# 2. 建立线性回归模型 1个特征,一个权值,一个偏置
# 随机给一个权重和偏置的值,让他计算损失,然后在当前的状态下调整。
weight = tf.Variable(tf.random_normal([1,1], mean=0.0, stddev=1.0), name="w")
bias = tf.Variable(0.0, name="b")
# 预测的值
y_predict=tf.matmul(x, weight)+bias
# 3. 建立损失函数,均方误差
loss = tf.reduce_mean(tf.square(y_true - y_predict))
# 4.梯度下降优化损失
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)
# 打印随机最先初始化的权重和偏置,weight,bias为变量,必须要运行才有值
print("随机初始化的参数权重为:%f, 偏置为:%f" %(weight.eval(), bias.eval()))
# 训练优化
sess.run(train_op)
print("优化的参数权重为:%f, 偏置为:%f" % ( weight.eval(), bias.eval()))
优化一次的结果为:
随机初始化的参数权重为:-1.247384, 偏置为:0.000000
优化的参数权重为:0.371060, 偏置为:0.820012
已知的权重为0.7,偏置为0.8,很显然优化一次是不够的,因此改为循环训练优化:
# 循环训练,运行优化
for i in range(200):
sess.run(train_op)
print("第%d次,优化的参数权重为:%f, 偏置为:%f" % (i, weight.eval(), bias.eval()))
循环200次后的优化结果为:
第199次,优化的参数权重为:0.701386, 偏置为:0.797212
-
训练参数问题:trainable
定义变量时,若trainable设置为false,这变量就是普通的张量了,不能随着梯度下降来更改值。
-
学习率和步长
若学习率设置的过大,会导致梯度爆炸
若设置的过小,就会要训练很多次- 关于梯度爆炸/梯度消失
- 在极端情况下,权重的值变得非常大,以至于溢出,导致NaN值
- 如何解决?(1,2,4都是用于神经网络)
- 重新设计网络
- 调整学习率
- 使用梯度截断(在训练过程中检查和限制梯度)
- 使用激活函数
- 关于梯度爆炸/梯度消失
-
添加权重参数,损失值等在tensorboard观察的情况
- 收集变量
- 合并变量写入事件文件
线性回归优化后的代码
# 定义命令行参数
# 1.首先定义有哪些参数需要在运行时候指定
# 2.程序当中获取定义命令行参数
# 第一个参数:名字,默认值,说明
tf.app.flags.DEFINE_integer("max_step", 100, "模型训练的步数")
tf.app.flags.DEFINE_string("model_dir", "./ckpt/model", "模型文件的加载路径")
# 获取命令行参数名字
FLAGS = tf.app.flags.FLAGS
def myregression():
"""
自实现一个线性回归预测
:return: None
"""
with tf.variable_scope("data"):
# 1.准备数据, x特征值[100,1],100个样本1个特征;y目标值
x = tf.random_normal([100, 1], mean=1.75, stddev=0.75, name="x_data")
# 矩阵相乘必须是二维的
# 自己先给一个真实值
y_true = tf.matmul(x, [[0.7]])+0.8
with tf.variable_scope("model"):
# 2. 建立线性回归模型 1个特征,一个权值,一个偏置
# 随机给一个权重和偏置的值,让他计算损失,然后在当前的状态下调整。
weight = tf.Variable(tf.random_normal([1,1], mean=0.0, stddev=1.0), name="w")
bias = tf.Variable(0.0, name="b")
# 预测的值
y_predict=tf.matmul(x, weight)+bias
with tf.variable_scope("loss"):
# 3. 建立损失函数,均方误差
loss = tf.reduce_mean(tf.square(y_true - y_predict))
with tf.variable_scope("optimizer"):
# 4.梯度下降优化损失
train_op = tf.train.GradientDescentOptimizer(0.1).minimize(loss)
# 1.收集tensor
tf.summary.scalar("losses", loss)
tf.summary.histogram("weights", weight)
# 2. 定义合并的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)
# 打印随机最先初始化的权重和偏置,weight,bias为变量,必须要运行才有值
print("随机初始化的参数权重为:%f, 偏置为:%f" %(weight.eval(), bias.eval()))
# # 训练优化
# sess.run(train_op)
# print("优化的参数权重为:%f, 偏置为:%f" % ( weight.eval(), bias.eval()))
# 建立事件文件
filewriter = tf.summary.FileWriter("./summary/test", graph=sess.graph)
# 加载模型,覆盖模型当中随机定义的参数,从上次训练的结果开始
if os.path.exists("./ckpt/checkpoint"):
# saver.restore(sess, "./ckpt/model")
saver.restore(sess, FLAGS.model_dir)
# 循环训练,运行优化
# for i in range(500):
for i in range(FLAGS.max_step):
sess.run(train_op)
# 运行合并的tensor
summary = sess.run(merged)
filewriter.add_summary(summary, i)
print("第%d次,优化的参数权重为:%f, 偏置为:%f" % (i, weight.eval(), bias.eval()))
# saver.save(sess, "./ckpt/model")
saver.save(sess, FLAGS.model_dir)
return None