机器学习从入门到放弃:我们究竟是怎么教会机器自主学习的?

发布时间 2023-08-28 23:36:47作者: Blackbinbin

一、前言简介

  我相信你一定听过一个说法,那就是机器学习模型可以被视为函数的一种表示方式。它们通常是由多个函数组成的,这些函数通过参数连接在一起。我们让机器从数据中提取模式、规律和关联,然后使用这些信息来做出预测、分类、聚类等任务。所以从本质上来说,在机器学习中我们其实就是要找一个超级函数,我们已知的数据就是输入的参数,它通过算法和统计方法使计算机能够从大量的数据中学习,通过逼近拟合真实的超级函数,来根据学习到的知识做出决策或执行任务。

  以 classification(分类)任务来说,机器学习就是通过一堆训练集,然后根据 loss function 来查找到最拟合逼近真实函数的求解函数 func(),从而实现分类的输出。

   所以说嘛,机器学习也没有那么难~(bushi,你可以秒懂它。

 

 

二、Logitic Regression(逻辑回归)和 Neuron Network(神经元网络)

  我们还是以上面的分类问题类进行举例,在分类方法中,需要了解逻辑回归的概念。逻辑回归(Logistic Regression)虽然名字中带有"回归"一词,但实际上它是一种用于分类问题的统计学习方法,而不是回归问题。逻辑回归用于预测二分类问题,即将输入数据分为两个类别中的一个。

  逻辑回归通过将线性函数的输出映射到一个介于0和1之间的概率值,来表示输入数据属于某个类别的概率。这个映射使用了逻辑函数(也称为sigmoid函数),它具有S形的曲线,这使得模型的输出在0和1之间变化。逻辑回归的公式如下:

  其中,P(Y=1|X) 是给定输入特征 X 条件下属于类别 1 的概率,beta_0, beta_1, beta_n 是模型的参数,X_1, X_2, X_n 是输入特征。模型的目标是通过调整参数,使得预测的概率尽可能接近实际观测值。在训练过程中,逻辑回归使用最大似然估计等方法来找到最佳的参数值,以使模型的预测结果与实际观测值之间的差异最小化。一旦训练好了逻辑回归模型,它可以用于预测新的数据点所属的类别。

  那这个分类模型函数中怎么求解参数 beta_0, beta_1....beta_n 的呢?这里其实就是模型训练方法的求解,一般来说针对逻辑回归问题都是使用最大似然估计,来进行拟合确定曲线。

  举个?~

  一个箱子里有蓝色和黄色的球,从箱子里取出5个球,然后分别计算篮球和黄球所占的比例是多少?

  很显然,一眼看出,蓝球:黄球=3/2

  但是真实中我们并不知道这个箱子内的球总数是多少,那么我们能否通过有限次的取球动作(训练),去拟合出真实的分类函数呢(模型求参),答案是可以的,那就是使用最大似然估计。

  假设比例是 p,那么每次取出来是篮球的概率就是 p,取出来是黄球的概率就是 1-p。

  取球的结果符合0,1分布,也就是概率函数为:

  对于真是的五次取出的结构,那么就是似然函数:

  对于似然函数,不同的 p 的概率,求解出来的的 L(p) 似然函数肯定是不一样的。在概率分布中是指数分布族时,一般来说其似然函数都是凹函数,所以要最逼近真实的分类函数,那么就要求取最大似然估计的值,也就是两边求对数,然后求导,让导数为0:

  带入 p=3/5 发现刚好导数等于0,那么也就是 p=3/5 就是最逼近真实篮球分布的概率。

  上面的似然求解过程,其实也就是机器学习中咱们最常见的 sigmoid 函数,也叫Logistic函数。先来看看它长什么样子,如下图。

  从上图可以看出,sigmoid函数的形状像一个S,自变量的取值范围是负无穷到正无穷,因变量的取值范围在0到1之间,而且,当自变量大于0时,因变量的值大于0.5,当自变量小于0时,因变量的值小于0.5。在二分类问题中,因变量y的值只能是0或者1,利用sigmoid函数的特征,如果把临界值设置为0.5,则当自变量大于0,因变量的取值范围在0.5和1之间时,让y等于1,相反,当自变量小于0,因变量的取值范围在0和0.5之间时,让y等于0。

  在讲 Neuron Network 之前我想通过一个特殊的数据集来引出为什么机器学习要使用 Neuron Network 来解决模型求解的问题。

  针对输入的两个数据参数,x1 和 x2 我们在坐标系中分别标出这四组数据的坐标,其中 class 标识分类的不同。我们可以看到在坐标系中,我们是无法使用一个直线去划分两个分类的,不管你怎么画分类的直线,你都没办法把蓝色和红色的点分成两边。

  所以应该怎么办呢?依旧在逻辑回归中去解决这个问题,有一种方法是 Feature Transformation,也就是变换你的参数,其实就是变换坐标系,如下,左边的坐标系经过变化就变成右边的样子:

  现在的话逻辑回归可以解决这个问题了,可以找出一条直线来进行分类,

  但是这个是人为的经验调参,不可能每一份数据我们都去观测一遍,然后再设计一个函数去转换坐标系吧?这样一点不人工智能,所以我们在此基础上,又将入参经过许多的前置函数,然后在拼接起来变成变成是可以一条直线进行分类的,那么这个过程就是 Neuron Network(神经元网络)。如下如 x1,x2 经过两个前置函数的计算来进行 transformation ,变成 Z 逻辑回归函数可以直接分类的输入。

  

  所以在神经元网络中,不断的重叠,拼接,只是为了不断的进行 feature transfomation,然后进行最后的分类的求解问题,而每一个 Logtic Regression 函数都称作一个 Neuron。而各种 Neuron 你可以用各种不同的方式连接起来,也就是不同的架构,比如上一篇中的 transformer 就是生成式 AI 使用的比较多的一种架构。

 

 

 三、Fully Connect Feedforward Network

  全连接前馈神经网络(Fully Connected Feedforward Network),也被称为多层感知机(Multilayer Perceptron,MLP),是一种常见的人工神经网络结构。它是深度学习中最基本和常见的神经网络模型之一。

  全连接指的是神经网络中的每一层都与前一层中的每个神经元相连接。在全连接前馈神经网络中,信息从输入层流经一个或多个隐藏层,最终到达输出层,每个隐藏层都包含一些神经元,这些神经元通过权重进行连接,并通过激活函数处理后传递给下一层。其中的每一个的 neuron network 都有一组自己的 weight(权重) 和 bias(偏置),而这两个是根据给出的 train data 训练得来的。

  比如输入 x1=1, x2=-1,那么第一个 neuron network 的输出就是:1*1+(-2*-1)+1 = 4,经过 sigmoid 函数后,输出等于 0.98

   假设每一个的 neuron network 的 weight 和 bias 我们都知道,那么我们就可以计算出最终的output

   所以这一大堆的 neuron 组成的就是一个函数,也就是机器学习中需要找到的 function set

 

   如果我们扩充参数,那么真实的场景下的神经网络如下

  在生成的 outputs 的时候,还记得上面我们提到的最大似然值吗,我们需要去评估这个预测生成的输出和真实的数据之间是否是拟合的。所以在 logtic regresssion 分类的时候使用最大似然值去估计分类的概率,而当函数的输出不是分类,而是多个随机的值的时候也就是 linear regression(线性回归)的时候,一般使用均方差来进行对比评估真实值和预测值。那么在寻找一组 weight 和 bias 来使得 LOSS 最小的情况,这个过程就是 Gradient Descent(梯度下降)

 

 

四、Gradient Descent

  在尝试理解梯度下降的时候,我一直会不太明白梯度的概念。不过我们对导数的概念都比较熟悉,导数就是和我们梯度最为相近的一个东西。一个函数的导数,它是定义一个函数在 x 处的变化量,也就是函数上某个点相切的斜率。因为导数的概念是一维函数,所以它描述的是 x 向左和向右的一个趋势。那么如果是一个三维的图像上,那么导数则是:

   在这个类似马鞍形状的图形上,在某个点上的导数的方向应该怎么定义呢?貌似什么方向上去定义都可以,只要找到一个和图形表面相切的直线就行了。因为导数本身是一个标量,它只反映变化的程度,而具体的方向是哪里呢是人为给定的。比如确定某个方向,那么根据这个方向便可以求出变化率。上面的 z 对 x 和 y 的偏微分就是指的 z 在 x 和 y 方向的变化率。

  而梯度呢,它的概念也很简单,就是所有参数的方向的向量:

  那么在上面类似马鞍的图中,z的梯度就是 (-2x, 2y)。梯度不仅有大小,还有方向的概念,那么在具体的图形中,梯度主要表示了图形的“陡峭程度”,从某种程度来说就是一个函数的变化趋势。在图形的某个点上,梯度的大小表示函数增长的快慢,梯度的方向则是表示函数增长的趋势也就是方向。

  那么怎么根据这个梯度,获取这个 LOSS 函数的极小值解呢?

  参数根据上面的公式来进行更新,也就是更新 weight 和 bias , 带入公式:Weight(t+1) = Weight(t) - a*此参数weight梯度,其中 a 为学习率,使我们自己设定,比如我们可以设定一个比较小的值 0.001。这样每次更新 weight 和 bias 后带入前面的神经网络函数,就能一步一步的找到 LOSS 的最小值,这个过程就是梯度下降。

  以下面函数为例:

  对参数进行更新:

  函数对每个参数的梯度如下:

  如果以一个如下的函数来说明的话,梯度下降算法查找的的过程就是,根据某一个初始的 x0,然后根据梯度,这里梯度因为只有一个参数其实也就是 f(x) 的导数,去更新下一个 x 的值,当导数为0的时候也是就红色点最底部的时候,这个 LOSS 函数得到最小值,也就找到了最优解。

   这里的 learning rate 设置为 0.005,这个参数一般设置一个较小的值,这样才能逐步慢慢的梯度下降到我们需要找到的最优解,否则学习率太大的情况会导致红色的点在极值附近来回震荡。而这个 LOSS 梯度下降算法其实有很多,如下图,最常用的基本是 SGD。而一个模型的训练效果究竟好好,也就在于 LOSS 能不能找到一个全局最小值。而影响此值的也很有很多,比如初始值的选取啊,学习率的设置大小,局部最小值和鞍点的出现等等。

 

 

五、Backpropagation Algorithm(反向传播算法)

  反向传播算法(Backpropagation Algorithm)是一种用于训练人工神经网络的优化算法。它是训练多层神经网络、特别是全连接前馈神经网络(多层感知机)的核心算法之一。反向传播算法通过计算损失函数对网络中每个参数的梯度,然后根据梯度调整参数,以最小化损失函数。

  反向传播算法的基本思想是将误差从输出层向输入层反向传播,逐层计算每个参数对误差的贡献,然后根据这些梯度信息来更新参数。算法的步骤如下:

  1. 前向传播:输入一个样本,通过前向传播计算网络的输出,也就是模型对该样本的预测值。在这个过程中,保留中间层的激活值,以备后面的计算使用。
  2. 计算损失:将网络的输出与实际的标签进行比较,计算损失函数,衡量预测与实际之间的差异。
  3. 反向传播:从输出层开始,计算损失函数关于每个参数的梯度。首先,计算输出层的梯度,然后逐层向后计算中间层的梯度,直到到达输入层。这是一个逐层链式法则的过程。
  4. 更新参数:根据计算得到的梯度信息,使用梯度下降等优化方法来更新每个参数,以减小损失函数。更新参数时,乘以一个学习率来控制每次更新的步幅。
  5. 重复步骤 1~4:针对训练集中的每个样本,重复执行前向传播、计算损失、反向传播和参数更新的过程,直到达到预定的迭代次数或损失收敛。

  如果你看明白了上一个关于梯度下降算法的原来,那么反向传播对你来说就非常好理解了!!

  举个?~

  现在我们构建一个只有一层的神经网络:

  假设每个样本入参都有两个维度的 input,分别是 x1 和 x2,每位维度的取值是:

  而这个样本的真实值是:

  神经网络中所有参数随机初始化:  

  那么根据神经网络的一个输出我们可以计算得到我们的估计值 y' = 2.9

  这一轮的正向传播后我们就可以根据估算值和真实值,计算误差,假设我们这里设置的 LOSS 方程是一个均方差函数:

  反向传播的过程其实就是求导的过程,就是为了求出参数 w1 ~ w6 需要更新的值,以 w5 为例,通过链式法则,对其求导得:

  LOSS 函数在 w5 方向上的梯度就是:

  那么 w5 则更新为:

  

  而对于 w1 的更新则为:

  带入参数后,计算可得 w1 方向的梯度为:

  更新 w1 参数:

  那么经过一轮的正向传播,然后再进行反向传播更新参数后,我们就得到了一组新的参数:

  当第二轮正向传播的时候,我们会发现均方差 LOSS 函数计算的误差会比第一轮的值小了,2.205 -> 1.3478:

   由此我们就完成了一轮参数的更新了

 六、总结

  从上面?的每个知识点里,我们可以从管中窥豹,明白机器学习究竟是怎么做到学习这件事情的。其实掰开了看原理细节,发现也没有那么难,对不对?这篇文章意在帮助大家对神经网络有了一个大概的了解,知道了这个原理之后,后面的学习才能知其所以然。

 

Reference

[1] https://www.bilibili.com/video/BV1QV4y1E7eA/?spm_id_from=333.788&vd_source=122a8013b3ca1b80a99d763a78a2bc50

[2] https://www.bilibili.com/video/BV1Wv411h7kN?p=13&vd_source=122a8013b3ca1b80a99d763a78a2bc50

[3] https://zhuanlan.zhihu.com/p/121750358