一、回归

        回归的核心思想,就是“找规律,做预测”。
        我们通过分析一些已知的数据,找到一个“公式”或“规律”,然后用这个规律来预测未知的情况。

二、线性回归

        2.1书上的定义:

        首先,假设自变量x和因变量y之间的关系是线性的, 即y可以表示为x中元素的加权和,这里通常允许包含观测值的一些噪声; 其次,我们假设任何噪声都比较正常,如噪声遵循正态分布。

        2.2一个简单的例子

       定义是抽象的,书上的一个经典的例子:预测房价,我在这里简化一下。

        我们想预测一套房子的售价。直觉上我们知道,房价和很多因素有关,比如房子的大小。这里:

        因变量(输出):就是我们想预测的东西——房价。
        自变量(输入):就是我们觉得会影响房价的因素——房屋面积。

        第一步:收集数据
        我们调查了市场上10套已售出的房子,记录下每套房子的面积和售价。我们可以把这些数据点画在一张图上(初中的平面直角坐标系)。

        第二步:找规律(建模)
        现在,我们要在这些看似杂乱的点中间,找到一条“最合适”的直线(或曲线),来代表面积和房价的整体关系。这条线就叫做 “回归线”(一元一次方程)。

        这个过程就是“回归”,也就是你提到的“为一元和因变量之间关系建模”。

         第三步:做预测
        现在,我们有了一个“规律”(那条蓝色的线)。如果有一套新房子,面积是120平方米,但我们不知道它的价格。我们就可以在横轴上找到120,向上画一条线,碰到蓝色回归线后,再向左画一条线,找到纵轴上对应的价格,比如250万。这个250万就是我们的预测值。

        2.3线性模型

        现实中的问题不可能像是我刚才举的例子那么简单,房价不会只受面积这一种特征影响。还有可能受房龄等因素影响。

        房屋价格可以表示为特征面积和房龄的加权和,如下面的式子:
        price = w1*area + w2*age + b

        w1和w2代表权重,权重代表这个特征值对预测值的影响。

        b代表偏置,可以理解为方程的截距。如果没有b的话,那么线性方程是过原点的一条直线,可能就找不到最合适的那条曲线。书上的原话是:我们模型的表达能力将受到限制。

        上面的二元一次方程,我们在这里把它换一个名字仿射变换。 它的特点是通过加权和对特征进行线性变换, 并通过偏置项来进行平移。

        2.4仿射变换

        我们把上面的价格仿射变换进行抽象,写成更为一般的形式。把特征值变多,就可以得到:
        y = w1*x1 + w2*x2 + ... + wd*xd + b

        我们学过了线性代数,知道了向量乘法,那么就可对上面的式子再进行优化。把所有的权重放在向量w中,把所有的特征放在向量x中。就可以得到更为优美简洁的式子:
        y = w^T x + b

        向量x对应于单个数据样本的特征,引入n个样本该怎么办?
        用矩阵:
        y = Xw + b

        2.5确定模型

        回归的最终目的是作预测,这也是深度学习的目的。我们已经学会了仿射变换,知道该如何预测,接下来要做的就是让这个预测变得最准确。
        我们知道,输出的预测值由输入特征通过线性模型的仿射变换决定,仿射变换由所选权重和偏置确定。
        所以如何确定我们最终的预测模型,也就是找到最适合的权重w和偏置b。好让我们在输入特征值后,得到最准确的输出结果。这个过程可以称之为优化。
        可我们该怎么找w和b呢?

        为此,我们需要两个条件:(1)一种模型质量的度量方式; (2)一种能够更新模型以提高模型预测质量的方法。

        2.5.1损失函数

        在我们开始考虑如何用模型拟合(fit)数据之前,我们需要确定一个拟合程度的度量。 损失函数(loss function)能够量化目标的实际值与预测值之间的差距。 

        什么是损失函数?就是(预测值 - 实际值)的平方 *1/2。还记得我们小学就学过的方差吗?
        平方的意义:(1)可以消除正负的讨论,这一点用绝对值也一样。(2)可以扩大损失的程度。
        乘1/2的话,是为了在将来求导的时候,让系数变成1。

         为了度量模型在整个数据集上的质量,我们需计算在训练集n个样本上的损失均值(也等价于求和)。

        如果存在w和b,使得损失均值达到最小,那么这个w和b就是我们确定模型所需要的参数。

        2.5.2解析解

        解析解可以理解为数学上的最优解。线性回归的优化很简单,可以用一个公式表达出来。

        但是其他模型的最优解很难用一个公式表达出来,而且大多数问题或许根本没有解析解。

        所以解析解可以进行很好的数学分析,但解析解对问题的限制很严格,导致它无法广泛应用在深度学习里。

        那么,在没有解析解的情况下,我们该如何确定模型呢?

        2.5.3随即梯度下降

        这种方法几乎可以优化所有深度学习模型。 它通过不断地在损失函数递减的方向上更新参数来降低误差。

        梯度:就是平均损失关于参数模型的导数。
        我们知道,一个开口向上的抛物线函数该如何寻找最小值,那就是找导数为零的点。
        模型的函数可以类比来看。我们将梯度乘以一个预先确定的正数\eta,并从当前参数的值中减掉。逐步让梯度趋近于零。这就是梯度下降。

        而正数\eta则被我们称之为学习率,这是一个超参数,它不在训练中更新。这个值不宜过大,否则可能会越过最小值。也不宜过小,因为学习的成本很高。

        而因为在每一次更新参数之前,我们必须遍历整个数据集,为了减少时间成本。 因此,我们通常会在每次需要计算更新的时候随机抽取一小批样本, 这种变体叫做小批量随机梯度下降)。

        在弄明白随机梯度下降的原理之后,我们就可以得到确定模型的步骤:
        (1)初始化模型参数的值,如随机初始化; (2)从数据集中随机抽取小批量样本且在负梯度的方向上更新参数,并不断迭代这一步骤。

三、矢量化加速

        矢量化加速,就是把“一个一个地处理”变成“一批一批地处理”,从而极大提高计算速度。

        矢量化加速的意义:大大缩短了处理数据的计算速度。要知道,深度学习的数据,是数以十亿计的,如果用循环算法,那需要的时间是难以估量的。

        书上的代码没什么好说的,我举一个生动的例子。

        超市购物:假设你需要买苹果、香蕉、橘子三种水果。

方法一:循环(低效,未矢量化)

这就像你采用最原始的方法:

  1. 走进超市。

  2. 找到苹果,拿去收银台,排队,付款。

  3. 走出超市,回家放下苹果。

  4. 再次走进超市。

  5. 找到香蕉,拿去收银台,排队,付款。

  6. 走出超市,回家放下香蕉。

  7. 再次走进超市。

  8. 找到橘子,拿去收银台,排队,付款。

  9. 走出超市,回家放下橘子。

        发现了问题吗? 你为了三样东西,重复了三次最耗时的“进出超市、排队付款”的过程。效率极低!

        在编程中,这就像一个 for 循环:

# 伪代码示例:逐个元素相加
list_a = [1, 2, 3]
list_b = [4, 5, 6]
result = []

for i in range(3):
    sum_i = list_a[i] + list_b[i] # 一次只做一个加法
    result.append(sum_i)

# 结果: [5, 7, 9]

        计算机的CPU每次只执行一个加法指令,然后准备下一个,再执行... 这中间有很多准备和调度的开销。

方法二:矢量化(高效)

现在,你换一种聪明的方法:

  1. 推一个购物车走进超市。

  2. 找到苹果,放进购物车。

  3. 找到香蕉,放进购物车。

  4. 找到橘子,放进购物车。

  5. 推着装满商品的购物车,一次性地到收银台,排队,付款。

  6. 一次性地把全部商品带回家。

        效率大大提升! 你把三次耗时的“结算流程”合并成了一次。

        在编程中,这就对应着矢量操作:

# 伪代码示例:矢量相加
import numpy as np

array_a = np.array([1, 2, 3])  # 这是一个“向量”(一维数组)
array_b = np.array([4, 5, 6])

result = array_a + array_b  # 一次完成所有加法

# 结果: [5, 7, 9]

        所以,当你写 A + B 而不是用循环去加时,你不仅仅是让代码更简洁,你实际上是启动了一个高效的“批量处理流水线”,速度可能提升几十甚至上百倍!

四、正态分布与平方损失与似然

        4.1正态分布

        正常状态的分布。

        如果你统计了世界上所有成年人的身高,并把其以柱状图的方式汇集在一张图上,你会发现一个规律。在1.4~1.9米的人,占据了绝大部分。越是远离这个区间的人数越少,低于0.5米和超过4米的成年人甚至没有。

        而如果人数来到无限,你会得到一条光滑的、钟形的曲线。这条曲线,就是正态分布曲线。

        特点:
        钟形曲线:中间高,两边低,左右对称。
        集中趋势:有一个峰值,这个峰值对应的位置叫做均值,代表了数据的“中心”或“平均水平
        离散程度:曲线的“胖瘦”由标准差决定。标准差大,曲线就胖、就矮,说明数据很分散(测量误差大);标准差小,曲线就瘦、就高,说明数据很集中(测量很精准)。

        在自然界和社会中,无数现象都近似服从正态分布。

        4.2平方损失

        衡量“错误”的直尺。

        深度学习的本质,是做一个预测概率模型。既然要预测,那么就要有一个度,来衡量被预测出来的结果和真实的结果之间的差距。

        最直接的想法:abs(真实值-预测值)叫做绝对损失,abs()是绝对值函数。

        平方损失的想法:(真实值-预测值)的平方叫做平方损失。

        至于为什么要平方,在前一节的损失函数说过,这里再说一遍。
        (1)放大大的误差(2)平方函数是光滑的、可导的(3)与正态分布紧密相连

        总而言之,在机器学习中,平方损失就是所有数据点的预测值与真实值之差的平方的平均值。我们的目标就是找到一组模型参数,让这个“平方损失”的值最小。

        4.3似然

        衡量模型“靠谱”程度的尺子。

        根据已经确定的结果,观测产生这种结果的可能环境,或者是环境中的某些参数。 它衡量的是模型的“解释能力”。

        假设我们有一个抛硬币的模型,假设这个硬币有参数,P(正面向上) = \theta。
        \theta是存在的,但是我们不知道它是多少。
        现在在做出了10次实验之后,得出的结果是7次正面,3次反面。
        那么似然的目的就是在求\theta等于多少。

        最大似然估计,就是要求当\theta等于等于多少的时候,发生7次正面向上的概率最大。
        显然,上面的例子钟,当\theta=7时,发生的概率最大。

根据书上的推导:

        当我们使用平方损失函数来训练一个线性回归模型时,我们实际上是在做一个隐含的假设:预测误差是服从正态分布的。并且,最小化平方损失,等价于对模型参数进行最大似然估计。

        推导的过程其实不重要,只要记住这个结论就行了。


        

       

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐