zoukankan      html  css  js  c++  java
  • 【tf.wiki】02-TensorFlow基础示例:线性回归 (分别使用np和ts进行梯度下降预测房价+反归一化还原数据)

    知识补充

    举例函数(Z=f(X,Y)):

    • 偏导数
      • 将X固定,Z的增量除以Y的增量,我们称之为Z对Y的偏导数
      • 同理,我们保持Y值不变,Z值仅随X值改变,Z的增量除以X的增量,我们称之为Z对X的偏导数
    • 梯度
      • 每个点都有一个箭头来表示Z对X的偏导数,每个点都有一个箭头来表示Z对Y的偏导数
      • 我们将这两个箭头向量相加,就得到一个新向量,称之为Z的梯度
      • Z的梯度向量总是指向Z函数增长最大的地方
      • 可以得出梯度是Z=f(X,Y)某一点的含有方向的导数,这个方向导数乘以该点的单位向量,就得到一个准确数值,这个数值就是该点在这个方向上的变换率。

    示例说明

    考虑一个实际问题,某城市在 2013 年 - 2017 年的房价如下表所示:

    年份 2013 - 2017

    房价 12000 14000 15000 16500 17500

    现在,我们希望通过对该数据进行线性回归,即使用线性模型 y = ax + b 来拟合上述数据,此处 a 和 b 是待求的参数。

    首先,我们定义数据,进行基本的归一化操作。

    首先对数据进行归一化

    import numpy as np
    
    X_raw = np.array([2013, 2014, 2015, 2016, 2017], dtype=np.float32)
    y_raw = np.array([12000, 14000, 15000, 16500, 17500], dtype=np.float32)
    
    from sklearn import preprocessing
    x_scaler = preprocessing.MinMaxScaler().fit(X_raw.reshape(-1, 1))
    y_scaler = preprocessing.MinMaxScaler().fit(y_raw.reshape(-1, 1))
    
    X = x_scaler.transform(X_raw.reshape(1, -1))
    y = y_scaler.transform(y_raw.reshape(1, -1))
    
    print(X)
    print(y)
    
    print('*'*20, '反向')
    print(x_scaler.inverse_transform(X))
    print(y_scaler.inverse_transform(y))
    # print(preprocessing.minmax_scale.inverse_transform(y))
    print(X)
    print(y)
    
    [[0.   0.25 0.5  0.75 1.  ]]
    [[0.         0.3636365  0.54545474 0.818182   1.        ]]
    ******************** 反向
    [[2013. 2014. 2015. 2016. 2017.]]
    [[11999.999 14000.    15000.001 16500.    17500.   ]]
    [[0.   0.25 0.5  0.75 1.  ]]
    [[0.         0.3636365  0.54545474 0.818182   1.        ]]
    

    接下来,我们使用梯度下降方法来求线性模型y=a*x+b中两个参数 a 和 b 的值;

    回顾机器学习的基础知识,对于多元函数 f(x) 求局部极小值,梯度下降 的过程如下:

    • 初始化自变量为 (x_0) , k=0

    • 迭代进行下列步骤直到满足收敛条件:

      • 求函数 f(x) 关于自变量的梯度 ( abla f(x_k))

      • 更新自变量: (x_{k+1} = x_{k} - gamma abla f(x_k)) 。这里 (gamma) 是学习率(也就是梯度下降一次迈出的 “步子” 大小)

      • (k leftarrow k+1) (迭代下一轮)

    接下来,我们考虑如何使用程序来实现梯度下降方法,求得线性回归的解 (min_{a, b} L(a, b) = sum_{i=1}^n(ax_i + b - y_i)^2)

    NumPy 下的线性回归

    此处的损失函数为均方误差 (L(x) = sum_{i=1}^N (ax_i + b - y_i)^2)。其关于参数 a 和 b 的偏导数为 (frac{partial L}{partial a} = 2 sum_{i=1}^N (ax_i + b - y) x_i),$frac{partial L}{partial b} = 2 sum_{i=1}^N (ax_i + b - y) $。本例中 $N = 5 $。

    由于均方误差取均值的系数$ frac{1}{N}$ 在训练过程中一般为常数( N 一般为批次大小),对损失函数乘以常数等价于调整学习率,因此在具体实现时通常不写在损失函数中。

    NumPy手动计算损失函数

    a,b = 0,0
    
    num_epoch = 10000
    learning_rate = 5e-4
    
    for e in range(num_epoch):
        # 手动计算损失函数关于自变量(模型参数)的梯度
        y_pred = a* X[0] + b
        grad_a, grad_b = 2* (y_pred - y[0]).dot(X[0]), 2*(y_pred - y[0]).sum()
    
        # 更新参数
        a, b = a - learning_rate * grad_a, b - learning_rate * grad_b
    
    print(a, b)
    

    Numpy 反归一化,还原数据

    # 房价预测对比
    print(X_raw)
    print(y_raw)
    res = X * a + b
    
    print(res)
    print(y_scaler.inverse_transform(res.reshape(-1, 1) ))
    print(y_scaler.inverse_transform(res.reshape(-1, 1) ).reshape(1, -1))
    
    [2013. 2014. 2015. 2016. 2017.]
    [12000. 14000. 15000. 16500. 17500.]
    [[0.05756507 0.30165762 0.5457502  0.7898427  1.0339353 ]]
    [[12316.606]
     [13659.116]
     [15001.625]
     [16344.134]
     [17686.645]]
    [[12316.606 13659.116 15001.625 16344.134 17686.645]]
    

    TensorFlow 下的线性回归

    使用 TensorFlow 计算线性回归, 程序的结构和前述 NumPy 的实现非常类似:
    这里,TensorFlow 帮助我们做了两件重要的工作:

    • 使用 tape.gradient(ys, xs) 自动计算梯度;
    • 使用tf.keras.optimizers.SGD 自动进行优化计算
    • 使用 optimizer.apply_gradients(grads_and_vars) 自动更新模型参数。
    import tensorflow as tf
    # python --version
    print(tf.__version__)
    
    2.1.0
    
    tf_X = tf.constant(X)
    tf_y = tf.constant(y)
    
    tf_a, tf_b = tf.Variable(initial_value=0.), tf.Variable(initial_value=0.)
    variables = [tf_a, tf_b]
    
    num_epoch = 10000
    optimizer = tf.keras.optimizers.SGD(learning_rate=5e-4)
    for e in range(num_epoch):
        # 使用tf.GradientTape()记录损失函数的梯度信息
        with tf.GradientTape() as tape:
            tf_y_pred = tf_a * tf_X + tf_b
            loss = tf.reduce_sum(tf.square(tf_y_pred - tf_y))
        # TensorFlow自动计算损失函数关于自变量(模型参数)的梯度
        grads = tape.gradient(loss, variables)
    
        # TensorFlow自动根据梯度更新参数
        optimizer.apply_gradients(grads_and_vars=zip(grads, variables))
    
    print('variables', variables)
    
    variables [<tf.Variable 'Variable:0' shape=() dtype=float32, numpy=0.97637004>, <tf.Variable 'Variable:0' shape=() dtype=float32, numpy=0.057565123>]
    

    TensorFlow 反归一化,还原数据

    # 房价预测对比
    print(X_raw)
    print(y_raw)
    tf_res = np.array(X * tf_a + tf_b)
    
    print(tf_res)
    print(y_scaler.inverse_transform(tf_res.reshape(-1, 1) ))
    print(y_scaler.inverse_transform(tf_res.reshape(-1, 1) ).reshape(1, -1))
    
    
    [2013. 2014. 2015. 2016. 2017.]
    [12000. 14000. 15000. 16500. 17500.]
    [[0.05756512 0.30165762 0.54575014 0.7898426  1.0339352 ]]
    [[12316.608]
     [13659.116]
     [15001.625]
     [16344.134]
     [17686.643]]
    [[12316.608 13659.116 15001.625 16344.134 17686.643]]
    你不逼自己一把,你永远都不知道自己有多优秀!只有经历了一些事,你才会懂得好好珍惜眼前的时光!
  • 相关阅读:
    Java命令行启动jar包更改默认端口以及配置文件的几种方式
    Windows下带配置文件的mysql命令行安装方法
    Windows下mysql主从搭建
    Windows下mysql集群搭建
    CAP原则(CAP定理)、BASE理论(精简)
    进程间通讯的7种方式
    Go Web 编程之 数据库
    Go 每日一库之 fsnotify
    Go 每日一库之 viper
    Go 每日一库之 go-ini
  • 原文地址:https://www.cnblogs.com/zhazhaacmer/p/14437215.html
Copyright © 2011-2022 走看看