深度神经网络DNN

深度网络DNN的概念,是基于浅层网路——多层感知机MLP(或称人工神经网络ANN)的基础上发展而来。关于MLP或ANN的知识,此处不做赘述,网上有不少资料能够参考。面试

DNN是一个很广的概念,大名鼎鼎的CNN、RNN、GAN等都属于其范畴以内。CNN多用于网络结构数据类型的任务,如图像、声音、文本等;RNN多用于时间序列类型的任务,如音频、文本(NLP)、视频等;GAN则主要用于“生成数据、以假乱真”,适用于创做类任务。可是本文亦不叙述CNN等知识,相关知识可参考本人相关博客卷积神经网络CNN。本文主要讲述通常的DNN任务,考虑以下问题:算法

有8000个变量,其中少数变量之间可能存在相关性;有20000个样本,每一个样本都有这8000个变量的数据;这20000个样本能够被分为2类(label)。求如何用这些变量构造一个分类器?网络

这个问题,是一个典型的高通量信息数据的问题(如基因组学、代谢组学等),首先考虑的方法是普通机器学习的模型,如PCA、PLS、LASSO等降维,单因素差别分析如Wilcoxon检验、Fold Change卡差别界值,甚至聚类分析,再建模弄个SVM、随机森林、ANN等,最后回归解释性模型如Logistic等。机器学习进阶一点的方法还有XGBoost也能够试试。框架

可是,若是抛开普通机器学习的方法,仅讨论深度学习的方法,这个任务该如何解决?有两个idea,第一是直接套用CNN,可是直观感受,卷积在此处的做用可能不大(也可能有用,将变量固定顺序,将构成一维图像,虽然相邻像素较难联合构成有效的局部特征),所以CNN的方法试试就行;第二是采用全链接的DNN(如FC的ResNet),因为是全链接,参数较多,容易过拟合,考验炼丹的能力了(注意ReLU等非线性变换须要保留,不然就退化成线性分类器了)。机器学习

深度学习就是学习如何利用矩阵的线性变换激活函数的非线性变换,将原始输入空间投向线性可分/稀疏的空间去分类/回归。增长节点数:增长维度,即增长线性转换能力。增长层数:增长激活函数的次数,即增长非线性转换次数。ide

深度 vs. 浅层:浅层神经网络能够模拟任何函数,但数据量的代价是没法接受的。深层解决了这个问题。相比浅层神经网络,深层神经网络能够用更少的数据量来学到更好的拟合。深层的前提是:空间中的元素能够由迭代发展而来的。函数

有人总结了一下经验(看看就好,也不要全信):学习

1.若是数据已经有了特征,好比性别、年龄、地点、访问量等等特征,则直接使用DNN或者全链接进行判断;优化

2.在有了特征的状况下使用CNN可能会致使模型的准确率不是特别高。idea

 

本文就这类问题,进行建模技巧讲解。

 

从Neural Network到Deep Learning

本部分摘自:DNN与ANN的区别

传统神经网络中,采用的是BP算法的方式进行,简单来说就是采用迭代的算法来训练整个网络,随机设定初值,计算当前网络的输出,而后根据当前输出和label之间的差去改变前面各层的参数,直到收敛(总体是一个梯度降低法)。

大约二三十年前,Neural Network曾经是ML领域特别火热的一个方向,可是后来确慢慢淡出了,缘由包括如下几个方面:

1)比较容易过拟合,参数比较难tune,并且须要很多trick;

2)训练速度比较慢,在层次比较少(小于等于3)的状况下效果并不比其它方法更优;

同时BP算法存在的问题:

(1)梯度愈来愈稀疏:从顶层越往下,偏差校订信号愈来愈小;

(2)收敛到局部最小值:尤为是从远离最优区域开始的时候(随机值初始化会致使这种状况的发生)。

直到2006年,Hinton等人提成了一个实际可行的Deep Learning框架。

为了克服神经网络训练中的问题,DL采用了与神经网络很不一样的训练机制。而deep learning总体上是一个layer-wise的训练机制。这样作的缘由是由于,若是采用back propagation的机制,对于一个deep network(7层以上),残差传播到最前面的层已经变得过小,出现所谓的gradient diffusion(梯度消失或梯度弥散)。

Hinton等人提出,在非监督数据上创建多层神经网络的一个有效方法,简单的说,分为两步,一是每次训练一层网络,二是调优,使原始表示x向上生成的高级表示r和该高级表示r向下生成的x'尽量一致。方法是:

1)首先逐层构建单层神经元,这样每次都是训练一个单层网络。

2)当全部层训练完后,Hinton使用wake-sleep算法进行调优。

将除最顶层的其它层间的权重变为双向的,这样最顶层仍然是一个单层神经网络,而其它层则变为了图模型。向上的权重用于“认知”,向下的权重用于“生成”。而后使用Wake-Sleep算法调整全部的权重。让认知和生成达成一致,也就是保证生成的最顶层表示可以尽量正确的复原底层的结点。好比顶层的一个结点表示人脸,那么全部人脸的图像应该激活这个结点,而且这个结果向下生成的图像应该可以表现为一个大概的人脸图像。Wake-Sleep算法分为醒(wake)和睡(sleep)两个部分。

1)wake阶段:认知过程,经过外界的特征和向上的权重(认知权重)产生每一层的抽象表示(结点状态),而且使用梯度降低修改层间的下行权重(生成权重)。也就是“若是现实跟我想象的不同,改变个人权重使得我想象的东西就是这样的”。

2)sleep阶段:生成过程,经过顶层表示(醒时学得的概念)和向下权重,生成底层的状态,同时修改层间向上的权重。也就是“若是梦中的景象不是我脑中的相应概念,改变个人认知权重使得这种景象在我看来就是这个概念”。

 

Deep Learning训练过程具体以下:

1)使用自下上升非监督学习(就是从底层开始,一层一层的往顶层训练):

       采用无标定数据(有标定数据也可)分层训练各层参数,这一步能够看做是一个无监督训练过程,是和传统神经网络区别最大的部分(这个过程能够看做是feature learning过程):

       具体的,先用无标定数据训练第一层,训练时先学习第一层的参数(这一层能够看做是获得一个使得输出和输入差异最小的三层神经网络的隐层),因为模型capacity的限制以及稀疏性约束,使得获得的模型可以学习到数据自己的结构,从而获得比输入更具备表示能力的特征;在学习获得第n-1层后,将n-1层的输出做为第n层的输入,训练第n层,由此分别获得各层的参数;

2)自顶向下的监督学习(就是经过带标签的数据去训练,偏差自顶向下传输,对网络进行微调):

       基于第一步获得的各层参数进一步fine-tune整个多层模型的参数,这一步是一个有监督训练过程;第一步相似神经网络的随机初始化初值过程,因为DL的第一步不是随机初始化,而是经过学习输入数据的结构获得的,于是这个初值更接近全局最优,从而可以取得更好的效果;因此deep learning效果好很大程度上归功于第一步的feature learning过程。

 

一些技巧和认知的梳理

本部分摘自:面试常问的深度学习(DNN、CNN、RNN)的相关问题

1、如何避免陷入局部极小值

1.调节步伐:调节学习速率,使每一次的更新“步伐”不一样;

2.优化起点:合理初始化权重(weights initialization)、预训练网络(pre-train),使网络得到一个较好的“起始点”,如最右侧的起始点就比最左侧的起始点要好。经常使用方法有:高斯分布初始权重(Gaussian distribution)、均匀分布初始权重(Uniform distribution)、Glorot 初始权重、He初始权、稀疏矩阵初始权重(sparse matrix)。

 

2、如何防止过拟合
L2正则化,Dropout(若规律不是在全部样本中都存在,则dropout会删除这样的规律),每一个epoch以后shuffle训练数据,设置early-stopping。加Batch Normalization(BN首先是把全部的samples的统计分布标准化,下降了batch内不一样样本的差别性,而后又容许batch内的各个samples有各自的统计分布),BN最大的优势为容许网络使用较大的学习速率进行训练,加快网络的训练速度(减小epoch次数),提高效果。
 

3、为什么使用Batch Normalization

若用多个梯度的均值来更新权重的批量梯度降低法能够用相对少的训练次数遍历完整个训练集,其次可使更新的方向更加贴合整个训练集,避免单个噪音样本使网络更新到错误方向。然而也正是由于平均了多个样本的梯度,许多样本对神经网络的贡献就被其余样本平均掉了,至关于在每一个epoch中,训练集的样本数被缩小了。batch中每一个样本的差别性越大,这种弊端就越严重。通常的解决方法就是在每次训练完一个epoch后,将训练集中样本的顺序打乱再训练另外一个epoch,不断反复。这样从新组成的batch中的样本梯度的平均值就会与上一个epoch的不一样。而这显然增长了训练的时间。同时由于没办法保证每次更新的方向都贴合整个训练集的大方向,只能使用较小的学习速率。这意味着训练过程当中,一部分steps对网络最终的更新起到了促进,一部分steps对网络最终的更新形成了干扰,这样“磕磕碰碰”无数个epoch后才能达到较为满意的结果。

为了解决这种“不效率”的训练,BN首先是把全部的samples的统计分布标准化,下降了batch内不一样样本的差别性,而后又容许batch内的各个samples有各自的统计分布。

 

4、神经元的运算逻辑

本段摘自:【Keras】DNN神经网络模型 (文中附有Keras的代码实现)

神经元的运算逻辑,必定是线性内核和非线性激活相结合,因此神经元的算法是非线性的。所以DNN神经元的计算内核为X*W+b,以softmax函数(二元分类中使用Sigmoid函数)为非线性核的构造方式。同理,RNN的核采用RNN运算内核,CNN采用卷积运算内核。

逻辑分类能够视为一层DNN神经网络,计算内核为X*W+b,以softmax函数(二元分类中使用Sigmoid函数)为非线性核的构造方式。像逻辑分类这种,线性运算单元设计为权重相乘的,而且层与层之间的神经元所有相连的神经网络就是全链接神经网络,即DNN

进一步增长隐层,,容纳更多的神经元,来加强模型的能力。比起浅层模型在特征工程和模型工程的各类尝试,神经网络经过更多的神经元直接加强模型的能力。

DNN vs. CNN:我的观点,阉割掉卷积操做、改成全链接,便可转变为普通DNN。而CNN的ResNet比较成熟,所以反而能够经过改造CNN来获得DNN(纯属我的观点,具体实现固然会有问题)

 

5、本质的探讨

为何神经网络高效:并行的先验知识使得模型可用线性级数量的样本学习指数级数量的变体。

为何深层神经网络比浅层神经网络更高效:迭代组成的先验知识使得样本可用于帮助训练其余共用一样底层结构的样本。

神经网络在什么问题上不具有优点:不知足并行与迭代先验的任务。(本人不太理解)

对于这些关于本质的说法以及神经网络在什么问题上不具有优点,本人暂时存疑。

 

6、训练DNN的一些其余技巧参考

如何正确训练DNN 、DNN训练技巧(Tips for Training DNN)

这些博文中引用了一个很重要的观点:“Do not always blame overfitting”。具体的,以后展开叙述。


 

代码实现

待更新