TensorFlow-深度学习-04-梯度下降求解线性回归
线性回归,说白了就是求一条线性方程,能够最大限度的把坐标图上的每个点包括到,或者让这些点能够更加接近这条直线,本节将使用梯度下降的方法求这条解线性方程。
有数据集的朋友可以使用pandas读取数据,这里我就不读取数据集了,有关于数据集的读取参考:机器学习——Pandas库
1、读取数据集
因为我这里没有数据集读取,所以自定义了100组数据(x,y)。
'''-----------------造数据-------------------'''
# 是文件可以用pandas读取
x = tf.Variable(tf.random_uniform([100],minval=0,maxval=20), dtype=tf.float32) # 随机构造30个点
line_y = tf.add(tf.multiply(1.2, x), 0.8) # y=k*x+c,求出x对应的线性方程的y值
这100组数据不可能是符合线性函数分布的数据,所以我们需要给每组y值加上(减去)一些小小的干扰,也就是噪声。
noise = tf.Variable(tf.random_normal([100], mean=0, stddev=0.8)) # 构造噪声干扰项,平均值接近0,方差越小就让这些数据都接近
y = tf.add(line_y, noise)
这样,我们的数据就建造完毕了。
2、构建W,b
在机器学习或深度学习中,一般用y=wx+b来表示这条方程。w,b可以是常数,也可以是矩阵。
w=tf.Variable(0.1,dtype=tf.float32) # 拟合方程的w,初值可以随便设,后面通过梯度下降可以更新
b=tf.Variable(0.1,dtype=tf.float32) # 拟合方程的b,初值可以随便设,后面通过梯度下降可以更新
然后根据y=wx+b来构建这条拟合方程,求出预测值:
y_=tf.add(tf.multiply(w,x),b) # 预测值
3、梯度下降
diff=tf.square(tf.subtract(y,y_)) # 平方差
loss=tf.reduce_mean(diff) #平均损失值
step=tf.train.GradientDescentOptimizer(learning_rate=0.01).minimize(loss)
4、训练
for i in range(10000):
sess.run(step)
if (i+1) % 1000==0:
curr_loss=sess.run(loss)
print("curr_loss:",curr_loss)
5、绘图
有关于绘图的操作可以参考:机器学习——数据可视化库Matplotlib
plt.plot(x,y,"ro",label="Point") # 画散点
y_=[]
for i in range(len(x)):
y_.append(w*x[i]+b) # 预测值
plt.plot(x,y_,color="blue",label="regression line") #画直线
plt.legend(loc="best")
plt.show()
至此,基本的线性回归模型就制作好了。下面附上所有源码:
import tensorflow as tf
import matplotlib.pyplot as plt # 画图库
'''目的:随机生成100个点,这100个点(x,y)并不是一条线性函数一一对应的,是有噪声干扰的,
我们通过梯度下降来拟合这条近似线性方程'''
def draw_line(x,y,w,b):
plt.plot(x,y,"ro",label="Point") # 画散点
y_=[]
for i in range(len(x)):
y_.append(w*x[i]+b) # 预测值
plt.plot(x,y_,color="blue",label="regression line") #画直线
plt.legend(loc="best")
plt.show()
def line_regression():
'''-----------------造数据-------------------'''
# 是文件可以用pandas读取
x = tf.Variable(tf.random_uniform([100],minval=0,maxval=14), dtype=tf.float32) # 随机构造30个点
line_y = tf.add(tf.multiply(1.2, x), 0.8) # y=k*x+c,求出x对应的线性方程的y值
noise = tf.Variable(tf.random_normal([100], mean=0, stddev=0.8)) # 构造噪声干扰项,平均值接近0,方差越小就让这些数据都接近
y = tf.add(line_y, noise)
'''-----------------拟合---------------------'''
w=tf.Variable(0.1,dtype=tf.float32) # 拟合方程的w,初值可以随便设,后面通过梯度下降可以更新
b=tf.Variable(0.1,dtype=tf.float32) # 拟合方程的b,初值可以随便设,后面通过梯度下降可以更新
y_=tf.add(tf.multiply(w,x),b) # 预测值
diff=tf.square(tf.subtract(y,y_)) # 平方差
loss=tf.reduce_mean(diff) #平均损失值
step=tf.train.GradientDescentOptimizer(learning_rate=0.01).minimize(loss)
init=tf.global_variables_initializer() # 变量初始化
with tf.Session() as sess:
sess.run(init)
for i in range(10000):
sess.run(step)
if (i+1) % 1000==0:
curr_loss=sess.run(loss)
print("curr_loss:",curr_loss)
new_w, new_b = sess.run([w, b]) # 需要把它变成一个tensor
new_x, new_y = sess.run([x, y]) # 需要把它变成一个tensor
print("w:",new_w,"b",new_b)
draw_line(new_x,new_y,new_w,new_b) #调用函数
if __name__=="__main__":
line_regression()
运行结果:
这里我训练了1万次,所得的loss值(只打印10次)为:
loss值最小达到了0.01,不算太小,我们可以加大训练次数。但是需要注意过拟合的发生,而数据模拟出来的w与b的数值为:
我刚开始设的值为line_y = tf.add(tf.multiply(1.2, x), 0.8) # y=k*x+c,求出x对应的线性方程的y值
,即w=1.2,b=0.8,可以看到,拟合出来的结果也还是比较准确。
拟合出来的图像为:
注意,在加大训练次数或增加学习率的时候,一定要注意缩小x值的范围,不然,loss会出现Nan的情况。