3.5 梯度下降模型实例
实例1:使用Python实现线性回归梯度下降模型
在3.3节中我们使用最小二乘法完成了一元线性回归的参数求解过程,本节的第一个例子就使用Python完成梯度下降算法对3.3节数据集合对应的一元线性回归模型进行求解。代码如下:
import numpy as np from numpy import dot from numpy import mat #y=2x X = mat([1,2,3]).reshape(3, 1) Y = 2*X theta = 1. alpha = 0.1 for i in range(100): theta = theta + np.sum(alpha * (Y- dot(X, theta))*X.reshape(1,3))/3. print(theta)
数据准备部分与3.3节完全相同,在这里就不赘述了。接下来的代码是模型参数的初始化,我们人为设定起始参数为1.0,也可以使用随机算法生成随机参数。另外,我们还需要指定学习速率,在本例中使用0.1。
theta = 1
alpha = 0.1
然后指定梯度下降的学习速率,学习速率在这里指定为0.1。一般来说,梯度下降学习速率太快(α过大)容易导致算法无法收敛,梯度下降学习速率太慢(α过小)容易造成计算资源的浪费和模型运行时间过长。
for i in range(100): theta = theta + np.sum(alpha * (Y- dot(X, theta))*X.reshape(1,3))/3.
接下来的代码进行参数更新,即梯度下降的实际运行过程通过NumPy矩阵运算,我们很容易就可以完成更新量的计算,通过循环更新参数集合100次。整个过程比较清晰,但是有一点需要特别注意,如果是多元线性回归模型,就需要在一次计算中同步更新参数矩阵的所有要素。
例如下面的三元线性回归模型中,每次循环中需要对参数矩阵的4个要素同时进行更新。
for i in range(10000): temp[0] = theta[0] + alpha*np.sum((Y-dot(X, theta))*X0)/150. temp[1] = theta[1] + alpha*np.sum((Y-dot(X, theta))*X1)/150. temp[2] = theta[2] + alpha*np.sum((Y-dot(X, theta))*X2)/150. temp[3] = theta[3] + alpha*np.sum((Y-dot(X, theta))*X3)/150. theta = temp
实例2:使用TensorFlow框架实现线性回归梯度下降模型
本例介绍使用TensoFlow进行线性回归的过程。
import tensorflow as tf x = tf.constant([[1], [2], [3], [4]], dtype=tf.float32) y_true = tf.constant([[0], [-1], [-2], [-3]], dtype=tf.float32) linear_model = tf.layers.Dense(units=1) y_pred = linear_model(x) loss = tf.losses.mean_squared_error(labels=y_true, predictions=y_pred) optimizer = tf.train.GradientDescentOptimizer(0.01) train = optimizer.minimize(loss) init = tf.global_variables_initializer() sess = tf.Session() sess.run(init) for i in range(100): _, loss_value = sess.run((train, loss)) print(loss_value) print(sess.run(y_pred))
虽然使用TensorFlow看起来代码量比使用Python的NumPy框架进行数学运算时多不少,但是本实例代码完美地体现了TensorFlow的设计思想,具有平滑的学习曲线这样一个内在优势。因此,线性回归过程完成机器学习代数化向语义的进化,这样一套代码完全遵守TensorFlow机器学习的标准流程(模型构建、模型初始化、模型训练),而且将复杂的数学表达式封装成了mean_squared_error等方法,也使初级开发者更加容易掌握,而高级开发者可以聚焦模型构建本身。
首先是框架的引入和数据的准备,为了能够聚焦到线性回归模型本身,我们依然使用非常简单的数据集合,使用TensorFlow中的常量来直接存储。
x = tf.constant([[1], [2], [3], [4]], dtype=tf.float32) y_true = tf.constant([[0], [-1], [-2], [-3]], dtype=tf.float32)
接下来的部分是模型的构建过程,也是我们要重点讲解的内容。
linear_model = tf.layers.Dense(units=1)
此处建立一个一元线性模型,units=1表示输入一个参数。这里我们使用了TensorFlow自己的层模型,也可以用Keras模块中的层模型进行替换。
y_pred = linear_model(x) loss = tf.losses.mean_squared_error(labels=y_true, predictions=y_pred) optimizer = tf.train.GradientDescentOptimizer(0.01) train = optimizer.minimize(loss)
通过mean_squared_error告知了TensorFlow在框架运行时计算预测值和标签值的偏差平方和,并以最小化这个值作为训练目的(optimizer.minimize(loss))。
init = tf.global_variables_initializer() sess = tf.Session() sess.run(init) for i in range(100): _, loss_value = sess.run((train, loss)) print(loss_value) print(sess.run(y_pred))
上面的代码是训练过程的详细实现,我们惊喜地发现,训练过程(包含参数初始化)和第2章例子的流程完全一致,因此在学习过程中只要聚焦于模型构建本身就可以了。