秋招材料整理——深度学习基础

目录

    • 一、多任务计算
    • 二、归一化、标准化normalize
    • 三、激活函数:ReLU
    • 四、梯度优化
    • 五、梯度下降法 vs. 牛顿法
    • 六、过拟合、欠拟合的起因,怎么解决
    • 七、Batch Normalization批数据的规范化
    • 八、梯度弥散/爆炸
    • 九、dropout (全连接层)
    • 十、tensorflow:Graph、Operation、Tensor、Session

一、多任务计算

共享隐层, 多个任务并行训练并共享不同任务已学到的特征表示
(1)交替训练:不同任务,不同的数据集,一次优化一层,每层都有一个loss,一个optimiser
(2)联合训练:不同任务,相同的数据集,一次优化一层,每层都有一个loss,loss相加,一共一个optimiser

二、归一化、标准化normalize

  • 目的
    ①把特征的各个维度标准化到特定的区间
    ②把有量纲表达式变为无量纲表达式(去除数据的单位限制)
  • 好处
    ①加快梯度下降求最优的速度,各维度取值范围差别越大,椭圆等高线会越狭长。由于梯度方向垂直于等高线方向,此时优化路线会较为曲折,迭代会很慢
    ②提升模型精度,不归一化会突出数值较高的指标的作用
  • 方法
    (1)极差变换: (不涉及距离、协方差,数据不符合正态分布时)
    y i = x i − m i n ( x ) m a x ( x ) − m i n ( x ) y_i=\frac{x_i-min(x)}{max(x)-min(x)} yi=max(x)min(x)ximin(x)
    (2)0均值标准化变换: (标准差)(用到距离时,PCA降维时)
    y i = x i − m e a n ( x ) σ y_i=\frac{x_i-mean(x)}{\sigma} yi=σximean(x)

三、激活函数:ReLU

  • 作用:提高网络的分类能力

(1)sigmoid y ( z ) = 1 1 + e − z , z = ∑ w i x i + b y(z) = \frac{1}{1+e^{-z}}, z = \sum w_ix_i+b y(z)=1+ez1,z=wixi+b

  • 缺点:
    ①要么接近于0,要么接近于1,会导致BP时出现梯度趋0的问题,发生梯度弥散
    ②输出不是关于原点中心对称的,收敛速度会变得很慢(如果输入是正的,w的梯度要么全正,要么全负)
    ③计算很耗时

(2)tanh t a n h ( x ) tanh(x) tanh(x):(sigmoid图像下移0.5)解决sigmoid不关于原点对称

  • 缺点:梯度仍然会发生饱和,引起梯度弥散

(3)ReLU修正线性单元(Rectified linear unit)(常用): m a x ( 0 , x ) max(0,x) max(0,x)

  • 优点:
    1)前向反向计算都非常快,收敛速度快
    2)不容易发生梯度弥散/爆炸问题(梯度>1,爆炸;<1,弥散)
  • 缺点:
    1)输出不是关于原点中心对称的
    2)dead ReLU:永远不会被激活,参数不会更新,造成数据多样性的丢失不可逆转
    ①表现:网络在训练一段时间后,loss依然很大,且持续不变
    为什么刚开始loss可以下降一部分,但是后来不行了?
    刚开始你的 w e i g h t > 0 weight>0 weight>0,但梯度也 > 0 >0 >0,几次训练后, w e i g h t − 学 习 率 ∗ 梯 度 < 0 weight - 学习率*梯度<0 weight<0
    ②通常在两种情况下发生:
    1)初始化ReLU时,把权重设置成了不能使神经元激活的数值,导致神经元不会训练
    2)通常是学习率太高

(4)Leaky ReLU m a x ( α x , x ) max(αx, x) max(αx,x):修正dead ReLU
(5)ELU
f ( x ) = { x x > 0 α ( e x p ( x ) − 1 ) x < = 0 f(x)= \begin{cases} x& x>0\\ α(exp(x)-1)& x<=0 \end{cases} f(x)={xα(exp(x)1)x>0x<=0
继承了ReLU的优点,也不会有输出不是0中心的问题,会得到0均值的输出
(6)Maxout m a x ( w 1 T x + b 1 , w 2 T x + b 2 ) max(w_1^Tx+b_1,w_2^Tx+b_2) max(w1Tx+b1,w2Tx+b2)
不会出现神经元失活(dead),但参数太多

  • 为什么在CNN中将原先的sigmoid、tanh换成ReLU可以取得比较好的效果?
    sigmoid、tanh会导致梯度弥散问题,例如sigmoid的导数的取值范围是(0, 0.25],小于1的数乘在一起,越来越小。而ReLU的导数 ∈ 0 , 1 \in{0,1} 0,1,这样的话只要一条路径上的导数都是1,无论神经网络是多少层,这一部分的乘积都始终为1,因此深层的梯度也可以传递到浅层中。
  • 为什么在RNN中,将tanh换成ReLU不能取得类似的效果?
    1)在RNN中直接把激活函数换成ReLU会导致非常大的输出值:
    原始RNN表达式: a i = W f i − 1 + U x i + b i , f i = f ( a i ) a_i=Wf_{i-1}+Ux_i+b_i,f_i=f(a_i) ai=Wfi1+Uxi+bi,fi=f(ai),原始RNN在每个阶段都共享同一个参数W,假设从某一层开始 x i , b i x_i,b_i xibi都为0,则最后的输出就是 f ( W f ( W f ( … ) ) ) f(Wf(Wf(…))) f(Wf(Wf())),某种程度上相当于W做连乘,那么只要W有一个大于1的特征值,经过若干次连乘后都会导致一个非常大的矩阵;
    2)梯度爆炸:
    BP时,连乘的W越来越多,ReLU可以让梯度传递,后面就会导致梯度爆炸;而CNN上每一层使用的 W i W_i Wi不同并且是稀疏矩阵,很大程度上能抵消掉梯度爆炸的影响

四、梯度优化

(1)SGD:直接根据梯度校正W: x + = − η ∗ d x x+= -\eta*dx x+=ηdx
(2)momentum动量更新: v = α v − η ∗ d x , x + = v v=αv- \eta*dx,x+=v v=αvηdxx+=v
解决梯度高度敏感于参数空间某些方向的问题;
更新时在一定程度上保留之前更新的方向,同时利用当前梯度微调最终的更新方向
当前梯度与历史同向则增强,异向则减弱
(3)NAG(Nesterov Accelerated Gradient)(Nesterov momentum):
对我们预测的位置求梯度 v t = α v t − 1 − η ∗ d f ( x t − 1 + α v t − 1 ) , x t = x t − 1 + v t v_t=αv_{t-1}-\eta*df(x_{t-1}+αv_{t-1}),x_t =x_{t-1}+ v_t vt=αvt1ηdf(xt1+αvt1)xt=xt1+vt
(4)AdaGrad c a c h e + = d x 2 , x + = − η ∗ d x n p . s q r t ( c a c h e ) + 1 e − 7 cache += dx^2,x += \frac{-\eta*dx}{np.sqrt(cache)+1e-7} cache+=dx2x+=np.sqrt(cache)+1e7ηdx
自适应学习率,每个维度都不一样,梯度大的方向因为除的数越来越大而使步长变得越来越小,梯度小的越来越大;深度太大的时候,分母=0,x不再变化,结束训练
(5)RMSProp:解决提前结束的问题
c a c h e = α ∗ c a c h e + ( 1 − α ) ∗ d x 2 cache = \alpha * cache + (1- \alpha) * dx^2 cache=αcache+(1α)dx2,# α \alpha α衰减率
x + = − η ∗ d x n p . s q r t ( c a c h e ) + 1 e − 7 x += \frac{-\eta*dx}{np.sqrt(cache)+1e-7} x+=np.sqrt(cache)+1e7ηdx
(6)adam:RMSProp +momentum(β超参,t时间步长)
m = β 1 ∗ m + ( 1 − β 1 ) ∗ d x m = β_1 * m + (1-β_1)*dx m=β1m+(1β1)dx #动量,梯度的一阶矩
m / = 1 − β 1 t m /= 1-β_1^t m/=1β1t #偏置校正,一种针对m、v初始为0的补偿措施,在开始时把m、v变大
v = β 2 ∗ v + ( 1 − β 2 ) ∗ d x 2 v = β_2 * v + (1-β_2)*dx^2 v=β2v+(1β2)dx2 #二阶矩
v / = 1 − β 2 t v /= 1-β_2^t v/=1β2t
x + = − η ∗ m n p . s q r t ( v ) + 1 e − 7 x += \frac{-\eta*m}{np.sqrt(v)+1e-7} x+=np.sqrt(v)+1e7ηm
哪种更好?哪种都不好。应该开始阶段使用高学习率,后面降低

五、梯度下降法 vs. 牛顿法

常用的两种凸函数求极值的方法

  • 梯度下降法:直接求解目标函数极小值
    θ j − = α ∂ ∂ θ j J ( θ ) \theta_j -=\alpha\frac{\partial}{\partial\theta_j}J(\theta) θj=αθjJ(θ)
    更新参数的方式为目标函数在当前参数取值下的梯度值,前面再加上一个步长α
    α:随着迭代次数不断减小,不能到0
  • 牛顿法:由泰勒展开得到,通过求解目标函数一阶导为零的参数值,进而求得最小值
    θ = θ − l ′ ( θ ) l ′ ′ ( θ ) = θ − H − 1 ∇ θ l ( θ ) \theta=\theta-\frac{l'(\theta)}{l''(\theta)}=\theta-H^{-1}\nabla_\theta l(\theta) θ=θl(θ)l(θ)=θH1θl(θ)
    牛顿法收敛速度比梯度下降法快,而且由于海森阵的逆在迭代中不断减小,起到逐渐缩小步长的效果。计算海森阵的逆比较困难,消耗时间和计算资源。

六、过拟合、欠拟合的起因,怎么解决

  • 过拟合:
    • 起因:
      1)数据集有问题,太少,噪音多等;或者训练集和测试集特征分布不一致
      2)模型对数据的拟合过于自信,非常完美的拟合上了所有数据(包括噪声)
    • 解决:
      1)清洗数据,增大数据的数据集
      2)正则化:保留所有的特征变量,但是会减小特征变量的数量级, 值越小,就越光滑,也就越简单
      L1更容易产生稀疏解,但不稳定;
      L2倾向于让参数趋于0,更小的参数意味着更低的复杂度
      3)交叉验证
      4)对神经网络:
      ①dropout:随机失活(把相应权重设为0),训练时让神经元以一定概率dead;在最后的全连接层前加一层Dropout,默认参数是0.5
      ②数据增强:平移、旋转、加噪、亮度改变、饱和度改变等
      ③BN:根据BN的论文来看,BN层是可以缓解过拟合问题的,而且还可以减小网络初始化、未归一化的影响。如果在归一化时因图像数量太大,没办法求得准确的标准差,可以尝试在网络的输入加一层BN。
      5)对树:剪枝(预剪枝、后剪枝)
    • 判断:
      1)训练准确率升高时测试准确率却在降低,两准确率差的特别多
      2)每训练一小段时间就做一次测试,如果多次发生测试精度下降,说明可能过拟合的趋势已经发生,停止训练,或还原测试前的状态,调整参数
      3)当训练集和测试集的误差收敛但却很高时,为高偏差;
      当训练集和测试集的误差之间有大的差距时,为高方差;
      当训练集的准确率比其他独立数据集上的测试结果的准确率要高时,一般都是过拟合;
      理想情况是是找到偏差和方差都很小的情况,即收敛且误差较小
  • 欠拟合
    • 起因:模型没有很好的捕捉到数据特征,不能很好地拟合数据
    • 解决:
      1)添加其他特征项
      2)添加多项式特征
      3)减少正则化参数

七、Batch Normalization批数据的规范化

  • 随着一层层隐层神经元非线性函数的处理,输入数据逐渐向取值区间内极度饱和的区域靠拢,这样在做BP时这些数据的梯度变化很慢,随着层数的增加还会导致梯度消失问题,BN做的就是把这些数据强制拉回到均值为0方差为1的正态分布中,让他们落入到对输入比较敏感的更线性一点的区域,增大导数值,增强BP信息流动性,加快收敛,也能避免梯度消失问题。
  • 在每一个维度执行规范化
    x ^ ( k ) = x ( k ) − E [ x ( k ) ] V a r [ x ( k ) ] \hat{x}^{(k)}=\frac{x^{(k)}-E[x^{(k)}]}{\sqrt{Var[x^{(k)}]}} x^(k)=Var[x(k)] x(k)E[x(k)]
  • 优点:①加快收敛,提升稳定性(下一层不用再学习输入数据中的偏移)
    ②对初始化要求就没那么高了,而且支持较大的学习率
  • 均值和方差怎么更新的(指数加权滑动平均)
    μ = α ∗ 以 前 的 μ + ( 1 − α ) ∗ 当 前 的 μ μ = \alpha *以前的μ + (1-α) * 当前的μ μ=αμ+1αμ (α指数衰减的参数),var同理
    模型训练好之后, predict时, BN 还是要计算 x − μ σ 2 + ϵ \frac{x-μ}{\sqrt{σ^2+ϵ}} σ2+ϵ xμ , 这时的μ 和 ϵ是基于整个训练集的,比较直接的方法是在训练集上重新计算,但数据特别多时,计算量大,BN就是训练时就把μ 和 ϵ计算出来了,是近似值,两个值在训练迭代过程中相当于是在不断的moving

八、梯度弥散/爆炸

  • 梯度弥散
    • 什么是梯度弥散:BP时链式法则中的累乘效应和极小梯度在传递链上的连续出现,导致梯度更新无法有效到达前面的网络层,前面层的参数也就无法更新,称梯度弥散(消失)
    • 解决:
      ①BN:把逐渐向取值区间内极度饱和区域靠拢的数据强制拉回到均值为0方差为1的正态分布中,让他们落入到对输入比较敏感的更线性一点的区域内,增大梯度,通过这种方法,在前传过程中消除梯度弥散
      ②shortcut/skip connection:在BP过程中更好地把梯度传到前面的层次中
  • 梯度爆炸
    • 什么是梯度爆炸:初始化权值过大,累乘后,梯度呈指数级增长
    • 解决:
      ①梯度剪切:设置一个梯度剪切阈值,更新梯度时,如果梯度超过阈值,就将其强制限制在这个范围之内。
      ②权重正则化
      ③激活函数

九、dropout (全连接层)

  • 随机挑一些神经元失活,置零
  • 优点
    ①能用到更多特征,而不是强依赖于某一个特征,因为你不知道他会不会被失活
    ②相当于训练一个由很多小模型集成而成的大模型:每次dropout一部分后剩下的就相当于一个新模型
  • 训练时用dropout,测试时不再用(不然效率很低),就会出现差异,即测试时得到的更新期望会是训练时的二倍(与失活比例有关),你就需要补偿多出来的那一倍,补偿方式为:
    ①改变测试:测试时,要让激活函数×失活概率
    ②改变训练:反向dropout:在激活函数乘随机失活过滤器之前,让过滤器除以失活概率

十、tensorflow:Graph、Operation、Tensor、Session

  • 大部分开源代码、论文都支持tensorflow,对Numpy, Pandas,keras的支持,tensorboard方便
  • 使用数据流图技术来进行数值计算的开源软件库(不只是一个神经网络工具包,只要能用数据流图来描述的计算过程,就能用TensorFlow)。
  • 数据流图
    描述有向图中的数值计算过程。节点Ops(operator)代表数学运算、输入、输出或读写等操作;边表示节点之间的联系,负责传输多维数据(Tensors:有固定的类型、级别和大小)。
    1)Variables:变量,在图执行时候保持着自己的状态
    2)constant是常量
    3)Fetches:抓取,输出
    4)Feeds:先创建特定数据类型的占位符placeholder,之后再进行数据填充
  • 图计算
    图的创建类似于一个 [施工阶段:构造好图/演员到位],而在 [执行阶段:Action开拍] 则利用一个session来执行图中的节点。很常见的情况是,在 [施工阶段] 创建一个图来表示神经网络,而 [执行阶段] 在图中执行一系列的训练操作。
    • 创建图
      创建一个图来表示神经网络
    • 执行图:Session会话
      一个Session可能会拥有一些资源,例如Variable或者Queue,不再需要时,需要释放
      图通过Session的运行而执行计算。Session将图的ops放到计算设备上,然后通过方法执行它们;这些方法执行完成后,将返回tensors
      with tf.Session() as sess: #自动释放Session资源
      result = sess.run([product]) # run之前计算节点都不会被触发执行
  • 执行Operation或者求值Tensor有两种方式
    1)调用tf.Session.run(fetches, feed_dict=None)
    2)调用Operation.run(session)
    3)调用Tensor.eval(session)

你可能感兴趣的:(秋招)