zoukankan      html  css  js  c++  java
  • 线性回归

    线性回归

    标签(空格分隔): 深度学习


    我们举一个实际的例子:我们希望根据房屋的面积和房龄来预计房屋价格。为了开发一个能够预测房价的模型,我们需要收集一个真实的数据集。

    1. 该数据集包括:房屋的销售价格,房龄和面积。在机器学习的术语中,该数据集成为训练数据集或训练集,每一行数据被称为样本,也可成为数据点或者数据样本。我们预测的目标(在这个例子中是房屋价格)成为标签或目标。预测所根据的自变量成为特征或者协变量。

    2. 通常我们使用(n)来表示数据集中的样本数量。对搜因为(i)的样本,其输入表示为(X^{(i)}=[x_{1}^{(i)},x_2^{(2)}]^T),其输出对应的标签是(y^{(i)})

    线性模型

    线性假设是指目标可以表示为特征的加权和,如下面的式子:$$price = omega_{area}cdot area+omega_{age}cdot age +b ag1$$
    中的(omega_{area})(omega_{age})称为权重,(b)称为偏置(bias),或称为偏移量(offset)、截距(intercept)。权重决定了每个特征对我们预测值的影响,偏执是指当所有特征都取为0时,预测值应该为多少。即使现实中不会有任何房子的面积是0 或者房龄正好为0年,我们仍然需要偏置项。如果没有偏置项,我们模型表的能力将受到限制。严格的讲(公式(1))*是输入特征的一个仿射变换**。仿射变换的特点就是通过加u去哪和特征进行线性变换,并通过偏置项来进行平移。

    给定一个数据集,我们的目标是寻找模型的权重(W)和偏置(b),使得根据模型做出的预测答题符合数据里的真实价格。输出的预测值由输入特征通过线性模型的仿射变换决定,仿射变换由所选权重和偏置决定。

    • 有些学科往往只关注有少量特征的数据集,在这些学科中,建模时经常想这样通过长形式显示地表达。而在机器学习领域,我们通常使用的是高维数据集,建模时采用线性代数表示法会比较方便。当我们的输入包含(d)个特征时、我们将预测结果(hat{y})(通常使用“尖号”符号表示估计值)表示为:$$hat{y}=omega_1x_1+dots+omega_dx_d+b ag2$$

    将特征向量放到(xinmathbb{R}^d)中,并将所有权重放到(winmathbb{R}^d)中,我们可以用点积形式来简洁的表达模型:$$hat{y}=w^Tx+b ag3$$
    在公式3中,向量(x)对用于单个数据特征的样本。用符号表示的矩阵(Xinmathbb{R}^{x imes{d}})可以很方便的引用我们整个数据集的n个样本。其中,X的每一行是一个样本,每一列是一种特征。
    对于特征集合(X),预测值(hat{y}inmathbb{R}^n)可以通过(矩阵-向量)乘法表示为:(hat{y}=Xw+b ag4)

    损失函数

    在我们开始考虑如何用模型拟合数据之前,我们需要确定一个拟合程度的度量。损失函数能够量化目标的实际值和预测值之间的差距。通常我们回选择非负数作为损失,且数值越小表示损失越小,完美与测试的损失为0,回归问题中最常用的损失函数是平方误差数。当样本(i)的预测值为(hat{y}^i)其对应的真是标签为(y^{(i)})时,平方误差可以定义为以下公式:$$l{(i)}(oldsymbol{w},b)=frac{1}{2}(hat{y}{(i)}-y{i})2 ag5$$
    常数(frac{1}{2})不会带来本质的差别,但这样在形式上稍微简单一些,表现为我们对损失函数求导后常数系数为1. 此处的平方时因为 较大的差异值可以带来更大的损失函数。为了度量模型在整个数据集上的质量,我们需要计算在训练集n个样本上的损失均值。$$L(oldsymbol{w},b)=frac{1}{n}sum_{i=1}nl{(i)}(oldsymbol{w},b)=frac{1}{2n}sum_{i=1}n(wTx{(i)}+b-y{(i)})^2 ag6$$
    在训练模型的时候,我们希望能够寻找一组参数,这组参数可以最小换在所有训练样本上的总损失$$(oldsymbol{w}*,b*)=argmin L(w,b) ag7$$

    解析解

    线性回归刚好是一个很简单的优化问题。线性回归的解可以用一个公式简单的表达出来,这类解叫做解析解(analytical solution)。首先,我们将偏置b合并到参数w中。合并方法是在包含所有参数的矩阵中附加一列。我们预测的问题是最小化(Vert y-XwVert^2 ag8)。在这个损失平面上有一个临界点,这个临界点对应于整个区域的损失最小值。将损失关于(oldsymbol{w})的倒数设为0,得到解析解:(w^*=(X^TX)^{-1}X^Ty ag9)像线性回归这样的解析问题存在解析解,但并不是所有的问题都存在解析解。解析解可以很好的进行数学分析,但解析解的限制很严格,导致它无法应用在深度学习里面。

    小批量随机梯度下降

    即使在我们无法得到解析解的情况下,我们仍然可以有效的训练模型。在许多任务上,那些难以优化的模型效果要更好。因此,弄清楚如何训练这些难以优化的模型是非常重要的。
    本书中我们用到一种名梯度下降(gradient descent)的方法,这种方法几乎可以优化所有深度学习模型。它通过不断的在损失函数的递减的方向更新参数来降低误差。
    梯度下降最简单的用法是计算损失函数(数据集中所有样本的损失均值)关于模型参数的导数(在这里也可以称为梯度)。但是在实际的执行中可能会非常慢:因为在每一次更新参数之前,我们必须便利整个数据集。因此我们通常会在每次需要计算更新的时候随机抽取一批小样本,这种变体叫做小样本随机梯度下降(minibatch stochastic gradient descent)。
    在每次迭代中,我们首先随机抽取一个小批量(eta),它是由固定数量的训练样本组成的。然后,我们计算小批量的平均损失关于模型参数的导数(也称之为梯度)。最后,我们将梯度乘以一个预先确定正数(eta),并从当前参数的值中减掉。

    • 根据权重(omega)和偏置(eta)生成num_example个人造数据。其中x是训练集的数据,y是标签,在标签上加上一点标准差为0.01的噪音,
    true_w = torch.tensor([2, -3.4])
    true_b = 4.2
    features, labels = synthetic_data(true_w, true_b, 1000)
    def synthetic_data(w, b, num_examples):
        x = torch.normal(0, 1, (num_examples, len(w)))
        y = torch.matmul(x, w) + b
        y += torch.normal(0, 0.01, y.shape)
        return x, y.reshape((-1, 1))
    

    生成每批大小为batch_size的数据进行小样本训练,获取总的样本数量,然后将其打乱。返回batch_size大小的特征和标签。

    def data_iter(batch_size, features, labels):
        num_example = len(features)  # 特征数量
        indices = list(range(num_example))
        random.shuffle(indices)  # 洗牌 特征顺序打乱。
        for i in range(0, num_example, batch_size):
            batch_indices = torch.tensor(indices[i:min(i + batch_size, num_example)])
            yield features[batch_indices], labels[batch_indices]
    

    在开始下批量随机梯度下贱优化我们的模型参数之前,我们需要一些参数,在下面的代码当中,我们从均值为0,标准差为0.01的正态分布中随机采样随机数来初始化权重,并将偏置初始化为0.

    w = torch.normal(0, 0.01, size=(2, 1), requires_grad=True)
    b = torch.zeros(1, requires_grad=True)
    

    在初始参数之后,我们的任务是更新这些参数,直到这些参数足够你和我们的数据,每次更新都需要计算损失函数关于模型参数的梯度,有了这个梯度,我们就可以向减小损失的方向更新每个参数。

    • w 预设的均值为0, 标准差为0.01
    • b 预设的初值为0
    • x 有大量(n)的已知数据
    • y 有大量(n)的已知数据

    目标$$L(oldsymbol{w},b)=frac{1}{n}sum_{i=1}nl{(i)}(oldsymbol{w},b)=frac{1}{2n}sum_{i=1}n(wTx{(i)+b}-y{(i)})^2 ag6$$通过改变(oldsymbol{w},b)尽量降低(L).

    定义模型

    def linreg(x,w,b):
        return torch.matmul(x,w)+b
    

    损失函数

    def squared_loss(y_hat, y):
        return (y_hat - y.reshape(y_hat.shape)) ** 2 / 2
    

    优化算法

    介绍小批量随机梯度下降的工作示例。
    在每一步中,使用从数据集中随机抽取的一个小批量,然后根据参数计算损失的梯度。接下来,朝着减少损失的方向更新我们的参数。下面的函数实现小批量随机梯度下降更新。该函数接受模型参数集合,学习速率和批量大小作为输入。每一步的更新大小由学习速率(lr)决定。因为我们计算的损失是一个批量样本的综合,所以我们用批量大小来归一化步长,这样步长大小就不会取决于我们对批量大小的选择。

    def sgd(params,lr,batch_size):
        with torch.no_grad():
            for param in params:
                param -= lr* param.grad/batch_size
                param.grad.zero_()
    

    训练

    在每次迭代中,我们读取一个小批量训练样本,并通过我们的模型来获取一组预测。计算完损失之后,我们开始反向传播,存储每个参数的梯度。最后我们调用sgd来更新模型参数。

    lr = 0.03
    num_epochs = 3
    net = linreg
    loss = squared_loss
    
    for epoch in range(num_epochs):
        for x,y in data_iter(batch_size,features,labels):
            l = loss(net(x,w,b),y)
            l.sum().backward()
            sgd([w,b],lr,batch_size)
        with torch.no_grad():
            train_l = loss(net(features,w,b),labels)
            print(f'epoch {epoch+1},loss{float(train_l.mean()):f}')
    
  • 相关阅读:
    安装go版本
    golang简介
    安装MySQL
    art.dialog.art 中,将子页面窗口中的值传递给父框架中
    Windows7下安装CentOS
    生成uuid
    如何开启win7端口的图文教程
    PHPMailer不能发送邮件
    sql 如果关联表 没有值 设置 默认值
    php array 分页
  • 原文地址:https://www.cnblogs.com/A-FM/p/15076873.html
Copyright © 2011-2022 走看看