详细代码如下:
"""
线性回归模型数学表达式:
y=c1*x_1+...+cn*x_n+e (1),
e是一个服从正态分布的随机变量,即 e ~ N(u,sigma^2)
符号约定:
(1)假设有m个数据,第i个数据xi记为xi=(x_i1,...,x_in),对应的y值记为yi,如下:
y1=c1*x_11+...+cn*x_1n+e1
y2=c1*x_21+...+cn*x_2n+e2
...
ym=c1*x_m1+...+cn*x_mn+em
ei不同于e,这里的ei是值,不是随机变量,这些值的平均值是u,方差是sigma^2
(2)如下约定:
Y=(y1,y2,...,ym)^T
矩阵X=
x_11 x12 ... x_1n
x_21 x21 ... x_2n
...
x_m1 xm1 ... x_mn
beta=(c1,c2,...cn)^T
E=(e1,e2...,em)^T
符号^T表示矩阵转置
(3)线性回归模型矩阵形式表示如下:
Y=X*beta+E
generate_data方法就是根据这个随机生成数据的,
create_linear_model中省略了随机扰动项E,使用的是Y=X*beta
(4)损失函数:
L=(y1_pred-y1)^2 + ... + (ym_pred-ym)^2
yi_pred表示是数据xi根据求解后的模型计算出的预测值
代码中使用的是L/m,m是数据的个数,当数据的个数确定后,
两种损失函数等价,求解的模型参数一样
"""
import tensorflow as tf
import numpy as np
def create_linear_model(dimension):
"""定义线性回归模型
:param dimension: 数据的维数或者数据特征个数,比如对于数据x=(1,4,3),dimension就是3
:return: 返回创建好的模型
"""
# 自变量,x=(x1,...,xn),n=dimension,数据个数不确定,所以使用了None
x = tf.placeholder(tf.float64, shape=[None, dimension], name='x')
# 因变量,对应表达式的y
y = tf.placeholder(tf.float64, shape=[None, 1], name='y')
# 模型参数,对应模型中的c
beta = tf.Variable(np.random.random([dimension, 1]))
# 定义模型的表达式Y=X*beta
y_pred = tf.matmul(x, beta, name='y_pred')
# 定义损失函数(y_pred-y)^2/m
loss = tf.reduce_mean(tf.square(y_pred - y))
# 定义模型
model = {'loss_function': loss,
'independent_variable': x,
'dependent_variable': y,
'prediction': y_pred,
'model_params': beta}
return model
def gradient_descent(X, Y, model, learning_rate=0.01, max_iter=10000, tol=1.e-6):
"""
梯度下降法
:param x: 自变量数据
:param y: 因变量数据
:param model: 模型
:param learning_rate:学习率,默认是0.01
:param max_iter: 最大迭代次数,达到最大迭代次数,算法终止
:param tol: 总误差,默认是0.000001,误差小于该值算法终止
:return:
"""
# 定义梯度下降法,并设置学习率
method = tf.train.GradientDescentOptimizer(learning_rate=learning_rate)
# 定义一个求解“最小化损失函数“优化问题的优化器:
optimizer = method.minimize(model['loss_function'])
# 收集迭代过程中变量的数据信息
tf.summary.scalar('loss_function', model['loss_function'])
tf.summary.histogram('params', model['model_params'])
tf.summary.scalar('first_param', tf.reduce_mean(model['model_params'][0]))
tf.summary.scalar('last_param', tf.reduce_mean(model['model_params'][-1]))
summary = tf.summary.merge_all()
# 创建信息读写器,将数据信息写入文件
summary_writer = create_summary_writer('logs/gradient_descent')
# 模型变量初始化
sess = tf.Session()
init = tf.global_variables_initializer()
sess.run(init)
# 梯度下降法开始迭代
step = 0
pre_loss = np.inf
diff = np.inf
while (step < max_iter) & (diff > tol):
_, summary_info, loss = sess.run([optimizer, summary, model['loss_function']],
feed_dict={model['independent_variable']: X,
model['dependent_variable']: Y})
# 每次迭代的数据信息写入文件
summary_writer.add_summary(summary_info, step)
diff = abs(pre_loss - loss)
pre_loss = loss
step += 1
summary_writer.close()
def generate_data(num, dimension):
"""
随机产生模型数据,可以先阅读下create_linear_model方法中的文档注释
例如:num=5,dimension=3
beta= [1 2 3]
X=
[[0.17586156 0.1817122 0.531554 ]
[0.93252625 0.24245416 0.21445602]
[0.52736959 0.41516182 0.30301268]
[0.96282288 0.89517138 0.6235028 ]
[0.98281141 0.06380074 0.47512007]]
E=
[[0.50326889]
[0.61182256]
[0.74906335]
[0.64430668]
[0.77042713]]
Y=
[[2.63721685]
[2.67262519]
[3.01579462]
[5.26798074]
[3.30620023]]
:param dimension: 数据维数
:param num: 数据个数
:return: 随机生成的数据X,Y
"""
# 模型参数数据生成,为了生成Y,shape(1,dimension)
beta = np.array(range(dimension)) + 1
# 输入数据生成,shape(num, dimension)
X = np.random.random((num, dimension))
# 扰动项数据生成,shape(num, 1)
E = np.random.random((num, 1))
# 使用线性回归表达式生成y,shape(num, 1)
Y = X.dot(beta).reshape((-1, 1)) + E
return X, Y
def run():
"""
程序入口
:return:
"""
# 随机生成数据
num, dimension = 5, 3
x, y = generate_data(num, dimension)
# 定义模型
model = create_linear_model(dimension)
# 使用梯度下降法估计模型参数
gradient_descent(x, y, model)
def create_summary_writer(log_path):
"""定义信息收集器
:param log_path:
:return:
"""
if tf.gfile.Exists(log_path):
tf.gfile.DeleteRecursively(log_path)
summary_writer = tf.summary.FileWriter(log_path, graph=tf.get_default_graph())
return summary_writer
if __name__ == '__main__':
run()
程序成功执行后,生成一个数据信息文件,如图:
执行tensorboard --logdir [file_path]命令,如图:
file_path是文件所在目录,命令执行成功后,输出浏览器访问地址:http://leboop:6006
打开浏览器访问,程序在迭代过程中收集的数据信息,如图:
(1)标量信息,模型的第一个参数first_param和最后一个参数last_param,以及损失函数loss,如图:
(2)矩阵变量信息, 整个模型参数params,如图:
扫描二维码关注公众号,回复:
10775868 查看本文章
(3)TensorFlow计算图,如图:
(4)模型参数分布图,如图: