使用tensorflow api来实现线性拟合数据
为了便于计算以及求解,假定样本特征是二维的。
给定样本集D={x1,x2....xm} Di=(xi,yi)其中xi={xi1,xi2}有2个特征,求一个线性模型f=wx+b来拟合所有数据。
代码如下:
import tensorflow as tf
import numpy as np
# 使用 NumPy 生成假数据(phony data), 总共 100 个点.
x_data = np.float32(np.random.rand(2, 100)) # 随机输入
y_data = np.dot([0.100, 0.200], x_data) + 0.300
# 构造一个线性模型
#
b = tf.Variable(tf.zeros([1]))
W = tf.Variable(tf.random_uniform([1, 2], -1.0, 1.0))
y = tf.matmul(W, x_data) + b
# 最小化方差
loss = tf.reduce_mean(tf.square(y - y_data))
optimizer = tf.train.GradientDescentOptimizer(0.5)
train = optimizer.minimize(loss)
# 初始化变量
init = tf.initialize_all_variables()
# 启动图 (graph)
sess = tf.Session()
sess.run(init)
# 拟合平面
for step in range(0, 201):
sess.run(train)
if step % 20 == 0:
print (step, sess.run(W), sess.run(b))
# 得到最佳拟合结果 W: [[0.100 0.200]], b: [0.300]
1.首先产生一个随机的二维数组作为样本集X:
x_data = np.float32(np.random.rand(2, 100))
其中numpy.random.rand(d1,d2)函数:产生一个d1*d2维的数组,数组每个元素是[0,1)的一个随机数
2.利用y=w1x1+w2x2+b来产生样本X对应的y值
其中取w1=0.1, w2=0.2, b=0.3 即最终结果得到的拟合曲线应该是:
y=0.1x1+0.2x2+0.3
y_data = np.dot([0.100, 0.200], x_data) + 0.300
其中numpy.dot函数是 两个矩阵相乘 这里注意样本X的特征是按列排列的,之前学习时接触的是按行排列的。
3.构建一个线性模型f=wx+b 其中2维特征,即w也是1维
# 构造一个线性模型
b = tf.Variable(tf.zeros([1]))
W = tf.Variable(tf.random_uniform([1, 2], -1.0, 1.0))
y = tf.matmul(W, x_data) + b
tensorflow API学习:
API地址:https://tensorflow.google.cn/api_docs/python/tf
tf.zeros([d1,d2], dtype) 返回一个d1*d2维的零元素数组
tf.random_uniform 返回一个指定维数的数组,数组中每个元素为[min,max]中的一个随机值
tf.matmul返回两个矩阵相乘结果:
格式: tf.matmul(a, b, transpose_a=False, transpose_b=False, adjoint_a=False, adjoint_b=False, a_is_sparse=False, b_is_sparse=False, name=None)
参数:
a: 一个类型为 float16, float32, float64, int32, complex64, complex128 且张量秩 > 1 的张量。
b: 一个类型跟张量a相同的张量。
transpose_a: 如果为真, a则在进行乘法计算前进行转置。
transpose_b: 如果为真, b则在进行乘法计算前进行转置。
adjoint_a: 如果为真, a则在进行乘法计算前进行共轭和转置。
adjoint_b: 如果为真, b则在进行乘法计算前进行共轭和转置。
a_is_sparse: 如果为真, a会被处理为稀疏矩阵。
b_is_sparse: 如果为真, b会被处理为稀疏矩阵。
name: 操作的名字(可选参数)
返回值: 一个跟张量a和张量b类型一样的张量且最内部矩阵是a和b中的相应矩阵的乘积。
注意:
(1)输入必须是矩阵(或者是张量秩 >2的张量,表示成批的矩阵),并且其在转置之后有相匹配的矩阵尺寸。
(2)两个矩阵必须都是同样的类型,支持的类型如下:float16, float32, float64, int32, complex64, complex128。
4.损失函数为均方误差,即最小化均方误差
# 最小化方差
loss = tf.reduce_mean(tf.square(y - y_data))
optimizer = tf.train.GradientDescentOptimizer(0.5)
train = optimizer.minimize(loss)
tf.square函数: 返回两个元素的平方
tf.reduce_mean函数:求平均值
axis==None求所有元素平均值返回一个元素
axis==0 按列求平均值
axis==1 按行求平均值
其中GradientDescentOptimizer实现了随机梯度下降算法:
https://tensorflow.google.cn/api_docs/python/tf/train/GradientDescentOptimizer
learning_rate 为学习率
minimize方法:按照损失函数求解最优值
5.随机梯度下降算法:Stochastic gradient descent
随机选择一个梯度方向来不断迭代不断逼近最优值
其中alpha为学习率,上式取0.5
缺点:每次更新可能并不会按照正确的方向进行,因此可以带来优化波动(扰动)
优点:随机梯度下降算法每次只随机选择一个样本来更新模型参数,因此每次的学习是非常快速的,并且可以进行在线更新。随机梯度下降波动的特点可能会使得优化的方向从当前的局部极小值点跳到另一个更好的局部极小值点,这样便可能对于非凸函数,最终收敛于一个较好的局部极值点,甚至全局极值点。
关于随机梯度下降一篇很好的学习资料:
https://www.cnblogs.com/pinard/p/5970503.html
最终结果,迭代200次,可知最终结果是不断逼近y=0.1x1+0.2x2+0.3
6.随机梯度下降过程中拟合平面的3D变化过程:
import tensorflow as tf
import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
# 使用 NumPy 生成假数据(phony data), 总共 100 个点.
x_data = np.float32(np.random.rand(2, 100)) # 随机输入
y_data = np.dot([0.100, 0.200], x_data) + 0.300
# 构造一个线性模型
#
b = tf.Variable(tf.zeros([1]))
W = tf.Variable(tf.random_uniform([1, 2], -1.0, 1.0))
y = tf.matmul(W, x_data) + b
X, Y = np.meshgrid(x_data[0], x_data[1])
# 最小化方差
#print(tf.square(y - y_data))
loss = tf.reduce_mean(tf.square(y - y_data))
optimizer = tf.train.GradientDescentOptimizer(0.5)
train = optimizer.minimize(loss)
# 初始化变量
init = tf.initialize_all_variables()
# 启动图 (graph)
sess = tf.Session()
sess.run(init)
# 拟合平面
for step in range(0, 201):
sess.run(train)
if step % 20 == 0:
#print (step, sess.run(W), sess.run(b))
print (step, sess.run(W)[0][0], sess.run(W)[0][1], sess.run(b)[0])
#print (sess.run(b)[0])
Z = sess.run(W)[0][0]*X + sess.run(W)[0][1]*Y + sess.run(b)[0]
fig = plt.figure()
ax = Axes3D(fig)
ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap='rainbow')
plt.show()
分20次绘制拟合平面的3D位置:部分效果如下:
以上为迭代次数0,20,40,60,180,200次时,拟合平面的位置
可以考虑一下动画效果
参考地址
http://python.jobbole.com/81185/
http://docs.enthought.com/mayavi/mayavi/mlab.html#id1
刚开始学习,之后有时间研究一下tensorflow源码,研究一下随机梯度下降是如何实现的。