Gradient Descent in Linear Regression

Table of Contents

第五章 梯度下降

       通过直接计算得到的参数值一定是不够精确的,还需要通过训练不断将参数进行优化,而梯度下降为常用的优化算法。
       在Tensorflow中可以通过手工和自动的方式计算梯度也可以通过种优化器计算并优化梯度,此外还可以修改数据的提供方式来实现最小梯度下降。

5.1 准备工作

  1. 导入相关包

    import tensorflow as tf
    import numpy as np
    from sklearn.datasets import fetch_california_housing
    from sklearn.preprocessing import StandardScaler
    
  2. 下载并整理数据

    housing = fetch_california_housing()
    m,n = housing.data.shape # 获取数据的行列数
    housing_data_plus_bias = np.c_[np.ones((m,1)),housing.data] # 为数据添加偏差项,即添加y=ax+b中的b
    
  3. 数据预处理(归一化)

    scaler = StandardScaler().fit(housing_data_plus_bias)
    scaled_housing_data_plus_bias = scaler.transform(housing_data_plus_bias)
    

5.2 手工计算梯度

       通过公式计算梯度,手写梯度下降算法进行优化。

  1. 创建计算图

    n_epochs = 1000
    global_learning_rate = 0.01
    X = tf.constant(scaled_housing_data_plus_bias, dtype=tf.float32, name="X")
    y = tf.constant(housing.target.reshape(-1,1), dtype=tf.float32, name="y") # 数据标签
    XT = tf.transpose(X)
    theta = tf.Variable(tf.random_uniform([n+1,1],-1.0,1.0),name="theta")     # 参数
    y_pred =  tf.matmul(X, theta, name="prediction")                          # 预测值
    error = y_pred-y                                                          # 误差
    mse = tf.reduce_mean(tf.square(error), name="mse")                        # 均方误差(成本函数)
    gradient = 2/m * tf.matmul(XT, error)                                     # 梯度
    training_op = tf.assign(theta, theta-global_learning_rate*gradient)       # 训练
    
  2. 创建会话,执行计算图

    init = tf.global_variables_initializer()                                  # 添加初始化节点
    
    with tf.Session() as sess:
        sess.run(init)
    
        for epoch in range(n_epochs):                                       # 逐步训练
          if epoch%100==0:
             print("Epoch:", epoch, "MSE=", mse.eval())                    # 每一步均方误差
             sess.run(training_op)                                             # 执行每一步训练,更新梯度
      
        best_theta = theta.eval()                                             # 训练完毕,返回最佳参数
        print("The best theta is", best_theta)
    

5.3 自动计算梯度

       通过Tensorflow自带函数自动计算梯度,依然手写梯度下降算法进行优化。

  1. 创建计算图
    只需在手工计算梯度的计算图上将gradient=...修改为:

    gradient = tf.gradients(mse, [theta])[0]                                  # 使用反向自动微分计算梯度
    

    在 Tensorflow中自动计算梯度使用的是反向自动微分方法,此外还有数值微分,符号微分和前向自动微分,它们的用法及区别参见博客自动微分

  2. 创建会话
    与手工计算梯度相同,不再赘述。

5.4 优化器

       自动计算梯度并利用Tensorflow中的优化器进行优化。

  1. 创建计算图
    只需在自动计算梯度的计算图上将training_op=...修改为:

    ## 定义优化器(梯度下降)
    # optimizer = tf.train.GradientDescentOptimizer(learning_rate =   global_learning_rate)
    ## 定义优化器(动量)
    optimizer = tf.train.MomentumOptimizer(learning_rate = global_learning_rate, momentum = 0.9)
    training_op = optimizer.minimize(mse)
    
  2. 创建会话
    与自动计算梯度相同,不再赘述。

5.5 批量梯度下降

       要实现最小批量梯度下降算法,需要每次训练时用小批量替换输入数据X和y。可以添加一个占位符节点执行该替换操作。它不进行任何计算,只在运行时输出需要输出的值。

  1. 创建计算图
    需要将X,y定义为占位符节点并且定义批量的大小与批量的个数,其它与之前的计算图相同,但不可使用动量优化器:

    X = tf.placeholder(tf.float32, shape=(None, n+1), name="X")
    y = tf.placeholder(tf.float32, shape=(None, 1), name="y")
    batch_size = 100
    n_batches= int(np.ceil(m/batch_size))
    
  2. 创建会话
    先创建进行批量替换的函数,然后创建会话,详情如下:

    init = tf.global_variables_initializer()                                  # 添加初始化节点
    
    def fetch_batch(epoch, batch_index, batch_size):
         np.random.seed(epoch * n_batches + batch_index) 
         indices = np.random.randint(m, size=batch_size)
         X_batch = scaled_housing_data_plus_bias[indices] 
         y_batch = housing.target.reshape(-1, 1)[indices] 
         return X_batch, y_batch
    
    with tf.Session() as sess:
        sess.run(init)
    
        for epoch in range(n_epochs):
           for batch_index in range(n_batches):
              X_batch, y_batch = fetch_batch(epoch, batch_index, batch_size)
              sess.run(training_op, feed_dict={X:X_batch, y:y_batch})
        best_theta = theta.eval()
        print("The best theta is", best_theta) 
    

5.6 参考

[1] Wanna_Go.tensorflow的一些基础用法
[2] 乖乖猪001.tensorflow的归一化与梯度下降
[3] Geron.机器学习实战
[4] BogeyDa.梯度下降算法总览

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值