Tensorflow实现线性回归
线性回归理论以及公式:
目标公式:
当有m组训练公式的时候,输入数据写成矩阵的形式:
X=⎡⎣⎢⎢⎢⎢⎢⎢⎢x(1)1x(2)1⋮x(m)1x(1)2x(2)2⋮x(m)2⋯⋯⋱⋯x(1)nx(2)n⋮x(m)n⎤⎦⎥⎥⎥⎥⎥⎥⎥
X
=
[
x
1
(
1
)
x
2
(
1
)
⋯
x
n
(
1
)
x
1
(
2
)
x
2
(
2
)
⋯
x
n
(
2
)
⋮
⋮
⋱
⋮
x
1
(
m
)
x
2
(
m
)
⋯
x
n
(
m
)
]
权重写成权重向量:
偏置项向量: b=[b,b,⋯,b]Tn×1 b = [ b , b , ⋯ , b ] n × 1 T
一般来说,为了加快训练速度,梯度下降的时候,是以向量为单位,对向量进行求导。给出线性回归的使用到的求导公式:
其中: W W 是对称矩阵,小写的粗体是向量。公式来自于Matrix Cookbook这个PDF文档。
给出损失函数的矩阵化定义:
Im×m I m × m 是m阶的单位矩阵,这里只是为了更好的理解求导过程,单位矩阵肯定是对称矩阵,实际可以不加。
根据求导公式:
梯度下降的更新过程:
其中 α α 是学习速率。
tensorflow实现:
实际使用tensorflow的过程中,可以使用库函数实现自动化微分求导的过程,不必手写。
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
# 输入数据
x_data = np.random.normal(size=(100, 3))
w_real = np.matrix([3.0, 5.1, 1.7]).T
b_real = 0.2
y_data = np.matmul(x_data, w_real) + b_real * np.ones((100, 1))
# 占位符,输送数据
x = tf.placeholder(dtype=tf.float32, shape=[None, 3], name="x_train")
y_true = tf.placeholder(dtype=tf.float32, shape=None, name="y_true")
with tf.name_scope("inference") as scope:
w = tf.Variable(tf.zeros([3, 1]))
# 不显示地声明形状,形状会自适应
b = tf.Variable(0.0)
y_pred = tf.matmul(x, w) + b
with tf.name_scope("loss") as scope:
# 损失函数
loss = tf.reduce_mean(1 / 2 * tf.square(y_pred - y_true))
with tf.name_scope("train") as scope:
# 训练,使用Adam算法优化,学习步长0.1
train = tf.train.AdamOptimizer(0.1).minimize(loss)
# 用于绘图
x_axis = []
y_axis = []
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
# 执行1000次训练
for i in range(1000):
sess.run(train, feed_dict={x: x_data, y_true: y_data})
x_axis.append(i)
# 这里也需要feed数据
y_axis.append(sess.run(loss, feed_dict={x: x_data, y_true: y_data}))
print("loss:", sess.run(loss, feed_dict={x: x_data, y_true: y_data}))
print(sess.run(w), sess.run(b))
tf.summary.FileWriter("./graph", sess.graph)
plt.plot(x_axis, y_axis)
plt.show()
结果输出:
loss: 4.579861e-13
3.0000002,5.100001,1.7
0.19999987
损失函数图片:
tensorboard图片: