Machine Learning L7~L9

本文深入探讨了深度学习原理,讲解神经网络结构与反向传播算法,解析梯度消失及爆炸问题,提供解决策略,如ReLU激活函数和优化梯度下降方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Lecture7: Backpropagation

接着上一课Logistic Regression,这一课在逻辑回归基础上建立了神经网络,neural network。如下,框框里面就是一个逻辑回归。层数多了就是Deep Learning。
在这里插入图片描述
和机器学习的步骤基本完全相同,只是第一步选取function set选为神经网络,deep learning步骤如下:
step1: neural network
step2: goodness of function
step3: pick the best function
Neural Network说到底就是matrix的运算,有种嵌套的感觉。
a 1 = σ ( ω 1 x + b 1 ) a_1=\sigma(\omega^1x+b^1) a1=σ(ω1x+b1)—> a 2 = σ ( ω 2 a 1 + b 2 ) a_2=\sigma(\omega^2a^1+b^2) a2=σ(ω2a1+b2)—> a 3 = σ ( ω 3 a 2 + b 3 ) a_3=\sigma(\omega^3a^2+b^3) a3=σ(ω3a2+b3)
y = σ ( ω l a l − 1 + b l ) y=\sigma(\omega^la^{l-1}+b^l) y=σ(ωlal1+bl)<=> y = f ( x ) y=f(x) y=f(x)
在这里插入图片描述
Step1需要做的就是选取这个神经网络的大概结构,比如有多少层,是不是fully-connected(点对点),有没有maxpolling层,softmax还是ReLu等。

Step2: goodness of function -->Gradient Descent
既然选取完神经网络模型之后,就要判断这个模型是否好,并选取最佳模型。还是得用到之前的梯度降落,但是之前只有一个neural,现在能有几百个,每个neural有十几个参数,那算下来能有成千上万个参数了。
有效的方法? Backpropagation反向传播 :单个样本的loss function对参数的导数
链式法则:之后的逆向推导会用到
在这里插入图片描述
BP算法需要了解以下Forward Pass向前传播和Backward Pass反向传播。
Forward Pass:
compute ∂ z ∂ ω \frac{\partial z}{\partial \omega} ωzfor all parameters
在这里插入图片描述
是从前往后的一种算法,一层network一层的往里,依次算出所有的z值,最后到y值。
Backward Pass
compute ∂ c ∂ z \frac{\partial c}{\partial z} zcfor all activation function inputs z z z.
在这里插入图片描述
带入到前面的式子:
∂ c ∂ z = σ ′ ( z ) [ ω 3 ∂ c ∂ z ′ + ω 4 ∂ c ∂ z ′ ′ ] \frac{\partial c}{\partial z}=\sigma&#x27;(z)[\omega_3\frac{\partial c}{\partial z&#x27;}+\omega_4\frac{\partial c}{\partial z&#x27;&#x27;}] zc=σ(z)[ω3zc+ω4zc]这就是bp算法的核心。
一个好的理解(copy):
BackPropagation算法是多层神经网络的训练中举足轻重的算法。简单的理解,它的确就是复合函数的链式法则,但其在实际运算中的意义比链式法则要大的多。需要先直观理解多层神经网络的训练。

机器学习可以看做是数理统计的一个应用,在数理统计中一个常见的任务就是拟合,也就是给定一些样本点,用合适的曲线揭示这些样本点随着自变量的变化关系.
在这里插入图片描述
对应表达式为:
在这里插入图片描述深度学习同样也是为了这个目的,只不过此时,样本点不再限定为(x, y)点对,而可以是由向量、矩阵等等组成的广义点对(X,Y)。而此时,(X,Y)之间的关系也变得十分复杂,不太可能用一个简单函数表示。然而,人们发现可以用多层神经网络来表示这样的关系,而多层神经网络的本质就是一个多层复合的函数。借用网上找到的一幅图[1],来直观描绘一下这种复合关系。和直线拟合一样,深度学习的训练也有一个目标函数,这个目标函数定义了什么样的参数才算一组“好参数”,不过在机器学习中,一般是采用成本函数(cost function),然后,训练目标就是通过调整每一个权值Wij来使得cost达到最小。cost函数也可以看成是由所有待求权值Wij为自变量的复合函数,而且基本上是非凸的,即含有许多局部最小值。但实际中发现,采用我们常用的梯度下降法就可以有效的求解最小化cost函数的问题。

梯度下降法需要给定一个初始点,并求出该点的梯度向量,然后以负梯度方向为搜索方向,以一定的步长进行搜索,从而确定下一个迭代点,再计算该新的梯度方向,如此重复直到cost收敛。那么如何计算梯度呢?
假设我们把cost函数表示为 H ( W 11 , W 12 , ⋯ , W i j , ⋯ , W m n ) H(W11,W12,⋯,Wij,⋯,Wmn) H(W11,W12,,Wij,,Wmn)
,那么它的梯度向量[2]就等于 ∇ H = ∂ H ∂ W 11 e 11 + . . . + ∂ H ∂ W m m e m n ∇H=\frac{∂H}{\partial W_{11}}e_{11}+...+\frac{\partial H}{\partial W_{mm}}e_{mn} H=W11He11+...+WmmHemn
, 其中 e i j eij eij表示正交单位向量。为此,我们需求出cost函数H对每一个权值 W i j Wij Wij的偏导数。而BP算法正是用来求解这种多层复合函数的所有变量的偏导数的好方法。

我们以求e=(a+b)*(b+1)的偏导[3]为例。
它的复合关系画出图可以表示如下:
在这里插入图片描述在图中,引入了中间变量c,d。
为了求出a=2, b=1时,e的梯度,我们可以先利用偏导数的定义求出不同层之间相邻节点的偏导关系,如下图所示。
在这里插入图片描述
利用链式法则:
∂ e ∂ a = ∂ e ∂ c ⋅ ∂ c ∂ a 以 及 ∂ e ∂ b = ∂ e ∂ c ⋅ ∂ c ∂ b + ∂ e ∂ d ⋅ ∂ d ∂ b \frac{\partial e}{\partial a}=\frac{\partial e}{\partial c}\cdot \frac{\partial c}{\partial a}以及\frac{\partial e}{\partial b}=\frac{\partial e}{\partial c}\cdot \frac{\partial c}{\partial b}+\frac{\partial e}{\partial d}\cdot \frac{\partial d}{\partial b} ae=ceacbe=cebc+debd
链式法则在上图中的意义是什么呢?其实不难发现, ∂ e ∂ a \frac{∂e}{∂a} ae的值等于从a到e的路径上的偏导值的乘积,而 ∂ e ∂ b \frac{∂e}{∂b} be的值等于从b到e的路径 1 ( b − c − e ) 1(b-c-e) 1(bce)上的偏导值的乘积加上路径 2 ( b − d − e ) 2(b-d-e) 2(bde)上的偏导值的乘积。也就是说,对于上层节点p和下层节点q,要求得 ∂ p ∂ q \frac{∂p}{∂q} qp,需要找到从q节点到p节点的所有路径,并且对每条路径,求得该路径上的所有偏导数之乘积,然后将所有路径的 “乘积” 累加起来才能得到 ∂ p ∂ q \frac{∂p}{∂q} qp的值。

这样做是十分冗余的,因为很多路径被重复访问了。比如上图中,a-c-e和b-c-e就都走了路径c-e。对于权值动则数万的深度模型中的神经网络,这样的冗余所导致的计算量是相当大的。

同样是利用链式法则,BP算法则机智地避开了这种冗余,它对于每一个路径只访问一次就能求顶点对所有下层节点的偏导值。 正如反向传播(BP)算法的名字说的那样,BP算法是反向(自上往下)来寻找路径的。

从最上层的节点e开始,初始值为1,以层为单位进行处理。对于e的下一层的所有子节点,将1乘以e到某个节点路径上的偏导值,并将结果“堆放”在该子节点中。等e所在的层按照这样传播完毕后,第二层的每一个节点都“堆放”些值,然后我们针对每个节点,把它里面所有“堆放”的值求和,就得到了顶点e对该节点的偏导。然后将这些第二层的节点各自作为起始顶点,初始值设为顶点e对它们的偏导值,以”层”为单位重复上述传播过程,即可求出顶点e对每一层节点的偏导数。

以上图为例,节点c接受e发送的1x2并堆放起来,节点d接受e发送的1x3并堆放起来,至此第二层完毕,求出各节点总堆放量并继续向下一层发送。节点c向a发送2x1并对堆放起来,节点c向b发送2x1并堆放起来,节点d向b发送3x1并堆放起来,至此第三层完毕,节点a堆放起来的量为2,节点b堆放起来的量为21+31=5, 即顶点e对b的偏导数为5.

举个不太恰当的例子,如果把上图中的箭头表示欠钱的关系,即c→e表示e欠c的钱。以a, b为例,直接计算e对它们俩的偏导相当于a, b各自去讨薪。a向c讨薪,c说e欠我钱,你向他要。于是a又跨过c去找e。b先向c讨薪,同样又转向e,b又向d讨薪,再次转向e。可以看到,追款之路,充满艰辛,而且还有重复,即a, b 都从c转向e。

而BP算法就是主动还款。e把所欠之钱还给c,d。c,d收到钱,乐呵地把钱转发给了a,b,皆大欢喜。

Lecture 8:keras小用法

对于初学者来说,keras真的非常友善了,简单易懂又很强大,非常符合建立神经网络的正向思维。几分钟就能搭建好一个network。
1. define a set of function

model = Sequential()              
#先宣告一个model,下面决定长什么样
-------------------------------------------------------
model.add(Dense(input_dim = 28*28, output_dim = 500))
# dense表示Fully-connected layer,当然也可以改为convolution(只有有project详解)
# 输入为28*28的vector,输出为500个neural。
model.add(Activation('sigmoid'))
# 用sigmoid当作activation function
------------------------------------------------------
model.add(Dense(output_dim = 500))
# 输出为500个,input是上一层输出,所以不用input
model.add(Activation('sigmoid'))
------------------------------------------------------
model.add(Dense(output_dim = 10))
# output设为10维
model.add(Activation('Softmax'))

2. goodness of function (training 部分)

model.compile(loss ='categorical crossentropy', optimizer = 'adam', metrics = ['accuracy'])
# 这部分是先选取了损失函数loss function为交叉熵,然后求最佳解的方式为adam,最后用accuracy显示。

3. pick the best function
Find the optimal network parameters

model.fit(x_train, y_train, batch-size = 100, nb_epoch = 20)
# x_train, y_train每个都是2维的,除了参数,还有number of examples.
# batch_size 告诉keras一个batch有多大,一次有多少个样本,每个batch是一个轮回training
# 当batch_size = 1 ---> stochastic gradient descent
# nb_epoch ---> 总共update多少次batch

4. testing part
这一部分,就是要验证我们选择的model是否是好的,正确率是否大,error是否小。
case1:

score = model.evaluate(x_test, y_test)
print('total loss on test set:', score[0])
print('accuracy of testing set:', score[1])
# 计算这个test的正确率

case2:

result = model.predict(x_test)
# 计算分类结果

Lecture9: Tips for training DNN

  1. 没办法在training set上给出好的正确率
  2. training set上给你好结果,testing set上结果很差。
  3. 需要修改前面的参数才能给出好结果。
    在这里插入图片描述
1.vanishing gradient problem and exploding gradient problem

梯度消失
在神经网络中,当前面隐藏层的学习速率低于后面隐藏层的学习速率,即随着隐藏层数目的增加,分类准确率反而下降了。这种现象叫做消失的梯度问题。

通俗的说,不同的层学习的速度差异很大,表现为网络中靠近输出的层学习的情况很好,靠近输入的层学习的很慢,有时甚至训练了很久,前几层的权值和刚开始随机初始化的值差不多。因此,梯度消失、爆炸,其根本原因在于反向传播训练法则,属于先天不足。

两种情况下梯度消失经常出现,一是在深层网络中,二是采用了不合适的损失函数,比如sigmoid。梯度爆炸一般出现在深层网络和权值初始化值太大的情况下,下面分别从这两个角度分析梯度消失和爆炸的原因。

1.1 深层网络角度 (copy)
在这里插入图片描述
图中是一个四层的全连接网络,假设每一层网络激活后的输出为 f i ( x ) f_i(x) fi(x),其中 i i i为第 i i i层, x x x代表第 i i i层的输入,也就是第 i − 1 i−1 i1层的输出, f f f是激活函数,那么,得出 f i + 1 = f ( f i ∗ w i + 1 + b i + 1 ) f_{i+1}=f(fi∗wi+1+bi+1) fi+1=f(fiwi+1+bi+1),简单记为 f i + 1 = f ( f i ∗ w i + 1 ) f_{i+1}=f(fi∗wi+1) fi+1=f(fiwi+1)

BP算法基于梯度下降策略,以目标的负梯度方向对参数进行调整,参数的更新为 w ← w + Δ w w \leftarrow w+\Delta w ww+Δw,给定学习率 α \alpha α,得出 Δ w = − α ∂ L o s s ∂ w \Delta w=-\alpha \frac{\partial Loss}{\partial w} Δw=αwLoss。如果要更新第二隐藏层的权值信息,根据链式求导法则,更新梯度信息: Δ ω 2 = ∂ L o s s ∂ ω 2 = ∂ L o s s ∂ f 4 ⋅ ∂ f 4 ∂ f 3 ⋅ ∂ f 3 ∂ f 2 ⋅ ∂ f 2 ∂ ω 2 \Delta\omega_2=\frac{\partial Loss}{\partial \omega_2}=\frac{\partial Loss}{\partial f_4}\cdot\frac{\partial f_4}{\partial f_3}\cdot\frac{\partial f_3}{\partial f_2}\cdot\frac{\partial f_2}{\partial\omega_2} Δω2=ω2Loss=f4Lossf3f4f2f3ω2f2,很容易看出来 ∂ f 2 ∂ ω 2 = ∂ f ∂ ( f 1 ∗ ω 2 ) f 1 \frac{\partial f_2}{\partial \omega_2}=\frac{\partial f}{\partial(f_1 * \omega_2)}f_1 ω2f2=(f1ω2)ff1,即第二隐藏层的输入。所以说, ∂ f 4 ∂ f 3 \frac{∂f_4}{∂f_3} f3f4就是对激活函数进行求导,如果此部分大于1,那么层数增多的时候,最终的求出的梯度更新将以指数形式增加,即发生梯度爆炸,如果此部分小于1,那么随着层数增多,求出的梯度更新信息将会以指数形式衰减,即发生了梯度消失
1.2 激活函数角度
上文中提到计算权值更新信息的时候需要计算前层偏导信息,因此如果激活函数选择不合适,比如使用sigmoid,梯度消失就会很明显了,原因看下图,如果使用sigmoid作为损失函数,其梯度是不可能超过0.25的,这样经过链式求导之后,很容易发生梯度消失,sigmoid函数数学表达式为: s i g m o i d ( x ) = 1 1 + e ( − x ) sigmoid(x)=\frac{1}{1+e^(-x)} sigmoid(x)=1+e(x)1
在这里插入图片描述
解决方案:
替换激活方差Activation Function
1.2.1 Rectified Linear Unit(ReLU)
思想很简单,如果激活函数导数为1,那么就不存在梯度消失爆炸的问题了,每一层的网络都可以得到相同的更新了。
在这里插入图片描述
其导数图像为:
在这里插入图片描述
从上图中,我们可以很容易看出,relu函数的导数在正数部分是恒等于1的,因此在深层网络中使用relu激活函数就不会导致梯度消失和爆炸的问题。

ReLU的优点:

  1. 解决了梯度消失,爆炸问题。
  2. 计算方便且快。
  3. 加速了网络的训练。
  4. 解决了梯度消失

ReLU的缺点:

  1. 由于附属部分恒为0,会导致一些神经元无法激活(小学习率解决)。
  2. 输出不是以0为中心。
  3. 变成linear?可是我们需要nonlinear。

ReLU— Variant
leakrelu就是为了解决relu的0区间带来的影响,其数学表达为: l e a k r e l u = m a x ( k ∗ x , x ) leakrelu=max(k∗x,x) leakrelu=max(kx,x)其中k是leak系数,一般选择0.01或者0.02,或者通过学习而来。
leakrelu解决了0区间带来的影响,而且包含了relu的所有优点在这里插入图片描述
1.2.2 Maxout
与常规激活函数不同的是,maxout是一个可学习的分段线性函数.
然而任何一个凸函数,都可以由线性分段函数进行逼近近似。其实我们可以把以前所学到的激活函数:ReLU、激活函数,看成是分成两段的线性函数。

此部分没理解,后面会开专题。
https://blog.youkuaiyun.com/hjimce/article/details/50414467

2. Gradient descent的优化

Review of Adaptive Learning Rate
point是说如果有两个方向,一个梯度大的会给小的learning rate, 一个gradient小的会给大的learning rate。

ω t + 1 \omega^{t+1} ωt+1<— ω t − η ∑ i = 0 t g t \omega^t-\frac{\eta}{\sqrt{\sum_{i=0}^{t}}}g^t ωti=0t ηgt

可见分子是用来抑制过快获得增长过慢的,但更多情况是error surface更加复杂呢?

进阶版:RMSProp
RMSprop是Geoff Hinton提出的一种自适应学习率方法。Adagrad会累加之前所有的梯度平方,而RMSprop仅仅是计算对应的平均值,因此可缓解Adagrad算法学习率下降较快的问题。

优化方法后面会开专题总结。

若在Training data 上的结果很好,Testing data上的不好怎么办?

1. Early Stopping
在这里插入图片描述
2. Regularization
L1和L2正则
在这里插入图片描述
在这里插入图片描述
3. Dropout
每次更新参数之前,对每个neural(包括input)做sampling,每个neural有一定的几率被丢掉,最后变成细长的network。
Training的时候需要dropout,testing时候不需要dropout,但是要multiply ( 1 − p ) (1-p) (1p)%


Supervised Learning还剩下CNN没有总结,不过会单独开一个CNN的专题总结。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值