栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

tensorflow学习笔记 | 02 - 线性回归问题Numpy实战

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

tensorflow学习笔记 | 02 - 线性回归问题Numpy实战

一、引言

机器学习的目标是希望从已有数据中学习到一些高层次的规律,从而在给定某个新的 x 时,根据机器学习的结果,可以给出一个预测的y。

结果y通常有两种类型:连续型变量和离散型变量,对于连续型变量进行预测则使用回归模型,对于离散型变量进行预测则使用分类模型。

本文中讲述的是一个简单的线性回归问题,就是连续值预测的问题。

连续值预测的问题总结为如下:
f θ : x → y f_{theta}:x{rightarrow}y fθ​:x→y
其中 x x x 是给定的输入数据, θ {theta} θ是模型的参数, y y y是真实的实际结果,我们希望模型给出的预测结果 f ( x ) f(x) f(x)能够完美的逼近于实际结果 y y y,而预测结果与实际结果之间的差值成为误差。

二、一元线性回归 1. 建立模型

二元一次方程如下:
y = w ∗ x + b y=w*x+b y=w∗x+b
在数学世界中,只需要给定该直线上的两个点,我们就能精确的求解出 w 和 b 的值,比如给定(1,1.567)、(2,3.043),运用小学二年级的知识,求解出 w = 1.476,b = 0.091,多么完美。

但现实世界中并非如此精确且完美,我们采集出的数据如下图所示:

对于这堆数据,因为只是一部分数据,所以可以用一次方程建模,二次方程建模,也可以用三次方程建模,这其中最简单的就是用一条直线,也就是二元一次方程建模。并且,无论取哪条直线,都不能完美的覆盖这些点,所以这个时候我们能做的,只是建立一个直线模型,如下图蓝色线:

直线模型建立完成后,在某个给定的x处,实际y值偏离直线上的y值的距离,可以理解为噪声,所以在我们最初的直线模型中加入一个噪声参数 ϵ {epsilon} ϵ,通常这个噪声值符合某种概率分布,在我们可以接受的范围内。:
y = w ∗ x + b + ϵ y=w*x+b+epsilon y=w∗x+b+ϵ
接下来,我们利用给出的足够多的真实点,去计算出 w w w、 b b b、 ϵ epsilon ϵ这三个参数的值,从而找到最接近精确解的那条直线,这就是 machine learning 要做的事情。

2. 参数求解

当我们求解出一条直线后,对于数据中的每个点都计算出误差,再将所有的相加,就可以量化出拟合的直线和实际之间的误差。

构造一个损失函数:
l o s s = Σ i ( w ∗ x i + b − y i ) 2 loss=Sigma_{i}(w*x_{i}+b-y{i})^{2} loss=Σi​(w∗xi​+b−yi)2
损失函数的值越小,说明直线越接近实际值,损失函数的最小值即是最优解。

参数的最优解记为 w ′ w' w′和 b ′ b' b′,求解公式如下:
w ′ = w − l r ∗ l o s s ′ ∣ w w'=w-lr*loss'|_{w} w′=w−lr∗loss′∣w​
b ′ = b − l r ∗ l o s s ′ ∣ b b'=b-lr*loss'|_{b} b′=b−lr∗loss′∣b​

三、基于numpy的实例 step1. 计算loss函数

l o s s = Σ i ( w ∗ x i + b − y i ) 2 = ( w 0 x 0 + b 0 − y 0 ) 2 + ( w 0 x 1 + b 0 − y 1 ) 2 + . . . + ( w 0 x 99 + b 0 − y 99 ) 2 loss=Sigma_{i}(w*x_{i}+b-y{i})^{2}=(w_{0}x_{0}+b_{0}-y_{0})^{2}+(w_{0}x_{1}+b_{0}-y_{1})^{2}+...+(w_{0}x_{99}+b_{0}-y_{99})^{2} loss=Σi​(w∗xi​+b−yi)2=(w0​x0​+b0​−y0​)2+(w0​x1​+b0​−y1​)2+...+(w0​x99​+b0​−y99​)2
w 0 w_{0} w0​和 b 0 b_{0} b0​是随机初始化的,都初始化为0即可:
w 0 = b 0 = 0 w_{0}=b_{0}=0 w0​=b0​=0
随着累加过程,loss的值会变得很大,求平均:
l o s s ˉ = 1 N l o s s bar{loss}=frac{1}{N}loss lossˉ=N1​loss
实现代码如下:

# y = wx + b
def compute_error_for_line_given_points(b, w, points):
    totolError = 0
    for i in range(0, len(points)):
        x = points[i, 0]
        y = points[i, 1]
        # compute mean-squared-error
        totalError += (y - (w * x + b)) ** 2
    # average loss for each point
    return totalError / float(len(points))
step2. 计算梯度并更新

同样的loss函数,将w和b当作自变量求偏导:
l o s s = Σ i ( w ∗ x i + b − y i ) 2 loss=Sigma_{i}(w*x_{i}+b-y{i})^{2} loss=Σi​(w∗xi​+b−yi)2
实现代码如下:

def step_gradient(b_current, w_current, points, learningRate):
    b_gradient = 0
    w_gradient = 0
    N = float(len(points))
    # 对于每一个点计算梯度
    for i in range(0, len(points)):
        x = points[i, 0]
        y = points[i, 1]
        # grad_b = 2(wx+b-y)
        b_gradient += (2/N) * ((w_current * x + b_current) - y)
        # grad_w = 2(wx+b-y)*x
        w_gradient += (2 / N) * x * ((w_current * x + b_current) - y)
    # update w'
    new_b = b_current - (learningRate * b_gradient)
    new_w = w_current - (learningRate * w_gradient)
    return [new_b, new_w]
step3. 将w’赋给w,进行循环

每次将计算出的新w’值,赋给w,重新进行计算,实现代码如下:

def gradient_descent_runner(points, starting_b, starting_w, learning_rate, num_iterations):
    b = starting_b
    w = starting_w
    # update for severval times
    for i in range(num_iterations):
        b, w = step_gradient(b, w, np.array(points), learning_rate)
    return [b, w]
运行程序

data.csv地址:https://github.com/dragen1860/TensorFlow-2.x-Tutorials

if __name__ == '__main__':
    # 加载数据文件
    points = np.genfromtxt("data.csv", delimiter=",")
    learning_rate = 0.0001
    initial_b = 0
    initial_w = 0
    num_iterations = 1000
    print("Starting gradient descent at b = {0}, w = {1}, error = {2}"
          .format(initial_b, initial_w,
                  compute_error_for_line_given_points(initial_b, initial_w, points))
          )
    print("Running...")
    [b, w] = gradient_descent_runner(points, initial_b, initial_w, learning_rate, num_iterations)
    print("After {0} iterations b = {1}, w = {2}, error = {3}".
          format(num_iterations, b, w,
                 compute_error_for_line_given_points(b, w, points))
          )

运行结果如下:

最终得到的b为0.089,w为1.478,与数学精确值 w = 1.476,b = 0.091 相差不大。

参考文章

用人话讲明白线性回归LinearRegression

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/752951.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号