机器学习基础
机器学习基础
前言
因为本人之前选修的是机器学习方向,所以上过「机器学习」「数据挖掘」「计算机视觉」等课程。学习「机器学习」的时候比较认真,还是知道一些模型的,但是学「计算机视觉」的时候没有怎么听,而且这门课又是主要讲cv的,并没有对深度学习有一个系统的讲解,学到的知识是比较零碎的。所以,打算好好学习一下深度学习的理论知识,并做一个整理。
内容不会写成教程那样详细,大部分都将会是概括性的,总结性的,主要目的是做一个系统的梳理,原理什么的网上太多了!
因为深度学习是机器学习的一个分支,学习深度学习之前有必要先对机器学习有一个深入的了解。总之,如果入坑的话,建议先学机器学习,推荐「西瓜书」+「机器学习实战」,一本理论一本实践,这也是我们上课用的书。西瓜书公式推导不是很详细,如果自学的话,可以再补充一本「统计学习方法」,「机器学习实战」用的代码是基于陈旧的python2.7,在github上找一份python3版本的作为练习。同时可以访问sklearn官网,这是一个机器学习库,看它的文档学习,这个库封装的很好,学起来很简单。
不过,一切的前提是有数学基础和编程基础,即:学过微积分、线性代数、概率论的课程,掌握C/C++,Java或者python等,有一定编程功底。不然…
因为之前学过机器学习,这里只介绍机器学习的基本知识以及和深度学习紧密联系的内容。开始进入正题!
1.机器学习的基本任务
先放一个图镇楼!
机器学习基本任务分为四大类:
定义 | 任务 | |
---|---|---|
监督学习 | 使用已知正确答案的实例来训练模型 | 分类,回归,结构化学习(目标检测、识别、语义分割…) |
无监督学习 | 在无标签的数据集中查找规则的模型 | 聚类、降维 |
半监督学习 | 结合分类的聚类的思想生成新模型 | 自编码,生成式对抗,推荐 |
强化学习 | 对没有标注数据集,但知是否更近目标来构建模型 | 分类、回归 |
其中监督学习是目前最常用的一种机器学习类型,其一般过程如下图:
2. 机器学习一般流程
图片上方完整概述了机器学习的一般流程,不过我们重点关注建模和评估两步。因为机器学习的三要素是:模型
、学习准则
和优化算法
,这也是我们学习机器学习课程的核心。前面的数据预处理等部分其实特别重要,可以说决定机器学习模型上限,不过这部分是特征工程、数据挖掘的重点,我们的重点还是这三要素。
在监督学习中,模型就是我们要学习的条件分布
(概率模型)或决策函数
(非概率模型)。机器学习的目的就是找到一个模型来近似真实映射函数或条件分布。
什么是学习准则呢?我们知道,从输入空间到输出空间构成了一个样本空间,我们认为样本空间就是真实空间[ 这里涉及到机器学习理论的一个前提,就是我们假设样本集Q和世界W是独立同分布的,且Q在W中随机分布,因此具有足够的泛化能力 ] ,因为我们不知道真实的映射函数或条件分布,只能根据经验确定一个函数集合,称为假设空间 [选择不同模型,就有不同的假设空间,一般分为线性模型和非线性模型] ,而学习准则就是衡量当前模型好坏的一种手段,也就是当前模型和真实模型之间的差异、距离。一般用损失函数
表示。
而优化算法就是用于求解最优模型的计算方法,因为确定了训练集,假设空间和学习准则后,如何找到最优模型就成为了一个最优化
问题。分为参数优化和超参数优化,超参数用于定义模型结构或优化策略,一般人为调整。
确定模型后,还需要评估模型性能,评估方法包括:留出法
、交叉验证法
、自助法
。
3. 损失函数
可以参考文尾链接:Pytorch模型训练实用教程 和 pytorch loss function 总结
这里罗列了所有的损失函数,用来占坑,这些函数主要用于深度学习中。到时候用到哪个了再来详细补充~
L1范数损失 nn.L1Loss
公式:
平滑版L1损失 nn.SmoothL1Loss
公式:
二进制交叉熵损失 nn.BCELoss
公式:
带有logistic函数的二进制交叉熵损失 nn.BCEWithLogitsLoss
公式:
均方误差损失 nn.MSELoss
公式:
交叉熵损失函数 nn.CrossEntropyLoss
公式:
可以看出pytorch中对预测class进行了softmax操作,保证将预测值映射到0-1之间,且和为1。
关于交叉熵的理解可以看:一文搞懂交叉熵在机器学习中的使用
关于softmax可以参考:手打例子一步一步带你看懂softmax函数以及相关求导过程
KL 散度损失 nn.KLDivLoss
公式:
负对数似然损失函数 nn.NLLLoss
公式:
nn.MarginRankingLoss
公式:
nn.HingeEmbeddingLoss
公式:
多分类Hinge损失 nn.MultiMarginLoss
公式:
多标签分类损失 nn.MultiLabelMarginLoss
公式:
二分类logistic损失 nn.SoftMarginLoss
公式:
多标签损失 nn.MultiLabelSoftMarginLoss
公式:
cosine损失 nn.CosineEmbeddingLoss
公式:
三元组损失 nn.TripletMarginLoss
公式:
连接时序分类损失 nn.CTCLoss
公式:无
目标值为泊松分布的负对数似然损失 nn.PoissonNLLLoss
公式:
4.优化器
确定了模型和损失函数,接下来就要确定优化算法了。最常用、最简单的优化算法就是梯度下降法
。传统梯度下降法公式: 。不过这个简洁表示有很多不足,比如:
- 学习速率不易控制,过小收敛慢或陷入局部最优,过大又容易振荡
- 容易卡在鞍点或平坦区域,造成提前结束训练
从公式可知,影响优化的有两个因素:梯度方向
以及学习率
,因此从这两个方面入手来克服这些问题。
动量算法(Momentum)
引入动量算法
可以改变梯度下降方向
其实就是模拟了物理学中动量的概念,认为物体的运动有一个惯性。因此计算当前点的梯度后,和前一个点的梯度来进行合成,得到实际的梯度。这样做可以减小振幅,轨迹更加稳定,提高了算法的稳定性和收敛速度
当然还有一种叫做NAG的改进算法,它先按前一个点的梯度方向前进一小步,然后再修正这一步的梯度方向,进一步防止大幅度振荡,同时不会错过最小值,对参数更新也更加敏感
下面几种优化算法同时从梯度方向和学习率进行优化,效果更好!
AdaGrad算法
核心就是增加一个梯度累积变量r,用于保存累积平方梯度
,随着迭代次数增加,r的值变大,导致学习速率逐渐变小,同时算法中更新不同参数的学习速率不同,对稀疏参数大幅度更新对频繁参数小幅更新,因此提高了算法稳定性,不会因学习速率过大越过极值点,也不容易卡在鞍点。不过缺点就是,有时候学习速率减小太快导致训练不足。
RMSProp算法
通过修改AdaGrad算法而来,使用指数加权的移动平均
代替梯度平方和,引入了超参数来控制移动平均的长度范围
Adam算法
Adam本质上是带有动量项的RMSProp算法,利用梯度的一阶矩估计
和二阶矩估计
动态调整每个参数
pytoch中定义了这些优化器,每种优化算法具体细节以后用到再来补充~
5.其它问题
权重正则化
欠拟合
原因:训练不够或模型太简单过拟合
原因:训练过度或模型太复杂
一个好的模型,应该有一个较小的期望错误,但是我们只有训练集,并不知道真实的数据分布和映射函数,无法计算期望风险
,所以只能计算经验风险
,即根据训练集上的预测值和标签值之间的差值定义的损失函数值。所以原来的损失函数遵循经验风险最小化准则
。
但是我们的训练集只是真实数据一小部分,且包含噪声,所以经验风险最小化就会导致我们的模型过度学习训练集,导致过拟合,泛化性能不好。
所以我们就在经验风险最小化的基础上引入参数的正则化
,来限制模型能力,不要过度的经验最小化,这就称为结构风险最小化
。
后面一项就是正则化项,这里是正则化项用的范数,也可以用,等。其中引入了超参数,称为 权重衰减值
,用于平衡经验风险和正则化项的作用。
我们知道过拟合就是我们的模型学习能力太强了,即模型太复杂了,模型的参数太多了。而通过引入正则化项,就可以稀疏化我们的参数,因为要使结构风险最小化,就必须保证参数和不能太大,这样一些参数的值就要尽可能的小,因此防止了模型过度复杂。
下面几个问题重点关注深度学习,这里简略写一下,以后专门介绍
Dropout正则化
这是一种针对神经网络模型的正则化方法,在训练过程中随机屏蔽或忽略一些神经元,这样在正向传播中这些神经元对下游神经元作用消失,反向传播时它们的权重也不会更新。产生权重收缩
的效果,避免模型过拟合。
批量标准化
可以参考:
批量标准化BN 和
Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift全文翻译
在较复杂的神经网络中,随着前一层的参数的变化,各层的输入分布也会发生变化,这样就容易发生内部协变量移位
(internal Covariate Shift),使训练变得困难。通俗来说,比如隐藏层用作为**层,如果前一层参数变化,导致后一层的数据输入分布在两侧,根据曲线特点,可以知道此时梯度接近于0,所以就会产生梯度消失现象,导致参数不能更新了。批量标准化就是在隐藏层的输入前加入一个标准化层,解决这个问题的。
可以看到使隐藏层的输入数据归一化了,均值为0,方差为1,然后反标准化操作,引入了和这两个可以学习的参数,对标准化后的值进行缩放和平移,因为靠近0的区域在**函数上往往是线性区域,不利于训练好的非线性网络,同时也增加了网络的表达能力,使中间层输出不限制于标准正态分布,而是自己通过学习确定。
批量标准化优点很多,比如避免了梯度消失
和梯度爆炸
,加速网络收敛,并且提高了泛化能力
权重初始化
因为神经网络参数多,层数多,所以参数的初始化会影响模型的效果。
比如初始化值特别小,那么可能传到后面都没什么信息了。或者初始值特别大,可能在传播过程中产生爆炸的值。亦或是陷入了局部最优…
一般有哪些初始化方法呢?零值初始化
、随机初始化
、均匀初始化
、正态分布初始化
、正交分布初始化
等
关于**函数
正是因为**函数
,才让神经网络具有了非线性建模能力,否则无论多少层,也只能处理线性可分问题。常见的**函数包括:sigmoid、tanh、relu、LeakyReLU、softmax等
可以参考文尾链接~
总结
写得比较乱,有一些关于深度学习的比如损失函数、**函数、优化器、dropout等写的比较简洁,其实这里面单独一个主题都可以写很多,因为才刚刚开始,虽然参考了很多资料,不过理解不深,以后遇到再详写。