深度学习 --- 神经网络
神经网络
神经网络是机器学习中的重要模型,可以解决两类问题的解答
- 分类:把数据分为不同类别
- 回归:建立数据间的连续关系,在二维空间中我们想找到这样一条直线,空间中的点可以尽量多的在直线上或里直线最近,在三维空间中找到一个面,空间中的点可以尽量多的分布在这个面上,或里面的距离尽量小
最简单的神经网络分类问题–线性界限
在二维世界中,存在这样的有规律的点,如下,我们的目的是要根据这些点来寻找一条合适的直线来区分这些点,这个寻找的过程叫做学习,当我们有新的点时候,我们怎么来判断这个点在那个区域呢,或者说这个数据点书附加的含义是什么呢,我们可以根据前面的学习得到的直线来判断,比如这些点代表学生的平时成绩(y轴, x2),考试成绩(x轴,x1),这个时候我们吧(8,5)点带入学习的模型中(前面通过学习得到的直线),模型会返回给我们的结果是大于零还是小于零,大于零则改点在直线上方,表示被录取,小于零则在直线的下方,表示被拒绝,这个就是最简单的神经网络,线性界限,使用一条直线就能得到我们想要的结果
该直线可表示为
$ Wx + b = 0 $
$ w_1x_1 + w_2x_2 +b = 0 $
W =
(
w
1
,
w
2
)
(w_1, w_2)
(w1,w2) x = (x_1, x_2)
y = label : 0 or 1; 0表示被拒绝,1表示被录取
三维度的界限问题
现在我们离开二维世界,进入到三维的世界中,这个时候我们遇到的数据点多了一个维度,就想上面的成绩中我们加入了等级,那么这些点就搞成了空间中的一个面,我们要做的就是找到一个面来区分这些空间中的点构成的面
该面可表示为
$ Wx + b = 0 $
$ w_1x_1 + w_2x_2 +b = 0 $
W =
(
w
1
,
w
2
)
(w_1, w_2)
(w1,w2) x = (x_1, x_2)
y = label : 0 or 1; 0表示被拒绝,1表示被录取
二维的分类界限是一个直线,在三维中是一个面,那么有没有更高的维度呢。答案是有的,只不过是数据特征增多了,但是在三维以上的空间中示意图怎么画,我也不知道,如下图中我们可以知道,在n维空间中,我们要找到n-1维的空间来实现分类问题
感知器
我们上面的线性关系是将多个输入转换成输出一个输出,这个功能我们可以理解为感知器。这个感知器通过阶跃函数,如果大于0(在直线的上方)输出1,小于0(在直线的下方)就输出0,该感知器负责将输入数据转换为输出数据,其实跟我们上面提到的训练好的模型,他可以进行预测,图中每一个大圆圈就代表一个感知器
感知器技巧
我们知道了感知器其实就是一个隐藏层的线性关系方程,我们可以通过观察得到大致的线性方程,但是计算机不能通过观察得到,所以我们需要一个方法让计算机自己找到这个方程的参数
首先我们可以先随机设置参数,得到一个初始的线性方程,虽然这个方程开始的预测非常不准确,但是经过训练逐渐改善方程的权重
感知器步骤如下所示。对于坐标轴为 (p,q) 的点,标签 y,以及等式
y
^
=
s
t
e
p
(
w
1
x
1
+
w
2
x
2
+
b
)
\hat{y} = step(w_1x_1 + w_2x_2 + b)
y^=step(w1x1+w2x2+b)
- 如果点分类正确,则什么也不做。
- 如果点分类为正,但是标签为负,则分别减去
α
\alpha
αp,
α
\alpha
αq, 和
α \alpha α至 w 1 , w 2 w_1, w_2 w1,w2, b - 如果点分类为负,但是标签为正,则分别将 α \alpha αp, $ \alpha$q, 和 α \alpha α 加到 w 1 , w 2 w_1, w_2 w1,w2, b
我们现在假设有一条直线 3x + 4y -10 = 0红色直线,和一个点(4,5),学习速率为0.5 并且这个点的标签为负,如图点在直线的上面,这个方程将点分类为正,符合第二条规则,并做出计算的到第二条直线x+1.5y + 10.5 = 0,蓝色直线,
误差函数
在上一节我们看到,在初始化一条直线后,在评估一个点的时候会和我们真实值之间有差距,这个差距就是误差,我们需要找到一个能表示评估值和真实值之间差距的函数,我们根据这个误差函数来慢慢修正我们的分类函数的权重
误差函数可以告诉我们当前与正确答案之间的差别有多大,只有知道了误差,我们才能知道接下来该怎么做
误差函数和梯度下降
我们知道了误差函数的作用,就是表示真实值和预测值之间的差距,我们想要的是怎么将这个误差减到最小,上面是简单的线性问题,如果是复杂的非线性问题,我们该怎么做呢?我们需要对误差函数求导数,当导数为0的时候可以得到误差函数的极大值和极小值,我们希望的是极小值,具体的梯度下降见深度学习–3.梯度下降推导
激活函数 – sigmoid 函数
sigmoid用于二元分类激活函数,我们前面讲的都是的输出0或1的线性方程,但是如果我们要预测结果的概率,这个即使连续的问题,我们需要将阶跃函数变为S函数
激活函数sigmoid:
σ
(
x
)
=
1
1
+
e
−
x
\sigma(x) = \frac{1}{1+e^{-x}}
σ(x)=1+e−x1
图像为下图
激活函数 – Softmax 函数
softmax用于多元分类的激活函数
Softmax 是将一个事件可能有很多种情况的的每一种情况转换为概率,并且每一种情况的概率之和为1。
我们的想法是一种情况的得分除以所有情况的总分和,如图,但是这样有缺点,就是如果有的得分是负数,会出现除以0的情况
所以我们的想办法消除负数的结果,那么
e
x
e^x
ex函数可以消除负数的结果,所以想将每个输出结果作为
e
x
e^x
ex函数的输入,得到输出结果在使用上面的公式
激活函数的选择
- 当我们想要的结果为二元结果的时候,那么我们应该选择sigbmad激活函数(s),但是在这种二元情况,tanh会比s函数效果好很多。
- 当我们其他情况我们会选择线性修正单元(ReLU)
线性回归
在上面我们讲的是分类问题,我们这里讲的是线性拟合问题,在二维空间中我们想找到这样一条直线,空间中的点可以尽量多的在直线上或里直线最近,在三维空间中找到一个面,空间中的点可以尽量多的分布在这个面上,或里面的距离尽量小
具体的线性回归参见 深度学习–2.线性回归,可以先理解以一下误差函数的简单实现方式
最大似然率
在预测的模型中,我们最终要使用概率来表示预测结果的正确性,在预测完全部的数据后,我们要做的就是选出实际情况对应概率最大模型,就是全部情况判断正确的概率的乘积,叫做最大似然率
在左边的图中,在蓝色区域内与一个红点被判断为了蓝色,但是他确实红色的点,所以其判断正确的概率是0.1,因此,左边图的最大似然率是0.6 * 0.2 * 0.1 * 0.7 = 0.0084。因此右边的图最大似然率为0.3024,所以,右边的模型更好
更准确的模型可以提供更高的概率,
- 那么问题来了,如何最大化概率呢?那如果你还记得之前提到的误差函数,以及最少化误差函数可以获得最佳解决方案。
- 那么我们能否通过概率获得误差函数么?
- 最大化概率是否就等价于最小化误差函数?
交叉熵
在最大似然率
中,我们通过相乘的方式得到全部判断正确的概率, 但是如果上千个概率相乘,那么得到的结果会非常小,几乎接近与0,那么我们有什么办法将乘积转换为和呢,有的,我们是用 对数函数(log)–(log(ab) = log(a) + log(b)),如下图,对概率取对数后在再取绝对值,因为概率本身就是小数,小数的对数是负数。因此我们取概率的对数的绝对值后相加,得到的结果就是交叉熵,根据图中可以得知,交叉熵越大,模型越差,交叉熵越小,模型越好
这种方法比我们想象的还要强大,如果我们计算出概率,并且得到每个点所对应的对值,那我们实际上得到了每个点的误差,我们可以将分类正确概率的对数取相反数后的数字作为误差,
- 那么分类正确的点误差较小 -ln(0.6) = 0.51,
- 分类错误的点误差很大 -ln(0.2) = 1.61
因此交叉熵可以告诉我们模型的好坏,那么现在我们的目标从最大化概率转变为了最小化交叉熵 我们所寻找的误差函数就是这个交叉熵
事件和概率的对应关系和交叉熵:事件发生的概率越大,交叉熵越小,事件发生的概率越小,交叉熵越大
交叉熵公式
C
r
o
s
s
−
E
n
t
r
o
p
y
=
−
∑
i
=
1
m
y
i
ln
(
P
i
)
+
(
1
−
y
i
)
ln
(
1
−
P
i
)
Cross-Entropy = - \sum_{i=1}^{m} yi\ln(Pi) + (1-yi)\ln(1-Pi)
Cross−Entropy=−i=1∑myiln(Pi)+(1−yi)ln(1−Pi)
- Pi表示第i个事件配预测结果的概率
- yi表示第i个事件真实的结果
- -np.sum(Y * np.log§ + (1 - Y) * np.log(1 - P))
公式理解 - 当事件为门1和门2的时候,我们希望门后有礼物的概率很大,这个就对应交叉熵的第一部分,表示有门后礼物的事件 y 1 和 y 2 y_1和y_2 y1和y2为1,那么他们对应的概率 p 1 和 p 2 p_1和p_2 p1和p2越接近1越好,对应的交叉熵就越小,也就是误差越小,反之亦然。
- 再看看门3,门后有礼物的概率为0.1,那么我们不希望门后有礼物,门后有礼物的事件发生的概率越低越好,那么就对应交叉熵公式的第二部分, y 3 y_3 y3为0,那么p3越小,交叉熵就越小,误差就越小
梯度下降推导
我们有了上面的误差函数,就说明我们有了评判模型预测结果的好坏的标准,那当我们知道了结果的好坏后,我们怎么将这个预测的结果和真实值之间的偏差告诉模型,让模型来修改参数呢?我们知道,训练是一个渐进的过程,也就是说我们需要很多数据来训练模型,并且要使用这些数据反复训练很多次,训练一次我们叫做一个训练周期,可以理解为我们要背诵一首古诗,我们要背很多遍才能背的很熟练,我们每背诵一遍就对古诗的印象更深刻,这个影响更深刻的过程,就是我们改善模型参数的过程。对于训练模型,我们每训练一个周期,我们将全部数据的总误差的平均值添加到我们的参数上去,这里说的参数可以理解为神经网络中方程的权重,那我们是将权重加上误差还是减去误差呢?那得看误差函数对单个参数求偏导后的结果是怎么样的,具体推导可以看下面的链接,一个是线性回归中的平均平方误差函数的梯度下降的推导,一个是交叉熵误差函数的梯度下降推导 梯度下降推导
神经网络结构
我们知道了线性分类,就是找到一条直线,分类不同的点(二元分类),那当一条直线不能进行很好的分类的时候呢?我们可以尝试使用多条直线组合成曲线来进行分类,那么当一个点同时属于两条直线的分类范围的时候呢?就应该看这个点更靠近哪一条直线,使用权重,得到新的概率后使用 sigmoid 激活函数,得到新的概率
图中5和-2组成一条直线L1,7和3组成第二条直线L2, 7和5组成第三条直线L3,L1和L2的输出为L3的输入,这样L1和L3的输出作为L3的输入,然后配上合适的权重7和5就就构成了第三条直线,从图形上看,我们可以理解为我们取了L1的一部分和L2的一部分,构成了图右边的曲线,这就是简单的神经网络结构,如果增加输入维度,增多隐藏层线性方程,那么神经网络的深度就加深
多类别分类
我们在上面得知了二元分类问题,神经网络最后得到一个结果,那加入我们的结果是多元的呢,比如我们的结果是从鸭子,海狸,海象三个中选择一个,我们就在输出端添加更多节点,每个输出节点就输出一个结果,这三个节点的结果之和为1,我们从这三个结果中选择一个最大的作为我们的模型的预测结果,这输出端的激活函数就是 SoftMax
前向反馈
现在我们有一个合适的直线权重为w1和w2,偏差为b,并且有一个点的坐标为(x1, x2),标签为1,如下图,得到的点的位置,经过该网络,最后经过激活函数,我们会得到该点为蓝色区域的概率,这个过程就叫做前向反馈,也就是在已知的模型下,输入我们的需要预测的数据,得到预测概率
注意,这个模型不是太好
我们先在用矩阵的方式表示,如下图
我们知道神经网络可以看成由诸多的线性方程组和成的,那么我们可以将每一层的方程的权重集合寄来构成矩阵,对数据进行矩阵乘法效率会高很多
如图中上标为1的是第一层网络的权重,上标为2表示第二层的权重,矩阵
W
1
W^{1}
W1的行表示关于
x
n
x_n
xn的所有权重,列表是一个节点方程关于所有输入变量的相应的权重
关于矩阵乘法部分,W1是一个 3x2 的矩阵,x是 3x1 矩阵,无法直接相乘。w1.T*x. 这里.T表示转置, w1在转后,行表示一个方程的对于所有输入的权重,可以立即为一行就是一个方程
所以这个简单的神经网络的向前反馈的公式方程为
y ^ = σ ( w 2 σ ( w 1 ∗ x ) ) \hat{y} = \sigma (w2 \sigma (w1 * x)) y^=σ(w2σ(w1∗x))
反向传播
现在,我们准备好训练神经网络了。为此,我们将使用一种方法,叫做反向传播。简而言之,反向传播将包括:
- 进行前向反馈运算。
- 将模型的输出与期望的输出进行比较。
- 计算误差。
- 向后运行前向反馈运算(反向传播),将误差分散到每个权重上。
- 更新权重,并获得更好的模型。
- 继续此流程,直到获得很好的模型
我们可以将这个流程称之为梯度下降
首先我们随机设置权重,根据各层的线性方程得到最后的预测值,并且预测值是根据各层的每个权重
w
i
w_i
wi有关
y
^
=
σ
(
w
2
σ
(
w
1
∗
x
)
)
\hat{y} = \sigma (w2 \sigma (w1 * x))
y^=σ(w2σ(w1∗x))
然后根据交叉熵得到误差函数公式,我们根据误差函数的大小来评判结果的好坏,当误差公式的结果越小,则预测就越接近真实值,于是我们对误差函数对每一个权重w求偏导,得到W的偏导数矩阵。
只有当偏导数为0的时候误差达到最小(根据导数的性质,当导数为0的时候有极大值或极小值),我们根据
w : = w − α ϑ J ( w , b ) ϑ w ; b : = b − α ϑ J ( w , b ) ϑ b w := w - \alpha \frac{\vartheta J(w, b)}{\vartheta w} ; b := b- \alpha \frac{\vartheta J(w, b)}{\vartheta b} w:=w−αϑwϑJ(w,b);b:=b−αϑbϑJ(w,b)
反向修改w的值,然后再次根据新的权重去预测,在计算误差值,继续反向转播,知道误差达到我们预设的范围内
整个过程就像下图,
- 先预测点的结果,
- 然后根据点的预测结果和真实值相比较,是想让来两条线是靠近点还是远离点
- 求误差对每一个权重的偏导数,根据偏导数修改权重和偏差
- 使用新的权重重新预测,如此循环