使用tensorflow做梯度下降的线性回归_Tensorflow

 

tensorflow的安装

 

tensorflow支持的操作系统:

  • Ubuntu 16.04 或更高版本

  • Windows 7 或更高版本

  • macOS 10.12.6 (Sierra) 或更高版本(不支持 GPU)

  • Raspbian 9.0 或更高版本

 

在windows上安装,命令很简单:pip3 install tensorflow,因为我装了双版本Python,所以执行需要加上版本号。

注意:需要保证是 64位的Python 3.4、3.5 或 3.6版本,否则会有报错信息:

ERROR: Could not find a version that satisfies the requirement tensorflow (from versions: none)
ERROR: No matching distribution found for tensorflow

使用tensorflow做梯度下降的线性回归_Tensorflow _02

 

cmd命令行进入Python环境,64位Python版本信息是这样的

Python 3.6.6 (v3.6.6:4cf1f54eb7, Jun 27 2018, 03:37:03) [MSC v.1900 64 bit (AMD64)] on win32

[MSC v.1900 64 bit (AMD64)]  这几个字表示64位

 

windows安装官方文档:

https://www.tensorflow.org/install/pip

 

tensorflow支持在docker容器中运行,在docker环境下运行,tensorflow运行环境可以与系统环境隔开,不依赖于系统环境,却能共享主机的资源。

docker安装官方文档:https://www.tensorflow.org/install/docker

 

线性回归

 

不同于聚类,线性回归是一种有监督学习,标签是已知的。这里拿美国房价数据,共有81列,房价影响因素很多,简单起见,取其面积与房价两列,分别作为输入(特征),输出(标签),通过tensorflow训练得到一条线性回归表达式,以此来预测房价。

 

数据下载地址:https://www.kaggle.com/c/house-prices-advanced-regression-techniques/data

注: 链接被”墙“,需要vpn下载,可以使用这个免费chrome浏览器插件,开通google账号,并且使用google账号登陆后,才能下载。chrome浏览器插件地址,复制地址到浏览器,按照安装向导安装浏览器插件即可:http://qiniu.ikeguang.com/software/ikeguang.com/%E8%B0%B7%E6%AD%8C%E8%AE%BF%E9%97%AE%E5%8A%A9%E6%89%8Bchrome%E7%89%88.rar

使用tensorflow做梯度下降的线性回归_Tensorflow _03

 

使用tensorflow做梯度下降的线性回归_Tensorflow _04

 

数据前20行是这样的:

 

8450 208500
9600 181500
11250 223500
9550 140000
14260 250000
14115 143000
10084 307000
10382 200000
6120 129900
7420 118000
11200 129500
11924 345000
12968 144000
10652 279500
10920 157000
6120 132000
11241 149000
10791 90000
13695 159000
7560 139000

房价与面积的关系,可以将这种关系写下来,如下所示:

使用tensorflow做梯度下降的线性回归_Tensorflow _05

其中:

  •  y指的房价,即我们试图预测的值。

  •  m指的是直线的斜率。

  •  x指的是房屋面积,即输入特征的值。

  •  b指的是 y 轴截距。

 

按照机器学习的惯例,需要写一个存在细微差别的模型方程式:

使用tensorflow做梯度下降的线性回归_Tensorflow _06

 

其中:

  • y'指的是预测标签(理想输出值)。

  • b指的是偏差(y 轴截距)。而在一些机器学习文档中,它称为w0 。

  • w1指的是特征 1 的权重。权重与上文中用m表示的“斜率”的概念相同。

  • x1指的是特征(已知输入项)。

 

假设这条直线拟合好后,与真实值肯定有误差,通常计算均方误差,这个均方误差的概念,很好理解。

均方误差 (MSE) 指的是每个样本的平均平方损失。要计算 MSE,请求出各个样本的所有平方损失之和,然后除以样本数量:

使用tensorflow做梯度下降的线性回归_Tensorflow _07

我们需要拿一个模型来训练数据,通常由一个初始点开始,逐渐迭代降低损失,迭代学习可以联想到“二分查找”,“Hot and Cold”这种寻找隐藏物品(如顶针)的儿童游戏。在我们的游戏中,“隐藏的物品”就是最佳模型。刚开始,您会胡乱猜测(的值为 0。),等待系统告诉您损失是多少。然后,您再尝试另一种猜测(w1 的值为 0.5。),看看损失是多少。哎呀,这次更接近目标了。实际上,如果您以正确方式玩这个游戏,通常会越来越接近目标。这个游戏真正棘手的地方在于尽可能高效地找到最佳模型。

使用tensorflow做梯度下降的线性回归_Tensorflow _08

降低损失 (Reducing Loss):梯度下降法

 

误差也叫损失,与模型参数,即w的关系,可以表示如下:

使用tensorflow做梯度下降的线性回归_Tensorflow _09

即y = wx + b中,横轴w就是要找的,需要找到一个最佳的权重w值,使得误差(损失)最小,曲线最低处倒数为0,显然是个极小值点,这个取值w,对应损失最小。根据,显然是存在的。

已经确定,这个参数w肯定存在,那么怎么找出来,怎么最快的找出来?

 

梯度下降法,可以帮助我们快速找到这个点,梯度概念简单提一下。

使用tensorflow做梯度下降的线性回归_Tensorflow _10

大家都知道,梯度始终指向损失函数中增长最为迅猛的方向。梯度下降法算法会沿着负梯度的方向走一步,以便尽快降低损失。

 

“梯度始终指向损失函数中增长最为迅猛的方向”,我们想要快速减小损失函数,沿着负梯度的方向即可。

 

tensorflow代码

 

主要是读取训练数据,归一化(数据太大,无法训练),进行训练,最后进行误差梯度下降的展示。

import tensorflow as tf
import numpy as np
from matplotlib import pyplot as plt

def run():
    # 读取数据
    data = np.genfromtxt('data_areaSize_price.csv',delimiter=',',dtype=np.float)

    # 数据归一化
    x_data = np.array(data[:,0]) / np.max(data[:,0])
    y_data = np.array(data[:,1]) / np.min(data[:,1])

    # print(x_data)
    # print(y_data)

    # ===========模型搭建=====================
    # 声明weights变量是一个 -1到 1值,bias变量默认为0, 
    # 表达式 y = weights * x_data + biases 就是模型了
    weights = tf.Variable(tf.random_uniform([1], -1,0, 1.0))
    biases = tf.Variable(tf.zeros([1]))

    y = weights*x_data + biases


    # ===========计算误差:均方误差===========
    loss = tf.reduce_mean(tf.square(y-y_data))

    # ===========误差传播:梯度下降法===========
    optimizer = tf.train.GradientDescentOptimizer(0.5)

    # ================训练==================
    train = optimizer.minimize(loss)

    init = tf.global_variables_initializer() 

    sess = tf.Session()
    sess.run(init)         

    # 两次迭代损失差向量
    y_loss = []

    # 最大迭代次数
    iterate_max = 1000
    # 两次迭代损失差最大值
    loss_diff = 0.001
    # 初使误差值
    loss_pre = 0

    # 记录迭代的次数
    iterate_n = 0

    for step in range(iterate_max):
        sess.run(train)
        iterate_n = iterate_n + 1

        # y_loss.append(sess.run(loss))
        y_loss.append(abs(sess.run(loss) - loss_pre))

        if abs(sess.run(loss) - loss_pre) < loss_diff:
            print('iterate_n => ', iterate_n)
            print('loss_pre => ', loss_pre)
            print(step, 'weight => ',sess.run(weights), ' bias => ', sess.run(biases), 'loss => ',sess.run(loss))
            break

        loss_pre = sess.run(loss)

    print(y_loss)

    # 误差梯度下降展示
    plt.plot(range(iterate_n),y_loss)
    plt.show()

if __name__ == '__main__':
    run()

 

结果

使用tensorflow做梯度下降的线性回归_Tensorflow _11

iterate_n =>  115
loss_pre =>  5.0508256
114 weight =>  [2.5534637]  bias =>  [5.060318] loss =>  5.049826
[5.1966233253479, 0.0017781258, 0.001616478, 0.0016093254, 0.0016021729, 0.0015954971, 0.0015892982, 0.0015816689, 0.0015745163, 0.0015678406, 0.0015621185, 0.001554966, 0.0015478134, 0.0015425682, 0.001534462, 0.0015287399, 0.0015220642, 0.0015153885, 0.0015082359, 0.0015029907, 0.0014958382, 0.0014896393, 0.0014829636, 0.0014767647, 0.0014696121, 0.0014648438, 0.0014576912, 0.001452446, 0.0014448166, 0.0014400482, 0.0014328957, 0.0014276505, 0.0014204979, 0.0014152527, 0.0014081001, 0.0014028549, 0.0013971329, 0.001390934, 0.0013837814, 0.0013790131, 0.0013737679, 0.0013666153, 0.0013608932, 0.0013551712, 0.0013494492, 0.001344204, 0.0013380051, 0.0013327599, 0.0013260841, 0.0013213158, 0.0013155937, 0.0013084412, 0.0013051033, 0.0012969971, 0.0012936592, 0.0012869835, 0.0012822151, 0.0012755394, 0.0012717247, 0.0012655258, 0.0012593269, 0.0012555122, 0.0012483597, 0.001244545, 0.0012388229, 0.0012335777, 0.0012264252, 0.0012230873, 0.0012178421, 0.0012116432, 0.0012078285, 0.0012016296, 0.0011968613, 0.0011925697, 0.0011854172, 0.0011806488, 0.001177311, 0.0011715889, 0.0011649132, 0.001162529, 0.0011553764, 0.0011520386, 0.0011467934, 0.0011410713, 0.0011367798, 0.0011320114, 0.0011277199, 0.001121521, 0.0011167526, 0.0011129379, 0.0011081696, 0.0011019707, 0.0010986328, 0.0010938644, 0.0010886192, 0.0010843277, 0.0010795593, 0.0010757446, 0.0010704994, 0.0010652542, 0.0010609627, 0.0010561943, 0.0010523796, 0.0010480881, 0.0010428429, 0.001039505, 0.0010333061, 0.0010313988, 0.0010251999, 0.0010194778, 0.0010175705, 0.0010123253, 0.0010085106, 0.0010027885, 0.0009994507]

程序中设置最大迭代次数1000次,最大两次误差的差为0.001,程序实际迭代了115次,第114次误差为5.0508256 第115次误差为5.060318 两次误差的差别很小,为0.0009994507 <0.001,收敛,程序结束。。。

最终得到,房价与房屋面积关系表达式为:

y = 2.5534637 *x + 5.060318