用TensorFlow来实现梯度下降

Posted Lenskit

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用TensorFlow来实现梯度下降相关的知识,希望对你有一定的参考价值。

本篇我们尝试使用批量梯度下降。

首先我们将通过手动计算梯度来实现,然后使用TensorFlow的自动扩展功能来使TensorFlow自动计算梯度,最后我们将使用几个TensorFlow的优化器。

使用梯度下降时,首先要对输入特征向量进行归一化,否则训练会慢很多,可以使用TensorFlow,numpy,sklearn的standardscaler或其他解决方案,下面的代码会假定此规范化已经完成。

手动计算渐变:

# 梯度下降
import numpy as np
import tensorflow as tf
from sklearn.datasets import fetch_california_housing
from sklearn.preprocessing import scale

housing = fetch_california_housing()
m, n = housing.data.shape
# np.c_ 按colunm来组合array
housing_data_plus_bias = np.c_[np.ones((m, 1)), housing.data]
scaled_housing_data_plus_bias = scale(housing_data_plus_bias)
n_epochs = 1000
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")
theta = tf.Variable(tf.random_uniform([n + 1, 1], -1.0, 1.0), name="theta")
y_pred = tf.matmul(X, theta, name="predictions")
error = y_pred - y
mse = tf.reduce_mean(tf.square(error), name="mse")
gradients = 2 / m * tf.matmul(tf.transpose(X), error)
training_op = tf.assign(theta, theta - learning_rate * gradients)
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()

这个代码可以正常运行,但是需要从MSE中利用数学公式推导梯度。在线性回归中还比较容易,但如果用深度神经网络,会头很大。其实可以使用TensorFlow的自动计算梯度功能计算这个公式,只需要将上面的gradients = ...这一行替换为gradients = tf.gradients(mse,[theta])[0],gradients()函数使用一个op(此处是MSE)和一个变量列表(此处是theta),它创建一个ops列表(每个变量一个)来计算op的梯度变量。因此,梯度节点将计算MSE相对于theta的梯度向量。

自动计算梯度有四种主要方法,TensorFlow使用反向模式,这非常高效和准确,当有很多输入和少量的输出(比如神经网络)时,它只需要通过Noutput+1次图遍历就可以计算出所有输出的偏导数。

使用优化器

上面已经介绍了TensorFlow帮我们计算梯度,但其实还有更好的方法:TensorFlow提供了一些可以直接使用的优化器,包括梯度下降优化器,可以使用下面的代码替换上面的gradients=。。。和training_op=。。。:

optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate)
training_op = optimizer.minimize(mse)

如果要使用其他类型的优化器,只需要更改一行,例如可以通过定义优化器来使用动量优化器(通常会比渐变收敛速度快得多):

optimizer = tf.train.MomentumOptimizer(learning_rate=learning_rate, momentum=0.9)

 

以上是关于用TensorFlow来实现梯度下降的主要内容,如果未能解决你的问题,请参考以下文章

PyTorch-线性回归_SGD_动量梯度下降

动量Momentum梯度下降算法

面试时如何完整精确的回答动量下降法(Momentum)和Adam下降法的原理

零基础神经网络优化之动量梯度下降

pytorch常用优化器总结(包括warmup介绍及代码实现)

pytorch常用优化器总结(包括warmup介绍及代码实现)