单纯就是个人杂乱的笔记····
机器学习简介
Supervised VS Reinforcement
前者是监督学习,可以看作在老师的指导下学习(带Label),我们告诉机器该如何回答;
后者是强化学习,可以看作从评价中学习,机器只知道学习的好坏(得分),不知道哪里学的好哪里学的坏。
semi-supervised (半监督):有带Label的数据,也有不带Label的数据(也对学习有帮助)
Transfer Learning(迁移学习):有带Label的数据,并且有带Label且与任务不相干的数据(比如你的网络是划分猫和狗的图片,数据里却有老虎的图片)
Unsupervised(无监督):没有现成输出,让机器自己学习
Structed Learing(超越了分类):例如机器翻译、人脸辨识等
Error
我们机器学习一般是需要寻找一个未知的function,给定一定量的训练数据,我们可以机器学习到一个估计量的function*,我们一般考察估计量的bias(与实际值的差)和variance(方差,衡量随机变量或一组数据时离散程度的度量),如下图,靶心为实际function,bias是离靶心的距离,variance是蓝点 f* 的离散度:
在理想情况,bias和variance越小越好,但是实际情况,简单模型很可能bias大,variance小,复杂模型bias小,variance大,我们需要权重两者。
如何诊断我们的model:
- 我们的model在训练集上误差很大,则bias很大,为underfit
- 在训练集上误差小,在测试集上误差大,则variance大,为overfit 过拟合
如何处理大bias?
- 添加更多的输入特征
- 选择更复杂的模型
如何处理大variance
- 增加更多的data
- 正则化regularization
交叉验证 cross validation
在给定的建模样本中,拿出大部分样本进行建模型,留小部分样本用刚建立的模型进行预报.
交叉验证用于评估模型的预测性能,尤其是训练好的模型在新数据上的表现,可以在一定程度上减小过拟合,还可以从有限的数据中获取尽可能多的有效信息。
另: n折交叉验证:划分时取不同段为val验证,以避免固定划分数据集的局限性、特殊性
gradient descent 梯度下降
梯度下降(gradient descent),其主要目的是通过迭代找到目标函数的最小值,或者收敛到最小值。
假设一个人被困在山上,需要从山上下来(找到山的最低点)。但此时山上的浓雾很大,导致可视度很低;因此,下山的路径就无法确定,必须利用自己周围的信息一步一步地找到下山的路,不妨利用梯度下降算法来帮助自己下山。
首先以他当前的所处的位置为基准,寻找这个位置最陡峭的地方,然后朝着下降方向走一步,然后又继续以当前位置为基准,再找最陡峭的地方,再走直到最后到达最低处;最终会到达一个收敛点(局部最优但不一定全部最优)
从数学的角度而言,我们有一个可微分的函数 F ,其代表着山。我们的目标就是找到这个函数 F 的最小值,数学模型经典优化问题模型。根据之前的假设,最快下山的方式就是:找到当前位置最陡峭的方向,然后沿着此方向向下走,对应到函数中,就是找到给定点的梯度 ,然后朝着梯度相反的方向,就能让函数值下降的最快,因为梯度的方向就是函数变化最快的方向
梯度是微积分中一个很重要的概念:
- 在单变量的函数中,梯度其实就是函数的微分,代表着函数在某个给定点的切线的斜率
- 在多变量函数中,梯度是一个向量,向量有方向,梯度的方向就指出了函数在给定点的上升最快的方向
我们需要到达山底,就需要在每一步观测到此时最陡峭的地方,梯度就恰巧告诉了我们这个方向。梯度的方向是函数在给定点上升最快的方向,那么梯度的反方向就是函数在给定点下降最快的方向,这正是我们所需要的,即梯度下降方法。
在梯度下降法中,公式为:
其中 η 代表学习率(learning rate),通常通过调整α来控制每一步走的距离,即步长。
需要注意的是 η 过大或者过小都不好,如下图:
蓝色的 η 过小导致收敛时间过长,而黄色和绿色的 η 过大,导致错过了loss实际的最小值。
通常当 F 的参数超过3个,我们很难直接可视化loss的梯度下降趋势,但是我们可以可视化参数更新对Loss的影响,如下图:
很明显,黄色loss没有稳定下降,很可能是 η 过大导致步子迈太大了。
自适应学习率算法
我们有很多方法能够自适应的调整 learning rate,常见的如AdaGrad算法、RMSProp算法等等:
AdaGrad中,学习率要除以当前所有微分值的 平均平方和 的根,举例如下:
实际上 分子分母的 根号下 t + 1 可以相消舍去;AdaGrad中当参数损失偏导值比较大时,有一个较大的学习率;当参数的损失偏导值较小时,有一个较小的学习率。
对于之前强调的梯度下降方法,由于计算出所有训练数据的损失函数非常耗时,我们有改进的随机梯度下降法。
随机梯度下降法
并不对全部训练数据上的损失函数进行优化,在每一轮迭代中随机选择某一个或多个训练数据上的损失函数进行梯度下降优化,加快每一轮参数更新的速度。
Feature scaling 特征缩放
特征缩放希望将数据规范化,使得特征的范围具有可比性,消除数据数量级造成的影响,提高梯度下降方法收敛速度。
特征缩放的一些方法
标准化(Standardization)
特征标准化使每个特征的值有零均值(zero-mean)和单位方差(unit-variance),这个方法的公式如下:
mean是均值,std是标准差
分类 classification
分类问题很常见,通常我们希望得到一个 function ,input进入得到ouput的分类信息。比如宝可梦属性分类:
用回归方法解分类问题显然不合时宜,我们需要新的solution来解决分类。
可以用概率论的贝叶斯公式、最大似然估计。
deep learning
先说明一下最简单的全连接的前馈网络,各神经元分层排列。每个神经元只与前一层的神经元相连,接收前一层的输出,并输出给下一层.各层间没有反馈,如下图:
输入称为输入层,输出的前一层称为输出层,中间的部分称为隐藏层。
所谓深度学习,一般指的就是有很多层隐藏层。
神经网络可以将函数运算转化成矩阵的运算(如上图例),矩阵运算可通过GPU进行加速,而多层网络可看成进行多次矩阵运算。
可以理解为,隐藏层在分类问题中用于特征提取,在输出层带入softmax函数输出结果.
backpropagation
在神经网络的梯度计算中一般采用反向传播算法(backpropagation)
首先我们复习一下微分的链式法则:
举个例子看后向传播,L 为 Loss:
我们的w影响z,而z影响L,根据链式法则求L对w的微分。我们分为两步:
-
前向传:计算所有参数的 δ z δ ω \frac{\delta z}{\delta \omega} δωδz
对上图例子,z 对应 ω \omega ω 的偏微分就是其对应的输入xi,如下:
-
后向传:计算所有激活函数输入z的 δ l δ z \frac{\delta l}{\delta z} δzδl
上图求某个激活函数输入z的 δ l δ z \frac{\delta l}{\delta z} δzδl,激活函数为 α = σ ( z ) \alpha =\sigma(z) α=σ(z)
由链式法则可以得到上图的下方式子
而 δ z ′ δ a \frac{\delta z\rq}{\delta a} δaδz′ 和 δ z ′ ′ δ a \frac{\delta z\rq\rq}{\delta a} δaδz′′和前向计算一样,很容易得出为w3和w4,而 δ a δ z \frac{\delta a}{\delta z} δzδa 激活函数偏导基本固定,直接映射得到。
假设 δ l δ z ′ \frac{\delta l}{\delta z\rq} δz′δl 和 δ l δ z ′ ′ \frac{\delta l}{\delta z\rq\rq} δz′′δl已知,我们可以把 δ l δ z \frac{\delta l}{\delta z} δzδl写成类似神经元的wx + b的形式:
看成反向的神经元:
好,现在消除之前 假设 δ l δ z ′ \frac{\delta l}{\delta z\rq} δz′δl 和 δ l δ z ′ ′ \frac{\delta l}{\delta z\rq\rq} δz′′δl已知 这个条件;我们从输出层的y开始,y认为是关于 z ′ z\rq z′的函数,由链式法则 l → y → z ′ l\rarr y\rarr z\rq l→y→z′:
上面演示了输出层前一层 δ l δ z \frac{\delta l}{\delta z} δzδl计算,对于中间层的 δ l δ z \frac{\delta l}{\delta z} δzδl计算,我们从后往前递归计算即可。
总结两步如下图:
我们用后向传播能够得到所有参数的微分,之后便可以用梯度下降法一类的来更新权重;
batch && epoch
我们实际在做model train时,并不会直接最小化所有数据的 Loss,而是将数据随机分成若干个等大小的batch,便于并行运算;
然后我们随便取一个batch进行train,然后计算loss 更新权重参数;
重新选一个没选过的batch,计算loss 更新权重参数…直到所有batch全部pick;
而epoch就是 repeat多少次;
gradient problem
在构建人工神经网络时,我们起初认为网络越复杂,层数越深,效果会更好,但在实际中却常常事与愿违,是什么原因呢?
用之前的全连接网络做例子,前几层的输入的梯度往往很小,理由为:
我们用到的激活函数sigmod,其将大范围的input变化,在output以较小的变化展示出来
sigmod函数:
σ
(
z
)
=
1
1
+
e
−
z
\sigma(z) = \frac{1}{1+e^{-z}}
σ(z)=1+e−z1 图像如下:
求导后如下:
当梯度消失发生时,接近于输出层的隐藏层由于其梯度相对正常,所以权值更新时也就相对正常,但是当越靠近输入层时,由于梯度消失现象,会导致靠近输入层的隐藏层权值更新缓慢或者更新停滞。这就导致在训练时,只等价于后面几层的浅层网络的学习,效果反而变差。
本质上,是因为网络层数太深而引发的梯度反向传播中的连乘效应,梯度消失就是因为反向计算梯度是链式法则练成了较多(0,0.25)的值(对应sigmod的导数的值域范围),梯度爆炸而是连乘了较多大于1的值.
解决方法
换用Relu、LeakyRelu、Elu等激活函数
ReLu:让激活函数的导数为1
LeakyReLu:包含了ReLu的几乎所有有点,同时解决了ReLu中0区间带来的影响
dropout
Dropout可以比较有效的缓解过拟合的发生,在一定程度上达到正则化的效果。
简单说:我们在前向传播的时候,让某个神经元的激活值以一定的概率p被“丢掉”,这样每次更新参数前,网络的结构都会发生一定的改变,可以使模型泛化性更强,其不会太依赖某些局部的特征;
过程大致为:
- 恢复上次被删掉的神经元(此时被删除的神经元保持原样,没有被删除的神经元已经更新)
- 从隐藏层神经元中随机选择一个一半大小的子集临时删除掉(备份被删除神经元的参数)。
- 对一小批训练样本,先前向传播然后反向传播损失并根据随机梯度下降法更新参数(w,b) (没有被删除的那一部分参数得到更新,删除的神经元参数保持被删除前的结果)。
- 不断重复以上过程。
dropout只用在train不用再test,在test时,每一个神经单元的权重参数要乘以概率1-p(dropout丢弃率为p)
test时需要乘上1-p的原因:
考虑第一隐藏层的一个神经元在dropout之前的输出是
x
x
x,那么dropout之后的期望值是
E
=
(
1
−
p
)
∗
x
+
p
∗
0
E=(1−p)*x+p * 0
E=(1−p)∗x+p∗0 ,在测试时该神经元总是激活,为了保持同样的输出期望值,并使下一层也得到同样的结果,需要调整
x
→
(
1
−
p
)
∗
x
x→(1−p)*x
x→(1−p)∗x.
Convolutional Neural Network
卷积神经网络可以自行设计网络结构,CNN相较于全连接网络,其识别图像的参数更少,效果更好,下图为CNN考虑的问题和做法:
Convolution
卷积过程,我们首先有一个输入矩阵,多个Filter卷积核,Bias,得到一个输出矩阵,示例如下图:
蓝色为输入矩阵,暗蓝色为卷积核,绿色为输出特征;
注意卷积过程不是矩阵相乘,可以看成之前 Full connected的权重计算,只不过这个
w
w
w是Filter,
上图得到的-1,实际上是3个矩阵和对应Filter做
w
∗
x
+
b
w*x + b
w∗x+b 的操作(0 + 1 - 1 - 1 = -1)
上图最终输入为 3 * 3,因为步长stride = 2;
卷积的目的是为了什么呢?
卷积利用同一组参数的Filter找到不同区域的类似特性,示例如下图:
我们通过卷积得到的结果可称为Feature Map(可以看作新的图片),我们发现 Filter 左上右下斜对角全为1,这导致Feature Map中为3的位置,对应的输入数据保留有 左上右下斜对角全为1 的特质。
对于彩色图片,RGB三张图片,采用3通道输入。
我们把CNN看成是Full connected neural network的缩略版,解释如下:
我们把输入 6 * 6 的图片拉直,等价于输入36个pixel,输出当作多个点,而卷积核相当于在两者之间连线,显然CNN的连线是少于Full connected neural network的,同时这些线上的参数对每个pixel来说都是一样的,这样大大减小了参数的数量。
卷积不一定会降低大小,还可能增加大小,如
u
p
−
c
o
n
v
up-conv
up−conv:
Pooling
Max Pooling代表最大池化,是对某个filter抽取到的特征值,只取得其中最大得那个作为保留值,其他特征值全抛弃;
类似还有Average pooling,就是取平均值…
pooling将多个值处理为1个值,对应于图片就是做了下采样(subsampled),生成对应图像保留主要特征的缩略图。
Ensemble
集成思想是机器学习中重要的思想之一,Ensemble 针对的是多个模型的团队协作问题。
Bagging
假设现在有N条数据,从 N 条训练数据中有放回的随机抽取出
N
′
N\rq
N′条作为训练集
(每次在原样本中抽出一个,都有放回,再抽取下一次,一般 N = N’,但由于是有放回的抽,所以具体的数据还是不同)。
得到不同的数据集后,分别train得到不同的function
模型做预测的时候用 average(平均)或者 voting(投票)。
Bagging 用于模型j较复杂,结果容易过拟合的情况,用来减小 variance(比如decision tree + bagging的 随机森林算法),且基础模型之间没有太多联系,训练可并行进行。
Out-of-bag validation(self-validation)
用 bagging 方法不一定要把训练数据切分成训练集和验证集,理由:
因为每轮随机采样都会有一部分数据没有被采样到,可以用这部分数据来验证模型的泛化能力。
理论上有
1
e
\frac{1}{e}
e1 占比的数据是从不会被采样(一轮没有被采样的概率是
1
−
1
N
1-\frac{1}{N}
1−N1,N 轮都没被采样到的概率是
(
1
−
1
N
)
N
(1-\frac{1}{N})^{N}
(1−N1)N,当
N
→
∞
N\to ∞
N→∞ 时极限是
1
e
\frac{1}{e}
e1 )。
例如,训练基础模型的数据情况如下表
那就可以用 f2+f4 在 x1 上测试;f2+f3 在 x2 上测试…
Boosting
Boosting是用在弱的基分类器(erro rate小于0.5就行)上,通过集成弱分类器,可以得到一个效果较好的综合分类器。大致做法是:
首先需要找一个分类器
f
1
(
x
)
f\tiny1 \normalsize(x)
f1(x) ,然后找另一个分类器
f
2
(
x
)
f\tiny2 \normalsize(x)
f2(x) 去帮助
f
1
(
x
)
f\tiny1 \normalsize(x)
f1(x), 当然
f
1
(
x
)
f\tiny1 \normalsize(x)
f1(x) 不能和
f
2
(
x
)
f\tiny2 \normalsize(x)
f2(x)太相似 (过于相似会导致帮助效果太小,最好是互补)。
接下来,再寻找第二个
f
2
(
x
)
f\tiny2 \normalsize(x)
f2(x),最后再把所有的分类器集合起来…
在这里注意,boosting的分类器选择是有顺序的,而上面说的bagging是没顺序的,也就是说boosting不适合并行。
那么如何得到不同的基分类器呢?
类似Bagging我们resample数据进行train,也可以得到不同的基分类器。
除此以外,也可以改变每个数据的权重即re-weight, 而在实际应用中,一般是通过修改损失函数来完成的,对于不同的样本,其损失函数前面会乘上不同的系数,比如我们对每一组数据分一个weight
u
u
u,开始所有的
u
u
u都是1,我们可以重新赋值
u
u
u,令不同的数据不一样。
Adaboost
内容参考传送门
idea: 在
f
1
(
x
)
f\tiny1 \normalsize(x)
f1(x) 训练不好的数据上训练去训练
f
2
(
x
)
f\tiny2 \normalsize(x)
f2(x)
怎么找到这个
f
1
(
x
)
f\tiny1 \normalsize(x)
f1(x) 训练不好的数据集呢?
我们通过计算
f
1
(
x
)
f\tiny1 \normalsize(x)
f1(x)的error rate
ε
\varepsilon
ε来得到新的数据集:
只要基分类器不是随机的,那么
ε
\varepsilon
ε 总小于 0.5。
接下来,我们将这些data的权重
u
1
u\tiny1
u1 改为
u
2
u\tiny2
u2,使得:
那么这个操作就好像是说,我们re-weight了数据后,
f
1
(
x
)
f\tiny1 \normalsize(x)
f1(x)的表现变差了。
看个实例。现在有四笔数据,如下图,我们的
f
1
(
x
)
f\tiny1\normalsize(x)
f1(x) 最开始认错了一笔,
ε
\varepsilon
ε = 0.25:
之后我们把答错的data 权重调高,答对的权重调低,然后把这组re-weight的data来训练
f
2
(
x
)
f\tiny2 \normalsize(x)
f2(x),原则为:
d
1
d\tiny1
d1 如何求到?推导如下:
于是,我们可以推出