3.线性神经网络

3.线性神经网络

在深入了解深度神经网络之前,我们需要涵盖神经网络训练的基础知识。在本章中,我们将介绍整个训练过程,包括定义简单的神经网络体系结构,处理数据,指定损失函数以及训练模型。为了使事情更容易掌握,我们从最简单的概念开始。幸运的是,经典的统计学习技术(例如线性和逻辑回归)可以转换为浅层神经网络。从这些经典算法开始,我们将向您介绍基础知识,为更复杂的技术(例如softmax回归(在本章末介绍)和多层感知器(在下一章介绍))提供基础。

3.1。线性回归

在Colab中打开笔记本

回归是指用于建模数据点之间关系的一组方法 xx 和相应的实值目标 yy。在自然科学和社会科学中,回归的目的通常是表征投入和产出之间的关系。另一方面,机器学习最常与预测有关。

每当我们要预测数值时,都会出现回归问题。常见的例子包括预测(房屋,股票等的)价格,预测住院时间(针对医院的患者),需求预测(针对零售),等等。并非每个预测问题都是经典的回归问题。在接下来的部分中,我们将介绍分类问题,目标是预测一组类别中的成员资格。

3.1.1。线性回归的基本要素

在回归标准工具中,线性回归可能是最简单且最受欢迎的方法。线性回归的历史可以追溯到19世纪初,它来自一些简单的假设。首先,我们假设特征之间的关系 xx 和目标 yy 是线性的,即 yy 可以表示为输入xx的加权总和 ,在观察结果上加上或吸收一些噪音。其次,我们假设任何噪声都表现良好(遵循高斯分布)。为了激发这种方法,让我们从一个实际的例子开始。假设我们希望根据房屋面积(平方英尺)和年龄(岁数)估算房屋价格(美元)。

为了实际拟合用于预测房价的模型,我们需要动手研究一个由销售组成的数据集,我们知道每个房屋的销售价格,面积和年龄。在机器学习的术语中,数据集称为训练数据集训练集,每行(此处对应于一次销售的数据)称为 示例(或数据实例,“数据点”,样本)。我们试图预测的事物(此处为价格)称为标签(或目标)。预测所基于的变量(此处为年龄面积)称为特征协变量

通常,我们将使用 n表示我们数据集中的示例数量。我们通过以下方式索引数据实例i,将每个输入表示为 x(i)=[x(i)1,x(i)2]以及对应的标签为 y(i).

3.1.1.1。线性模型

线性假设仅表示目标(价格)可以表示为特征(区域和年龄)的加权总和:

price=warea⋅area+wage⋅age+b.(3.1.1)
这里,  warea 和  wage被称为  权重,并 b称为 偏差(也称为 偏移或  拦截)。权重确定每个功能部件对我们的预测的影响,偏差仅表示所有功能部件都具有价值时预测价格应具有的价值 0。即使我们永远不会看到任何面积为零或刚好为零岁的房屋,我们仍然需要截距,否则我们将限制线性模型的表示性。
 
给定数据集,我们的目标是选择权重  ww 和偏差  bb 因此,平均而言,根据我们的模型做出的预测最适合数据中观察到的真实价格。

在通常只关注具有少量功能的数据集的学科中,像这样以长格式显式表达模型是常见的。在ML中,我们通常使用高维数据集,因此使用线性代数符号更方便。当我们的输入包括 dd 特征,我们表达了我们的预测 y^y^ 如

^y = w1 x1 + ::: + wd xd + b (3.1.2)

将所有特征收集到向量中 xx 和所有的权重成一个向量 ww,我们可以使用点积紧凑地表达我们的模型:

在此,向量x对应于单个数据点。 我们经常会发现通过设计矩阵X引用整个数据集很方便。其中,X每个示例包含一行和每个特征包含一列。

收集数据点 X,预测 y^ 可以通过矩阵向量乘积表示:

给定训练数据集 XX 和相应的(已知)目标 yy,线性回归的目标是找到 权重向量ww 和偏差项 bb, 这些给定新的数据点xi,该新点从与训练数据相同的分布采样将预测目标yi 最低错误。

即使我们认为在给定x的情况下预测y的最佳模型是线性的,我们也不会期望找到在所有点(x; y)上yi均等于w⊤x+ b的真实数据。例如,我们用来观察特征X和标记y的任何仪器都可能遭受少量的测量误差。因此,即使我们确信基本关系是线性的,我们也将合并噪声项以解决此类错误。

在寻找最佳参数之前 ww 和 bb,我们还需要两件事:(i)某种给定模型的性质度量;(ii)更新模型以改善其性质的程序。

3.1.1.2。损失函数

在开始考虑如何拟合模型之前,我们需要确定适合度。损失函数可量化目标的实际值与预测值之间的距离。损失通常是一个非负数,其中较小的值更好,完美的预测会导致损失00。回归问题中最流行的损失函数是平方误差之和。当我们以预测为例ii 是 y^(i)y^(i) 相应的真实标签是 y(i)y(i),平方误差由下式给出:

常数1/2并没有什么实际的区别,但是会证明从符号上讲是很方便的,在我们取损失的导数时可以抵消。由于训练数据集已提供给我们,因此不受我们的控制,因此经验误差仅是模型参数的函数。为了使事情更具体,请考虑以下示例,在该示例中我们为一维情况绘制了一个回归问题,如图所示 。

注意,由于二次依赖性,估计值^y(i)与观测值y(i)之间的较大差异导致对损失的更大贡献。

为了衡量整个数据集上模型的质量,我们只需对训练集上的损失进行平均(或等效地求和)。

训练模型时,我们要查找参数(w∗,b∗w∗,b∗),从而将所有培训示例中的总损失降至最低:

3.1.1.3。解析解

线性回归恰好是一个异常简单的优化问题。与本书中将要遇到的大多数其他模型不同,可以通过应用一个简单的公式来解析线性回归,从而得出全局最优值。首先,首先,我们可以通过将列添加到由全1组成的设计矩阵中,将偏差b包含在参数w中。那么我们的预测问题是将||y−Xw||。因为此表达式具有二次形式,所以它是凸的,并且只要问题不退化(我们的特征是线性独立的),它就是严格凸的。

因此,损失面上只有一个临界点,它对应于全局最小值。取有关的损失的导数ww 并将其设置为等于 00 得出解析解:

尽管诸如线性回归之类的简单问题可以接受解析解,但您不应该习惯这种好运。尽管解析解决方案允许进行很好的数学分析,但解析解决方案的要求是如此严格,以至于它将排除所有深度学习。

3.1.1.4。梯度下降

即使在无法解析地求解模型的情况下,甚至在损失曲面是高维且非凸的情况下,事实证明我们仍然可以在实践中有效地训练模型。而且,对于许多任务来说,这些难以优化的模型要好得多,以至于弄清楚如何训练它们最终值得承担麻烦。

梯度下降的最原始应用是取真实损失的导数,该损失是对数据集中每个示例计算的损失的平均值。实际上,这可能非常慢。在进行单个更新之前,我们必须传递整个数据集。因此,每次我们需要计算更新时,我们通常都会决定对样本的随机小批量进行抽样,这是一种称为随机梯度下降的变体。

在每次迭代中,我们首先随机采样一个小批量 BB由固定数量的培训示例组成。然后,我们根据模型参数计算最小批次的平均损失的导数(梯度)。最后,我们将梯度乘以预定步长η>0η>0 并从当前参数值中减去结果项。

我们可以用以下数学方式表示更新(∂∂ 表示偏导数)

总而言之,该算法的步骤如下:(i)我们通常随机地初始化模型参数的值;(ii)我们反复从数据中多次抽样随机批次,并沿负梯度方向更新参数。

对于二次损失和线性函数,我们可以如下明确地写出:注意 ww 和 xx是向量。比起用系数表达事物,更优雅的向量符号使数学更易读。w1,w2,…,wdw1,w2,…,wd.

在上式中  |B|代表每个小批量中的样本个数(批量⼤小,batch size),η称作学习率(learning rate)并取正数。需要强调的是,这⾥的批量⼤小和学习率的值是⼈为设定的,并不是通过模型 训练学出的,因此叫作超参数(hyperparameter)。超参数调整是选择这些参数的过程,通常需要我们根据内部(训练)循环的结果调整超参数,而内部(训练)循环的结果是根据数据的单独验证拆分评估 的。 我们通常所说的“调参”指的正是调节超参 数,例如通过反复试错来找到超参数合适的值。在少数情况下,超参数也可以通过模型训练学出。
在训练了预定的迭代次数(或直到满足其他一些停止标准)之后,我们记录估计的模型参数,表示为 w^,b^w^,b^(通常,“帽子”符号表示估算值)。请注意,即使我们的函数确实是线性且无噪声的,这些参数也不会成为损耗的最小化极小值,因为尽管算法朝着局部最小值缓慢收敛,但它无法在有限的步骤中精确实现。

线性回归恰好是一个凸学习问题,因此只有一个(全局)最小值。但是,对于更复杂的模型(如深层网络),损耗面包含许多最小值。幸运的是,由于尚未完全理解的原因,深度学习从业人员很少会努力寻找能够将训练数据损失最小化的参数。更加艰巨的任务是找到参数,这些参数将在我们之前从未见过的数据上实现低损失,这是一种称为泛化的挑战。。

3.1.1.5。制作与学习的模型预测

给定学习的线性回归模型 w^⊤x+b^w^⊤x+b^,我们现在可以根据给定的面积来估算新房的价格(培训数据中未包含) x1x1 和年龄(年) x2x2。估计具有特定特征的目标通常称为预测推断

3.1.1.6。速度矢量化

在训练模型时,我们通常希望同时处理整个示例的小批处理。有效地做到这一点需要我们对计算进行向量化并利用快速的线性代数库,而不是在Python中编写昂贵的for循环。

为了说明为什么如此重要,我们可以考虑两种添加向量的方法。首先,我们实例化两个1000010000包含所有向量的三维向量。在一种方法中,我们将使用Python for循环遍历向量。在另一种方法中,我们将依赖于的单个调用np

%matplotlib inline
import d2l
import math
from mxnet import np
import time

n = 10000
a = np.ones(n)
b = np.ones(n)

由于我们会在本书中频繁地对运行时间进行基准测试,因此让我们定义一个计时器(此后可通过d2l软件包进行访问以跟踪运行时间。

# Saved in the d2l package for later use
class Timer:
    """Record multiple running times."""
    def __init__(self):
        self.times = []
        self.start()

    def start(self):
        # Start the timer
        self.tik = time.time()

    def stop(self):
        # Stop the timer and record the time in a list
        self.times.append(time.time() - self.tik)
        return self.times[-1]

    def avg(self):
        # Return the average time
        return sum(self.times) / len(self.times)

    def sum(self):
        # Return the sum of time
        return sum(self.times)

    def cumsum(self):
        # Return the accumulated times
        return np.array(self.times).cumsum().tolist()

现在我们可以对工作负载进行基准测试。首先,我们使用for循环添加它们,一次添加一个坐标。

c = np.zeros(n)
timer = Timer()
for i in range(n):
    c[i] = a[i] + b[i]
'%.5f sec' % timer.stop()

'4.08728 sec'

另外,我们依靠np计算元素和:

timer.start()
d = a + b
'%.5f sec' % timer.stop()
'0.00022 sec'

已经注意到,第二种方法比第一种方法快得多。向量化代码通常会产生数量级的加速。此外,我们将更多的数学运算推到了库中,不需要自己编写太多的计算,从而减少了出错的可能性。

3.1.2。正态分布和平方损耗

改变平均值对应于沿x轴的偏移,增大方差会分散分布,从而降低其峰值

 

3.1.3.1。神经网络图

我们将线性模型描述为神经网络。请注意,这些图显示了连通性模式(此处,每个输入都连接到输出),而不是权重或偏差所取的值。、

由于图形中只有一个计算的神经元(节点)(输入值未计算,而是给定的),我们可以将线性模型视为仅由一个人工神经元组成的神经网络。由于对于此模型,每个输入都连接到每个输出(在这种情况下,只有一个输出!),因此我们可以将此转换视为 完全连接的层,也通常称为密集层

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值