机器学习 知识点补充
特征、样本、数据集
特征(Feature) :特征是用来描述机器学习系统处理的对象或事件的特性。
样本(Sample) :样本是指我们从某些希望机器学习系统处理的对象或事件中收集到的已经量化的特征的集合。
数据集(Dataset) :数据集是指很多样本组成的集合。有时我们也将样本称为数据集中的数据点(Data Point) 。大部分机器学习算法可以被理解为在数据集上获取经验。
监督学习算法 与 无监督学习算法
监督学习算法(Supervised Learning Algorithm) :训练含有很多特征的数据集,不过数据集中的样本都有一个标签(Label)或目标(Target)。
无监督学习算法(Unsupervised Learning Algorithm) :训练含有很多特征的数据集,然后学习出这个数据集上有用的结构性质。
监督的理解:监督学习中教员或者老师提供标签给机器学习系统,指导其应该做什么。在无监督学习中,没有教员或者老师,算法必须学会在没有指导的情况下理解数据。
半监督学习(Semi-Supervised Learning) :监督学习与无监督学习相结合的一种学习方法。半监督学习使用大量的未标记数据,以及同时使用标记数据作为学习的数据集。
强化学习(Reinforcement Learning) :并不是训练于一个固定的数据集上。算法会和环境进行交互,所以学习系统和它的训练过程会有反馈回路。
常见的机器学习类型
凸凹函数 和 凸优化问题
凸函数 与 凹函数
凸集 :若集合中任意两点连线上的点都在该集合中,则称该集合为凸集。
凹集 :存在集合中任意两点连线上的点不在该集合中,则称该集合为凹集(非凸集)。
凸函数 :简单理解为在函数图像上任取两点,如果函数图像在这两点之间的部分总在连接着两点的线段上方且定义域为凸集的函数,为凸函数。
凹函数 :简单理解为在函数图像上任取两点,如果函数图像在这两点之间的部分总在连接这两点的线段的下方,则为凹函数。
凸优化
在一些最优化问题中很可能遇到复杂且不易求解的目标函数如高阶函数。如下图所示,其可能有多个局部极值点,而我们想找到的只有一个全局最优点。
对于一个复杂函数,找其全局最优点无疑比较困难,在实际工程中可能很难求解,这时我们想将一个复杂的非凸函数转化为一个如下图所示的凸函数,这样其局部最优便是全局最优。凸函数所对应的优化便是凸优化。
凸优化是机器学习的一个根本性问题,在工程中很多问题可以抽象化为一个凸问题,很多非凸问题可以通过一定的手段或方法转化为一个凸问题,一旦转化为一个凸问题,理论上,这个问题便可以得到解决。
凸优化的定义:只有满足以下两个条件才需要我们做凸优化的处理:
- 条件一:约束条件为凸集。
- 条件二:目标函数为凸函数。
非凸优化问题转化为凸优化问题的方法:
- 修改目标函数,使之转化为凸函数。
- 抛弃一些约束条件,使新的可行域为凸集并且包含原可行域。
交叉嫡损失函数
熵是对一个随机变量的不确定性的“数学性度量”,就像我们使用kg来表示物体的重量、用 m 来表示物体的长度等方式一样的数学度量。信息就是减少这种不确定的事物,如帮助调整概率、排除干扰或者确定具体属于哪一类。熵和信息数量相等,意义相反,获取信息意味着消除这种不确定性。
概率是表示随机变量是某个可能情况的确定性,而熵是随机变量属于某种可能情况的不确定性。
什么是交叉熵?
交叉熵,其用来衡量在给定的真实分布下,使用非真实分布所指定的策略消除系统的不确定性所需要付出的努力的大小,也就是两个概率分布之间的距离.给定两个概率分布 p 和 q,通过 q 来表示 p 的交叉熵就是通过概率分布 q 来表达概率分布 p 的困难程度,p 代表正确答案,q 代表的是预测值,交叉熵越小,两个概率的分布约接近。
H
(
p
,
q
)
=
∑
p
?
l
o
g
2
1
q
H(p,q)=\sum p*log_2\frac{1}{q}
H(p,q)=∑p?log2?q1? 我们可以用"相对熵"(或称 KL 散度)来衡量两个分布的距离。在机器学习中,P 往往用来表示样本的真实分布, Q 是我们训练模型得到的分布。当 P 的分布与 Q 相同时,它们的距离为 0。
机器学习中结果左边是由样本真是分布获得的,右边就是交叉熵。
另外,在神经网络中怎样把前向传播得到的结果也变成概率分布呢?Softmax 回归就是一个非常有用的方法。(所以面试官会经常问你,为什么交叉熵经常要个 softmax 一起使用?)
假设原始的神经网络的输出为
y
1
,
y
2
,
.
.
.
y
n
y_{1},y_{2},...y_{n}
y1?,y2?,...yn?,那么经过 Softmax 回归处理之后的输出:
s
o
f
t
m
a
x
(
y
)
i
=
e
y
j
∑
n
j
=
1
e
y
j
softmax(y)_i=\frac{{e^y}_j}{\sum_{n}^{j=1} {e^y}_j}
softmax(y)i?=∑nj=1?eyj?eyj??
这样就把神经网络的输出也变成了一个概率分布,从而可以通过交叉熵来计算预测的概率分布和真实答案的概率分布之间的距离了。
损失函数
神经网络中使用的代价函数被称作损失函数 (Loss Function)。
神经网络在数据集上学习,就是通过对训练数据集的学习,调整神经网络中每个神经元的参数,使得损失函数的值取得最低或者相对较低的值。
交叉嫡损失函数 categorical_crossentropy:
由以上描述可知,交叉熵是用来评估两个样本分布之间的距离,我们可以使用交叉熵来评估当前训练得到的概率分布与真实分布的差异情况,也就是使用交叉熵损失函数刻画的是实际输出(概率)与期望输出(概率)的距离,也就是交叉熵的值越小,两个概率分布就越接近。
梯度下降法(GD)
梯度下降(Gradient Descent)
首先我们可以把梯度下降拆解为梯度+下降,那么梯度可以理解为导数(对于多维可以理解为偏导),那么合起来变成了:导数下降,那问题来了,导数下降是干什么的?
这里我直接给出答案:梯度下降就是用来求某个函数最小值时自变量对应取值。
其中这句话中的某个函数是指:损失函数(cost / loss function),直接点就是误差函数。
损失函数就是一个自变量为算法的参数,函数值为误差值的函数。所以梯度下降就是找让误差值最小时候算法取的参数。
【补充点小知识】
但是这面两种算法产生的拟合曲线并不是完全和现有的点重合,拟合曲线和真实值之间有一个误差。所以我们一般用损失函数的
值来衡量这个误差,所以损失函数的误差值越小说明拟合效果越好。(简单理解:损失函数表示预测值与实际值之间的误差。)
梯度下降常用的方法有三种:
批量梯度下降(BGD) :每次更新使用所有的训练数据,最小化损失函数,如果只有一个极小值,那么批量梯度下降是考虑了训练集所有数据,但如果样本数量过多,更新速度会很慢。
随机梯度下降(SGD) :每次更新的时候只考虑了一个样本点,这样会大大加快训练速度,但是函数不一定是朝着极小值方向更新,且 SGD 对噪声也更加敏感。
小批量梯度下降(MBGD) :MBGD 解决了批量梯度下降法的训练速度慢问题,以及随机梯度下降对噪声敏感的问题。
梯度下降 Python 实现案例:
import numpy as np
import matplotlib.pyplot as plt
def f(x):
return np.array(x) ** 2 + 1
def Derivative(x):
return x * 2
def Gradient_Descent(current_x=0.1, learn_rate=0.01, e=0.001, count=50000):
for i in range(count):
grad = Derivative(current_x)
if abs(grad) < e:
break
current_x = current_x - grad * learn_rate
print("第{}次迭代逼近值为{}".format(i + 1, current_x))
print("最小值为:", current_x)
print("最小值保存小数点后6位:%.6f" % (current_x))
return current_x
def ShowLine(min_X, max_Y):
x = [x for x in range(10)] + [x * (-1) for x in range(1, 10)]
x.sort()
print(x)
plt.plot(x, f(x))
plt.plot(min_X, max_Y, 'ro')
plt.show()
minValue = Gradient_Descent(current_x=0.1, learn_rate=0.01, e=0.001, count=50000)
minY = f(minValue)
print('目标函数最小值约为:', minY)
ShowLine(minValue, minY)
Sigmoid、tanh 激活函数
学习神经网络的时候我们总是听到激活函数这个词,而且很多资料都会提到常用的激活函数,比如Sigmoid函数、tanh函数、Relu函数、softmax函数。那么我们就来详细了解下激活函数方方面面的知识。
什么是激活函数(activation function)?
神经网络中的每个神经元节点接受上一层神经元的输出值作为本神经元的输入值,并将输入值传递给下一层,输入层神经元节点会将输入属性值直接传递给下一层(隐层或输出层)。在多层神经网络中,上层节点的输出和下层节点的输入之间具有一个函数关系,这个函数称为激活函数(又称激励函数)。
激活函数的用途(为什么需要激活函数)?
如果不用激励函数(其实相当于激励函数是
f
(
x
)
=
x
f(x) = x
f(x)=x),在这种情况下你每一层节点的输入都是上层输出的线性函数,很容易验证,无论你神经网络有多少层,输出都是输入的线性组合,与没有隐藏层效果相当,这种情况就是最原始的感知机(Perceptron)了,那么网络的逼近能力就相当有限。
正因为上面的原因,我们决定引入非线性函数作为激励函数,这样深层神经网络表达能力就更加强大(不再是输入的线性组合,而是几乎可以逼近任意函数)。
激活函数设计需考虑的因素
-
非线性:当激活函数是非线性的,一个两层神经网络可以证明是一个通用函数近似值,如果失去了非线性,整个网络就相当于一个单层的线性模型。 -
连续可微性:这个属性对基于梯度优化方法是必要的,如果选择了一些具有局部不可微的函数,则需要强行定义此处的导数。 -
有界性:如果激活函数有界的,基于梯度的训练方法往往更稳定;如果是尤界的,训练通常更有效率,但是训练容易发散,此时可以适当减小学习率。 -
单调性:如果激活函数是单调的,与单层模型相关的损失函数是凸的。 -
平滑性:有单调导数的平滑函数已经被证明在某些情况下泛化效果更好。
有哪些激活函数,都有什么性质和特点?
早期研究神经网络主要采用 sigmoid 函数或者 tanh 函数,输出有界,很容易充当下一层的输入。近些年Relu函数及其改进型(如Leaky-ReLU、P-ReLU、R-ReLU等)在多层神经网络中应用比较多。
单位阶跃函数(赫维赛德阶跃函数)
单位阶跃函数,又称赫维赛德阶跃函数,方程式如下:
f
(
x
)
=
{
0
,
x
<
0
1
,
x
≥
0
f(x)=\begin{cases} 0,\qquad x<0 \\ 1, \qquad x \geq 0 \end{cases}
f(x)={0,x<01,x≥0?
函数曲线如下: ? 可以看出是个不连续函数,它是一个几乎必然是零的随机变量的累积分布函数,激活值只有 0 和 1,即百分百确定和百分百不确定,适合二分类问题。
sigmoid 函数(Logistic 函数)
Logistic 函数也叫 Sigmoid 函数,用于隐层神经元输出,取值范围为(0,1),它可以将一个实数映射到(0,1)的区间,因此 Sigmoid 函数作为输出层时可以用来做二分类。在特征相差比较复杂或是相差不是特别大时效果比较好。方程式如下:
f
(
x
)
=
1
1
+
e
?
x
f(x)=\frac{1}{1+e^{-x}}
f(x)=1+e?x1?
函数曲线如下: 其导数方程式如下:
f
(
x
)
′
=
f
(
x
)
(
1
?
f
(
x
)
)
f(x)^{'}=f(x)(1?f(x))
f(x)′=f(x)(1?f(x)) Logistic 函数平滑、易于求导,但是计算量大,反向传播求误差梯度时,求导涉及除法;反向传播时,很容易就会出现梯度消失的情况,从而无法完成深层网络的训练。
Tanh 函数
Tanh 函数能够将输入“压缩”到
(
?
1
,
1
)
(?1,1)
(?1,1) 区间,方程式如下:
f
(
x
)
=
T
a
n
h
(
x
)
=
e
x
?
e
?
x
e
x
+
e
?
x
f(x)=Tanh(x)=\frac{e^x-e^{-x}}{e^x+e^{-x}}
f(x)=Tanh(x)=ex+e?xex?e?x? 函数曲线如下: 可以看到 tanh 激活函数可通过 Sigmoid 函数缩放平移后实现。其导数方程式如下:
f
′
(
x
)
=
1
?
f
(
x
)
2
f^{′}( x ) = 1 - f(x)^2
f′(x)=1?f(x)2
与 sigmoid 函数相比,它的输出均值为 0,使其收敛速度要比 sigmoid 快,可以减少迭代次数。它的缺点是需要幂运算,计算成本高;同样存在梯度消失,因为在两边一样有趋近于0的情况。
ReLU函数(整流线性单位函数)
整流线性单位函数(ReLU )又称修正线性单元, 是一种人工神经网络中常用的激励函数(activation function),通常指代以斜坡函数及其变种为代表的非线性函数。
ReLU 认为有一定的生物学原理,并且由于在实践中通常有着比其他常用激励函数(譬如 Sigmoid 函数)更好的效果,而被如今的深度神经网络广泛使用于诸如图像识别等计算机视觉人工智能领域。方程式如下:
f
(
x
)
=
m
a
x
(
0
,
x
)
f(x)=max(0,x)
f(x)=max(0,x) 而在神经网络中,ReLU 作为神经元的激活函数,定义了该神经元在线性变换
w
T
+
b
w^T + b
wT+b 之后的非线性输出结果。换言之,对于进入神经元的来自上一层神经网络的输入向量
x
x
x,使用 ReLU 的神经元会输出:
f
(
x
)
=
m
a
x
(
0
,
w
T
+
b
)
f(x)=max(0,w^T + b)
f(x)=max(0,wT+b)
函数曲线如下: 导数方程式如下:
f
′
(
x
)
=
{
0
,
x
<
0
1
,
x
≥
0
f^{'}(x)=\begin{cases} 0,\qquad x<0 \\ 1, \qquad x \geq 0 \end{cases}
f′(x)={0,x<01,x≥0?
相对 sigmoid 和 tanh,极大地改善了梯度消失的问题,收敛速度块;不需要进行指数运算,因此运算速度快,复杂度低;ReLU 函数会使得一部分神经元的输出为0,这样就造成了网络的稀疏性,并且减少了参数的互相依存关系,缓解了过拟合问题的发生。它的缺点是对参数初始化和学习率非常敏感;存在神经元死亡;ReLU 函数的输出均值大于0,偏移现象和神经元死亡会共同影响网络的收敛性。
Softmax函数(归一化指数函数)
Softmax 函数,或称归一化指数函数,有多个输入,是 Sigmoid 函数的一种推广。它能将一个含任意实数的
K
K
K 维向量
z
z
z “压缩”到另一个
K
K
K 维实向量
σ
(
z
)
\sigma(z)
σ(z) 中,使得每一个元素的范围都在
(
0
,
1
)
(0,1)
(0,1) 之间,并且所有元素的和为
1
1
1。那么我们就可以将它理解成概率,在最后选取输出结点的时候,我们就可以选取概率最大(也就是值对应最大的)结点,作为我们的预测目标。方程式如下: Softmax 的使用包括两个好处,第一个好处是好求导,第二个就是它使得好结果和坏结果之间的差异更加显著,更有利于学习了。
离散随机 与 连续随机
离散随机变量:伯努利分布(Bernoulli Distribution)
在一次试验中,事件A出现的概率为
μ
\mu
μ,不出现的概率为
1
一
μ
1一\mu
1一μ。若用变量
X
X
X 表示事件
A
A
A 出现的次数,则
X
X
X 的取值为 0 和 1,其相应的分布:
p
(
x
)
=
μ
x
(
1
?
μ
)
1
?
x
p(x)=\mu^x(1-\mu)^{1-x}
p(x)=μx(1?μ)1?x
离散随机变量:二项分布(Binomial Distribution)
在
n
n
n 次伯努利分布中,若以变量
X
X
X 表示事件
A
A
A 出现的次数,则
X
X
X 的取值为
0
,
.
.
.
,
n
{0,... ,n}
0,...,n,其相应的分布:
P
(
X
=
k
)
=
(
n
k
)
μ
k
(
1
?
μ
)
n
?
k
k
=
1
,
?
?
?
,
n
P(X=k) = \begin{pmatrix} n \\ k \end{pmatrix}\mu^k(1-\mu)^{n-k} \qquad k=1,···,n
P(X=k)=(nk?)μk(1?μ)n?kk=1,???,n
连续随机变量
概率分布一般用概率密度函数(Probability Density Function, PDF),用
p
(
x
)
p(x)
p(x) 来描述。
∫
?
∞
+
∞
p
(
x
)
d
x
=
1
\int_{-\infty}^{+\infty}p(x)dx=1
∫?∞+∞?p(x)dx=1
高斯分布(Gaussian Distribution)
高斯分布表达式:
p
(
x
)
=
1
2
π
σ
e
x
p
(
?
(
x
?
μ
)
2
2
σ
2
)
p(x) = \frac{1}{\sqrt{2\pi\sigma}}exp(-\frac{(x-\mu)^2}{2\sigma^2})
p(x)=2πσ
?1?exp(?2σ2(x?μ)2?)
采用正态分布在很多应用中都是一个明智的选择。当我们由于缺乏关于某个实数上分布的先验知识而不知道该选择怎样的形式时,正态分布是默认的比较好的选择,其中有两个原因。
第一,我们想要建模的很多分布的真实情况是比较接近正态分布的。中心极限定理(central limit theorem)说明很多独立随机变量的和近似服从正态分布。这意味着在实际中,很多复杂系统都可以被成功地建模成正态分布的噪声,即使系统可以被分解成一些更结构化的部分。
第二,在具有相同方差的所有可能的概率分布中,正态分布在实数上具有最大的不确定性。因此,我们可以认为正态分布是对模型加入的先验知识量最少的分布。
numpy.random.normal(loc=0.0, scale=1.0, size=None)
loc:float :此概率分布的均值(对应着整个分布的中心 centre)
scale:float :此概率分布的标准差(对应于分布的宽度,scale 越大越矮胖,scale 越小,越瘦高)
size:int or tuple of ints :输出的 shape,默认为 None,只输出一个值
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import numpy
y = numpy.random.normal(loc=0.0, scale=1.0, size=None)
print(y)
深度神经网络(DNN)
深度神经网络(Deep Neural Networks,DNN)可以理解为有很多隐藏层的神经网络,又被称为深度前馈网络(DFN),多层感知机(Multi-Layer perceptron, MLP)。
多层感知器
多层感知器,就是在输入层和输出层之间加入隐层,以形成能够将样本正确分类的凸域。多层感知器的拓扑结构如下图所示:
由上图可以看出,随着隐层层数的增多,凸域将可以形成任意的形状,因此可以解决任何复杂的分类问题。Kolmogorov理论指出:双隐层感知器就足以解决任何复杂的分类问题。
多层感知器确实是非常理想的分类器,但问题也随之而来:隐层的权值怎么训练?对于各隐层的节点来说,它们并不存在期望输出,所以也无法通过感知器的学习规则来训练多层感知器。
DNN 的基本结构
按不同层的位置划分,DNN内部的神经网络层可以分为:输入层,隐藏层和输出层,一般第一层是输入层,最后一层是输出层,而中间的层数都是隐藏层。层与层之间是全连接的,即第i层的任意一个神经元一定与第i+1层的任意一个神经元相连。
深度学习与神经网络的区别
神经网络 :
(a)采用BP算法调整参数,即采用迭代式算法来训练整个网络。随机设定初值,计算当前网络的输出,然后根据当前输出和样本真实标签之间的差去改变前面各层的参数,直到收敛。
(b)比较容易过拟合,参数比较难调整,而且需要不少的技巧。
(c)训练速度比较慢。在成熟比较少(小于等于3)的情况下效果并不比其他方法更优。
深度学习 :
采用逐层训练机制。采用该机制的原因在于如果采用 BP 机制,对于一个深层网络(7层以上),残差传播到最前面的层将变得很小,出现所谓的gradient diffusion(梯度扩散)。
BP神经网络是一种按误差反向传播(简称误差反传)训练的多层前馈网络,其算法称为BP算法,它的基本思想是梯度下降法,利用梯度搜索技术,以期使网络的实际输出值和期望输出值的误差均方差为最小
神经网络在感知器的模型上做了以下 3 点的扩张:
- 加入隐藏层,隐藏层可以有多层,增强模型的表达能力。
- 输出层的神经元也可以不止一个,可以有多个输出,模型就可以灵活的应用于分类回归,以及其他的机器学习领域比如降维和聚类等。
- 对激活函数做扩展,包括Sigmoid函数,Softmax 和 ReLU 等。
反向传播算法(BP)
BP 算法(即反向传播算法 back propagation)适合于多层神经元网络的一种学习算法,它建立在梯度下降法的基础上。
BP网络的输入输出关系实质上是一种映射关系:一个 n 输入 m 输出的 BP 神经网络所完成的功能是从 n 维欧氏空间向 m 维欧氏空间中一有限域的连续映射,这一映射具有高度非线性。它的信息处理能力来源于简单非线性函数的多次复合,因此具有很强的函数复现能力。这是 BP 算法得以应用的基础。
什么是反向传播?
反向传播是神经网络中最基本的学习算法,他是可以根据输出层的误差来更新每一层的参数。
我们可以先通过BP网络的走向图大致掌握以下反向传播算法的主要用处,从输入层开始,数据进入到网络中经过每一层的计算变化,最终得出实际输出。然后和期望输出做比较计算损失值,此时的损失值将按照反方向逐渐向前传播计算,通过梯度下降的方式优化网络中的参数,求取出符合要求的网络模型。如图中所示:
泛化、过拟合 与 正则化
泛化 即是,机器学习模型学习到的概念在它处于学习的过程中时模型没有遇见过的样本时候的表现。
过拟合 :当某个模型过度的学习训练数据中的细节和噪音,以至于模型在新的数据上表现很差,我们称过拟合发生了。这意味着训练数据中的噪音或者随机波动也被当做概念被模型学习了。而问题就在于这些概念不适用于新的数据,从而导致模型泛化性能的变差。
过拟合更可能在无参数非线性模型中发生,因为学习目标函数的过程是易变的具有弹性的。
网上流传着一张图,很形象的解释了什么叫过拟合:
欠拟合 :与过拟合相反,指的是模型在训练和预测时效果都很差。
线性回归 与 多项式回归
|