机器学习与TensorFlow编程(1)线性回归模型

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/irving512/article/details/72628416

0. 参考资料


1. 总体介绍

1.1. 回归(Regression)

如果需要预测的值是连续值(如价格),则称此类学习任务为“回归”(Regression)。

1.2. 线性模型(Linear Model):

  • 概念:试图学得一个通过属性的线性组合来进行预测的函数。
  • 基本结构,其中  x1xn 为输入属性, θ0θn  为需要计算的参数:
    h(x)=θ1x1+θ2x2+...+θnxn+b
  • 为了方便编程,将  b  转换为  θ0  ,并定义  x0=1 ,则有以下公式:
    hθ(x)=θ0x0+θ1x1+θ2x2+...+θnxn
  • 矩阵形式:
    X=x0x1xnθ=θ0θ1θnhθ(x)=θTX

2. 损失函数(Loss Function)

2.1. 概念

用来估计预期结果  hθ(x)  真实值  y  之间的不一致程度。

2.2. 平方损失函数

在实际应用中,常用均方差作为损失函数(假设一共有m个样本,其中分母中添加2是为了计算方便):

J(θ)=12mi=1m(hθ(x(i))  y(i))2

2.3. 作用

如前所述,损失函数用于估计预测结果真实值之间的偏差。为了优化模型,必须调整参数 θ ,使损失函数 J(θ) 取值最小。


3. 梯度下降算法(Gradient descent)

3.1. 概念

  • 梯度下降(Gradient Descent),又名最速下降法,是最优化算法(Optimization Arithmetic)中的一种。
  • 优化算法的目标是取最优值。
  • 线性回归中,梯度下降的目标是:取  θ0θn  的最优值,令  J(θ)  取值最小。

3.2. 原理

  • 利用偏导数计算损失函数的梯度,利用负梯度方向作为搜索方向,接近目标值。
  • 若损失函数为凸函数,利用该方法可以获取全局最优解。
  • 若损失函数是一般函数,根据初始位置不同,可能会计算得到不同的局部最优解(不一定是全局最优解)。

3.3. 计算方法

  • 一般形式如下:
    θi:=θiαθiJ(θ)
  • 对于平方损失函数如下:
    θi := θiα1mj=1m(hθ(x(j))y(j))x(j)i

3.4. 学习率(Learning Rate)

  • 控制每一次梯度下降,修改的  θ  值。
  • 技巧:
    • 画出损失函数  J(θ)  与迭代次数之间的图像。
    • 当学习率过大时,可能不会收敛。
    • 当学习速率过低,收敛速度太慢。
    • 合适的学习率:损失函数随着时间变化逐渐降低,且下降速度不慢。

3.5. 特征标准化(Feature Normalization)

  • 概念:标准化数据特征范围(即不同输入数据都在同一数量级上)。
  • 使用特征标准化的原因:如果一个特征的范围更大,则该特征对于损失函数的影响也更大。为了使所有特征对于损失函数的影响都差不多,则应该使用特征缩放。
  • 常用特征标准化方法:
    • 特征缩放(feature scaling),将数据的特征缩放到[0,1]之间:
      x=xmin(x)max(x)min(x)
    • 均值标准化(mean normalization),其中  μ  为均值,  σ  为标准差:
      x=xμσ

4. 编程实现

4.1. 原始数据

  • 数据源:Coursra ML Week2编程作业提供的数据。
  • 输入特征与结果矩阵,每一行代表一个样本以及对应结果:
    [Xy]=(x(1))Ty(1)(x(2))Ty(2)(x(m))Ty(m)
  • 其中每个样本(不包括  x(i)0 )有
    x(i)=x(i)1x(i)2x(i)n

4.2. 数据预处理

  • 获取特征矩阵(m*(n+1)维矩阵)与结果矩阵(m*1维矩阵)

    X=(x(1))T(x(2))T(x(m))Ty=y(1)y(2)y(m)

  • 其中,每个样本(包括  x(i)0=1 (n+1)*1维矩阵)为

    x(i)=x(i)0x(i)1x(i)n

  • 特征标准化

4.3. 计算损失函数值与梯度下降值(optional)

  • 如果使用TensorFlow实现,有库函数可以调用。
  • 为了加强记忆,理解具体实现,自己推导出以下公式。
    • 损失函数 J为实数。
      J=12m(Xθy)T(Xθy)
    • 参数变化量gradn+1维向量,表示  θi  的变化量。
      grad=XT(Xθy)

5. TensorFlow实现

5.1. TensorFlow代码

import tensorflow as tf
import numpy as np


def read_data(file_name, delimiter=','):
    return np.loadtxt(file_name, delimiter=delimiter)


# 将4.1节原始数据,转换为4.2节中数据
def init_data(input_data):
    input_x = input_data[:, 0:-1]
    input_y = input_data[:, -1].reshape(m, 1)
    input_x = np.column_stack((np.ones(input_data.shape[0]), input_x)).reshape(m, n)
    return input_x, input_y


# 对应3.5节中,均值标准化
def feature_normalization(input_x):
    for i in range(1, input_x.shape[1]):
        mn = np.mean(input_x[:, i], dtype=np.float64)
        std = np.std(input_x[:, i], ddof=1, dtype=np.float64)
        input_x[:, i] = (input_x[:, i] - mn)/std
    return input_x


# 实现线性回归模型
def tensor_flow_run(input_x, input_y):
    # 初始化placeholder,后续将特征矩阵与结果向量导入
    X = tf.placeholder("float64")
    Y = tf.placeholder("float64")

    # 初始化theta
    theta = tf.Variable(tf.zeros([n, 1], dtype=tf.float64))

    # 构建cost函数,即2.2节公式
    cost = tf.reduce_sum(tf.square(tf.matmul(X, theta) - Y)) / 2 / m

    # 初始化梯度下降算法的学习率与策略
    train_op = tf.train.GradientDescentOptimizer(LEARNING_RATE).minimize(cost)

    with tf.Session() as sess:
        # 初始化所有参数
        init = tf.global_variables_initializer()
        sess.run(init)

        # 进行梯度下降
        for i in range(ITERATIONS):
            # 导入特征矩阵与结果向量,进行一次梯度下降计算
            # 调用TensorFlow库函数,实现4.3节内容
            sess.run(train_op, feed_dict={X: input_x, Y: input_y})

        # 输出最终theta参数
        print(sess.run(theta))


# 初始化学习率与迭代次数
LEARNING_RATE = 0.01
ITERATIONS = 1000

# 输入数据
data = read_data('ex1data1.txt', ',')

# 计算参数数量以及样本数量
m = data.shape[0]
n = data.shape[1]

# 对输入数据进行处理
datas = init_data(data)

x = datas[0]
y = datas[1]
# 特征标准化(均值标准化)
x = feature_normalization(x)

# 使用TensorFlow实现线性回归模型的梯度下降
tensor_flow_run(x, y)

5.2. 运行结果

  • 数据源介绍:Coursera Machine Learning中,第二周课程数据。
  • 测试1:
    • 输入数据:学习率0.01,梯度下降1000次,输入文件为ex1data1.txt
    • 输出(官方结果):[-3.6303 1.1664]
  • 测试2:
    • 学习数据:学习率0.001,梯度下降400次,输入文件ex1data2.txt
    • 输出(非官方结果):[112272.892901 33056.237507 14493.332476]

猜你喜欢

转载自blog.csdn.net/irving512/article/details/72628416
今日推荐