自实现线性回归案例:
线性回归原理:
-
构建模型
y = w1x1 + w2x2 + …+wnxn + b
-
构建损失函数
均方误差
-
优化损失
梯度下降
实现线性回归的训练
-
准备真实数据
准备100个样本
x 特征值 形状(100, 1)
y_true 目标值 (100, 1)
y_true = 0.8x + 0.7
-
假定x和y之间的关系
y = kx + b
k ≈ 0.8b ≈ 0.7
流程分析:
(100, 1) * (1, 1) = (100, 1)
y_predict = x * weights(1, 1) + bias(1, 1)
-
构建模型
y_predict = tf.matmul(x, weights) + bias
-
构建损失函数
error = tf.reduce_mean(tf.square(y_predict - y_true))
-
优化损失
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01).minimize(error)
-
import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
def linear_repression():
'''
自实现一个线性回归
:return:
'''
# 准备数据
x = tf.random_normal(shape=[100, 1])
y_true = tf.matmul(x, [[0.8]]) + 0.7
# 构建模型
# 定义模型参数用变量
weights = tf.Variable(initial_value=tf.random_normal(shape=[1, 1]))
bias = tf.Variable(initial_value=tf.random_normal(shape=[1, 1]))
y_predict = tf.matmul(x, weights) + bias
# 构建损失函数
error = tf.reduce_mean(tf.square(y_predict-y_true))
# 优化损失
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01).minimize(error)
# 由于定义了变量,所以需要显示初始化变量
init = tf.global_variables_initializer()
# 开启会话
with tf.Session() as sess:
# 初始化变量
sess.run(init)
# 查看初始化模型参数之后的值
print("训练模型参数为:权重:%f, 偏置:%f, 损失为:%f" % (weights.eval(), bias.eval(), error.eval()))
for i in range(1000):
sess.run(optimizer)
print("第%d次训练模型参数为:权重:%f, 偏置:%f, 损失为:%f" % ((i+1), weights.eval(), bias.eval(), error.eval()))
return None
if __name__ == "__main__":
linear_repression()
学习率的设置,步数的设置与梯度爆炸
学习率越大,训练到较好结果的步数较小;学习率越小,训练到较好结果的步数越大。在学习过程中会出现梯度爆炸现象。
在极端情况下,权重的值会变得非常大,以至于溢出,导致NaN值
如何解决梯度爆炸问题(深度神经网络中更容易出现)
- 重新设计网络
- 调整学习率
- 使用梯度(在训练过程中检查和限制梯度大小)
- 使用激活函数
使用tensorboard时应该注意的地方(可能会遇到在Windows下tensorboard拒绝访问)
- 确保电脑的名字不能是中文。
- 确保路径在对应的文件下有events文件。
- 在浏览器中搜索对应的网址时遇到拒绝访问,原因可能是在终端按下了ctrl+c,ctrl+c就会退出导致无法访问,在结束tensorboard后再退出。
- 查看tensorboard的效果:在pyCharm的Terminal终端输入tensorboard --logdir="C:\Users\user\Desktop\lzy"会有一个网址,在浏览器中输入网址可看到
增加变量显示
- 创建事件文件
- 收集变量
- 合并变量
- 每次迭代运行一次合并变量
- 每次迭代将summary对象写入事件文件
增加命名空间
使代码结构更加清晰,Tensorboard图结构清楚
# example
with tf.variable_scope("prepare_data"):
# 准备数据
x = tf.random_normal(shape=[100, 1])
y_true = tf.matmul(x, [[0.8]]) + 0.7
with tf.variable_scope("creat_model"):
# 构建模型
# 定义模型参数用变量
weights = tf.Variable(initial_value=tf.random_normal(shape=[1, 1]), name="weights")
bias = tf.Variable(initial_value=tf.random_normal(shape=[1, 1]), name="bias")
y_predict = tf.matmul(x, weights) + bias
with tf.variable_scope("loss_function"):
# 构建损失函数
error = tf.reduce_mean(tf.square(y_predict-y_true), name="error")
with tf.variable_scope("optimizer"):
# 优化损失
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01).minimize(error)
模型的保存与加载(important)
tf.train.Saver(var_list=None, max_to_keep=5)
保存和加载模型(保存文件格式:checkpoint文件)
var_list:指定要保存和还原的变量。可以作为一个dict或一个列表传递。
max_to_keep:指示要保留的最近检查点文件的最大数量。创建新文件时,会删除较旧的文件。如果没有或为零,则保存所有检查点文件。默认为5(保留最新的5个检查点文件)
保存:saver.save(sess, filepath)
加载:saver.restore(sess, filepath)
碰见的问题:
在Python中 \ 是转义符,\u表示其后是unicode编码,因此\User在这里会报错,在字符串前面加个 r,可以避免python与正则表达式语法的冲突.
命令行参数使用
-
tf.app.flags:支持应用从命令行接受参数,可以用来指定集群配置等
DEFINE_string(flag_name, default_value, docstring)
DEFINE_integer(flag_name, default_value, docstring)
DEFINE_boolean(flag_name, default_value, docstring)
DEFINE_float(float_name, default_value, docstring)
-
tf.app.flags:在flags后有一个FLAGS标志,在程序中可以调用到所定义的flag_name
-
通过tf.app.run()启动main(argv)函数
# tf.app.flags.DEFINE_integer("max_step", 0, "训练模型的步数")
# tf.app.flags.DEFINE_string("model_dir", " ", "模型保存的路径+模型名字")
# FLAGS = tf.app.flags.FLAGS
# 定义命令行参数
tf.app.flags.DEFINE_integer("max_step", 100, "训练模型步数")
tf.app.flags.DEFINE_string("model_dir", "Unknown", "模型保存的路径+模型名字")
# 简化变量名
FLAGS = tf.app.flags.FLAGS
def command_demo():
print("max_step:\n", FLAGS.max_step)
print("model_dir:\n", FLAGS.model_dir)
return None
# 通过FLAGS.max_step调用命令行中传过来的参数
在命令行终端输入python fileName.py --max_step=1000 --model_dir="myLove"
# 通过tf.app.run()启动main(argv)函数
def main(argv): # 注意argv不能少
print("code start")
return None
if __name__=="__main__":
tf.app.run()
fileName.py --max_step=1000 --model_dir=“myLove”
通过tf.app.run()启动main(argv)函数
def main(argv): # 注意argv不能少
print("code start")
return None
if __name__=="__main__":
tf.app.run()