① 信息传输的网络类型有几种
下面就几种常见的网络类型及分类方法作简单的介绍。
按网络的地理位置分类
*局域网(LocalAreaNetwork,简称LAN)
一般限定在较小的区域内,小于10km的范围,通常采用有线的方式连接起来。
*城域网(MetroolisAreaNetwork,简称MAN)
规模局限在一座城市的范围内,10~100km的区域。
*广域网(WideAreaNetwork,简称WAN)
网络跨越国界、洲界,甚至全球范围。
目前局域网和广域网是网络的热点。局域网是组成其他两种类型网络的基础,城域网一般都加入了广域网。广域网的典型代表是Internet网。
按网络的拓扑结构分类
网络的拓扑结构是指网络中通信线路和站点(计算机或设备)的几何排列形式。
*星型网络
各站点通过点到点的链路与中心站相连。特点是很容易在网络中增加新的站点,数据的安全性和优先级容易控制,易实现网络监控,但中心节点的故障会引起整个网络瘫痪。
*环形网络
各站点通过通信介质连成一个封闭的环形。环形网容易安装和监控,但容量有限,网络建成后,难以增加新的站点。
*总线型网络
网络中所有的站点共享一条数据通道。总线型网络安装简单方便,需要铺设的电缆最短,成本低,某个站点的故障一般不会影响整个网络。但介质的故障会导致网络瘫痪,总线网安全性低,监控比较困难,增加新站点也不如星型网容易。
树型网、簇星型网、网状网等其他类型拓扑结构的网络都是以上述三种拓扑结构为基础的。
按传输介质分类
*有线网
采用同轴电缆和双绞线来连接的计算机网络。
同轴电缆网是常见的一种连网方式。它比较经济,安装较为便利,传输率和抗干扰能力一般,传输距离较短。
双绞线网是目前最常见的连网方式。它价格便宜,安装方便,但易受干扰,传输率较低,传输距离比同轴电缆要短。
*光纤网
光纤网也是有线网的一种,但由于其特殊性而单独列出,光纤网采用光导纤维作传输介质。光纤传输距离长,传输率高,可达数千兆bs,抗干扰性强,不会受到电子监听设备的监听,是高安全性网络的理想选择。不过由于其价格较高,且需要高水平的安装技术,所以现在尚未普及。
*无线网
采用空气作传输介质,用电磁波作为载体来传输数据,目前无线网联网费用较高,还不太普及。但由于联网方式灵活方便,是一种很有前途的连网方式。
局域网通常采用单一的传输介质,而城域网和广域网采用多种传输介质。
按通信方式分类
*点对点传输网络:数据以点到点的方式在计算机或通信设备中传输。星型网、环形网采用这种传输方式。
*广播式传输网络:数据在共用介质中传输。无线网和总线型网络属于这种类型。
按网络使用的目的分类
*共享资源网:使用者可共享网络中的各种资源,如文件、扫描仪、绘图仪、打印机以及各种服务。Internet网是典型的共享资源网。
*数据处理网:用于处理数据的网络,例如科学计算网络、企业经营管理用网络。
*数据传输网:用来收集、交换、传输数据的网络,如情报检索网络等。
目前网络使用目的都不是唯一的。
按服务方式分类
*客户机/服务器网络
服务器是指专门提供服务的高性能计算机或专用设备,客户机是用户计算机。这是客户机向服务器发出请求并获得服务的一种网络形式,多台客户机可以共享服务器提供的各种资源。这是最常用、最重要的一种网络类型。不仅适合于同类计算机联网,也适合于不同类型的计算机联网,如C机、Mac机的混合联网。这种网络安全性容易得到保证,计算机的权限、优先级易于控制,监控容易实现,网络管理能够规范化。网络性能在很大程度上取决于服务器的性能和客户机的数量。目前针对这类网络有很多优化性能的服务器称为专用服务器。银行、证券公司都采用这种类型的网络。
*对等网
对等网不要求文件服务器,每台客户机都可以与其他每台客户机对话,共享彼此的信息资源和硬件资源,组网的计算机一般类型相同。这种网络方式灵活方便,但是较难实现集中管理与监控,安全性也低,较适合于部门内部协同工作的小型网络。
其他分类方法
如按信息传输模式的特点来分类的ATM网,网内数据采用异步传输模式,数据以53字节单元进行传输,提供高达1.2Gbs的传输率,有预测网络延时的能力。可以传输语音、视频等实时信息,是最有发展前途的网络类型之一。
另外还有一些非正规的分类方法:如企业网、校园网,根据名称便可理解。
从不同的角度对网络有不同的分类方法,每种网络名称都有特殊的含意。几种名称的组合或名称加参数更可以看出网络的特征。千兆以太网表示传输率高达千兆的总线型网络。了解网络的分类方法和类型特征,是熟悉网络技术的重要基础之一。
② AI面试题第二弹(神经网络基础)
提取主要特征,减小网络参数量,减小计算量
层层传递的梯度>1 梯度爆炸
层层传递的梯度<1 梯度消失
与权重有很大关系,激活函数的影响较小。
每次训练一层隐节点,训练时将上一层隐节点的输出作为输入,而本层隐节点的输出作为下一层隐节点的输入,此过程就是逐层“预训练”(pre-training);在预训练完成后,再对整个网络进行“微调”(fine-tunning)。Hinton在训练深度信念网络(Deep Belief Networks中,使用了这个方法,在各层预训练完成后,再利用BP算法对整个网络进行训练。
这个方案主要是针对梯度爆炸提出的,其思想是设置一个梯度剪切阈值,然后更新梯度的时候,如果梯度超过这个阈值,那么就将其强制限制在这个范围之内。这可以防止梯度爆炸。
比较常见的是l1l1l1正则,和l2l2l2正则,在各个深度框架中都有相应的API可以使用正则化
反向传播中,经过每一层的梯度会乘以该层的权重。
举个简单例子:
为了得到一致假设而使假设变得过度复杂称为过拟合(overfitting), 过拟合表现在训练好的模型在训练集上效果很好,但是在测试集上效果差 。也就是说模型的泛化能力弱。
过拟合主要由两个原因造成,数据集太小或模型太复杂
(1). 数据集扩增(Data Augmentation)
(2). 改进模型
·Early Stopping。在模型效果比较好的时候便提前停止训练
·正则化(regularization)
L1:稀疏参数
L2:更小参数
·Dropout
·多任务学习
深度学习中两种多任务学习模式:隐层参数的硬共享和软共享
硬共享机制是指在所有任务中共享隐藏层,同时保留几个特定任务的输出层来实现。硬共享机制降低了过拟合的风险。多个任务同时学习,模型就越能捕捉到多个任务的同一表示,从而导致模型在原始任务上的过拟合风险越小。
软共享机制是指每个任务有自己的模型,自己的参数。模型参数之间的距离是正则化的,以便保障参数相似性。
见后文
leaky relu
输入是x输出是y,正常的流程是:我们首先把x通过网络前向传播,然后把误差反向传播以决定如何更新参数让网络进行学习。使用Dropout之后,过程变成如下:
(1)首先随机(临时)删掉网络中一半的隐藏神经元,输入输出神经元保持不变(图中虚线为部分临时被删除的神经元)
(2) 然后把输入x通过修改后的网络前向传播,然后把得到的损失结果通过修改的网络反向传播。一小批训练样本执行完这个过程后,在没有被删除的神经元上按照随机梯度下降法更新对应的参数(w,b)。
(3)然后继续重复这一过程:
恢复被删掉的神经元(此时被删除的神经元保持原样,而没有被删除的神经元已经有所更新)
从隐藏层神经元中随机选择一个一半大小的子集临时删除掉(备份被删除神经元的参数)。
对一小批训练样本,先前向传播然后反向传播损失并根据随机梯度下降法更新参数(w,b) (没有被删除的那一部分参数得到更新,删除的神经元参数保持被删除前的结果)。
不断重复这一过程。
没有对数据进行归一化
忘记检查输入和输出
没有对数据进行预处理
没有对数据正则化
使用过大的样本
使用不正确的学习率
在输出层使用错误的激活函数
网络中包含坏梯度
初始化权重错误
过深的网络
隐藏单元数量错误
网络设计不合理(任务-网络不匹配)
机器学习有个很重要的假设:就是假设训练数据和测试数据是满足独立同分布的,这保障了通过训练数据获得的优秀模型也能够在测试集获得好的效果。但是在机器学习训练中输入层的每个批量(X,Y)中X的分布是不一致的,并且神经网络的隐藏层的输入分布在每次训练迭代中发生变化。 BatchNorm就是在深度神经网络训练过程中使得每一层神经网络的输入保持相同分布的。
BN的基本思想其实相当直观:因为深层神经网络在做非线性变换前(激活前)的 输入值 (就是那个x=WU+B,U是输入) 随着网络深度加深或者在训练过程中,其分布逐渐发生偏移或者变动,之所以训练收敛慢,一般是整体分布逐渐往非线性函数的取值区间的上下限两端靠近 (对于Sigmoid函数来说,意味着激活输入值WU+B是大的负值或正值),所以这 导致反向传播时低层神经网络的梯度消失 ,这是训练深层神经网络收敛越来越慢的 本质原因 , 而BN就是通过一定的规范化手段,把每层神经网络任意神经元这个输入值的分布强行拉回到均值为0方差为1的标准正态分布 ,其实就是把越来越偏的分布强制拉回比较标准的分布,这样使得激活输入值落在非线性函数对输入比较敏感的区域,这样输入的小变化就会导致损失函数较大的变化,意思是 这样让梯度变大,避免梯度消失问题产生,而且梯度变大意味着学习收敛速度快,能大大加快训练速度。
但是接下来的问题是:如果都通过BN,那么不就跟把非线性函数替换成线性函数效果相同了,意味着网络的非线性表达能力下降了, 所以BN为了保证非线性的获得,对变换后的满足均值为0方差为1的x又进行了scale加上shift操作(y=scale*x+shift), 每个神经元增加了两个参数scale和shift参数,这两个参数是通过训练学习到的,意思是通过scale和shift把这个值从标准正态分布左移或者右移一点并长胖一点或者变瘦一点,每个实例挪动的程度不一样,这样等价于激活前的值经过标准正太分布归一化后再从正中心周围的线性区往非线性区动了动。核心思想应该是想找到一个线性和非线性的较好平衡点,既能享受非线性的较强表达能力的好处,又避免太靠非线性区两头使得网络收敛速度太慢
Batch Normalization 好处:(1)提高了训练速度,收敛速度也大大加快(2)另外调参过程也简单多了,对于初始化要求没那么高,而且可以使用大的学习率等 (3)可以防止梯度消失(4)BN类似于Dropout的一种防止过拟合的正则化表达方式,可以有效防止过拟合,不用太依赖dropou和正则化
以下情况最好不要使用BN:(1)数据不平衡(2)batch_size太小
batch_size是机器学习中的一个重要参数,决定了梯度下降的方向,如果数据集比较小,完全可以采用全数据集的形式计算梯度,由全数据集确定的梯度方向能够更好地代表样本总体,从而更准确地朝向极值所在的方向。对于大型数据集则需要使用mini-batch_size,因为随着数据集的海量增长和内存限制,一次性载入所有的数据进来变得越来越不可行。
当batch_size=1,即在线学习,模型难以达到收敛 。
合理增加batch_size好处 :
(1)内存利用率提高了,大矩阵乘法的并行化效率提高
(2)跑完一次 epoch(全数据集)所需的迭代次数减少,对于相同数据量的处理速度进一步加快。
(3)在一定范围内,一般来说 Batch_Size 越大,其确定的下降方向越准,引起训练震荡越小
盲目增大 Batch_Size 坏处 :
(1)内存利用率提高了,但是内存容量可能撑不住了
(2)跑完一次 epoch(全数据集)所需的迭代次数减少,要想达到相同精度所需要的 epoch 数量越来越多,花费的时间越长
(3)大的batchsize收敛到sharp minimum,而小的batchsize收敛到flat minimum,后者具有更好的泛化能力。
总之batchsize在变得很大(超过一个临界点)时,会降低模型的泛化能力。在这个临界点之下,模型的性能变换随batch size通常没有学习率敏感
目标所在的真实框(ground truth) 与算法预测的目标所在的框(bounding box)的交集与并集的比值,我们会用IOU阈值来判定预测的bounding box是否有效。一般阈值会设定在0.5,当IOU的值大于等于0.5时,我们会把这个预测的bounding box 归为正类,而小于0.5的归为负类。
牛顿法使用的是目标函数的二阶导数,在高维情况下这个Hessian(n*n维度)矩阵非常大,计算复杂度是n*n,计算和存储都是问题
(1) 通过控制卷积核个数实现升维或者降维,从而减少模型参数和计算量
(2) 用于不同channel上特征的融合
(3)1x1的卷积相当于全连接层的计算过程,并且加入了非线性激活函数,从而增加了网络的非线性,使得网络可以表达更加复杂的特征。
它能够把输入的连续实值变换为0和1之间的输出,如果是非常大的负数,那么输出就是0;如果是非常大的正数,输出就是1
缺点:
(1)函数的饱和区,导致梯度几乎为0,造成梯度消失问题
(2)Sigmoid 的 output 不是0均值,具体解释见 https://blog.csdn.net/tyhj_sf/article/details/79932893
(3)其解析式中含有幂运算,计算机求解时相对来讲比较耗时。对于规模比较大的深度网络,这会较大地增加训练时间。
它解决了Sigmoid函数的不是零均值输出问题,然而,梯度消失(gradient vanishing)的问题和幂运算的问题仍然存在。
(1)在正区间解决了梯度消失的问题
(2)函数简单,计算速度快,收敛速度远快于sigmoid和tanh
缺点:
(1)Relu函数输出不是0均值
(2)神经元坏死问题:指的是某些神经元可能永远不会被激活,导致相应的参数永远不能被更新,有两个主要原因导致这种状况发生
(1) 非常不幸的参数初始化,这种情况比较少见
(2) learning rate太高导致在训练过程中参数更新太大,不幸使网络进入这种状态。解决方法是可以采用Xavier初始化方法,以及避免将learning rate设置太大或使用adagrad等自动调节learning rate的算法
为了解决ReLU函数带来的神经元坏死问题 , 提出了将ReLU的前半段设为αx,α通常设为0.01,,另外一种直观的想法是基于参数的方法PReLU函数, α可由方向传播算法学习出来。
ELU也是为解决ReLU存在的问题而提出,显然,ELU有ReLU的基本所有优点,以及:(1)不会有神经元坏死现象(2)函数输出均值接近于0
但是ELU的小问题就是计算量稍微有点大。
1、使用不同的激活函数,比如Relu,Leak-Relu,PRelu,elu等激活函数代替sigmoid函数
2、使用Batch Normalizaion(批量归一化)
3、使用残差网络
4、预训练加微调
1、梯度裁剪
2、权重正则化
两个3x3的卷积核的感受野比5x5的卷积核的感受野大,在保持相同感受野的同时,用3x3的卷积核可以提升网络的深度,可以很明显的减少计算量。
1、局部连接
2、权值共享:减小参数量
3、池化操作:增大感受野
4、多层次结构:可以提取low-level以及high-level的信息
1、数据集太小,数据样本不足时,深度学习相对其它机器学习算法,没有明显优势。
2、数据集没有局部相关特性,目前深度学习表现比较好的领域主要是图像/语音/自然语言处理等领域,这些领域的一个共性是局部相关性。图像中像素组成物体,语音信号中音位组合成单词,文本数据中单词组合成句子,这些特征元素的组合一旦被打乱,表示的含义同时也被改变。对于没有这样的局部相关性的数据集,不适于使用深度学习算法进行处理。举个例子:预测一个人的健康状况,相关的参数会有年龄、职业、收入、家庭状况等各种元素,将这些元素打乱,并不会影响相关的结果。
作用 :对输入的特征图进行压缩,
一方面使特征图变小,简化网络计算复杂度;
一方面进行特征压缩,提取主要特征。
通常来讲,max-pooling的效果更好,虽然max-pooling和average-pooling都对数据做了下采样,但是 max-pooling感觉更像是做了特征选择,选出了分类辨识度更好的特征,提供了非线性 。 pooling的主要作用一方面是去掉冗余信息,一方面要保留feature map的特征信息,在分类问题中,我们需要知道的是这张图像有什么object,而不大关心这个object位置在哪,在这种情况下显然max pooling比average pooling更合适。在 网络比较深的地方,特征已经稀疏了,从一块区域里选出最大的,比起这片区域的平均值来,更能把稀疏的特征传递下去 。
average-pooling更强调对整体特征信息进行一层下采样,在减少参数维度的贡献上更大一点,更多的体现在 信息的完整传递这个维度 上,在一个很大很有代表性的模型中,比如说DenseNet中的模块之间的连接大多采用average-pooling,在减少维度的同时,更有利信息传递到下一个模块进行特征提取。
average-pooling在 全局平均池化操作 中应用也比较广,在ResNet和Inception结构中最后一层都使用了平均池化。有的时候在模型接近 分类器的末端使用全局平均池化还可以代替Flatten操作 ,使输入数据变成一位向量。
CNN网络中另外一个不可导的环节就是Pooling池化操作,因为Pooling操作使得feature map的尺寸变化,假如做2×2的池化(步长也为2),假设那么第l+1层的feature map有16个梯度,那么第l层就会有64个梯度,这使得梯度无法对位的进行传播下去。其实解决这个问题的思想也很简单,就是把1个像素的梯度传递给4个像素,但是需要保证传递的loss(或者梯度)总和不变。根据这条原则,mean pooling和max pooling的反向传播也是不同的
mean pooling的前向传播就是把一个patch中的值求取平均来做pooling,那么反向传播的过程也就是把 某个元素的梯度等分为n份分配给前一层,这样就保证池化前后的梯度(残差)之和保持不变 ,图示如下 :
(2) max pooling
max pooling也要满足梯度之和不变的原则 ,max pooling的前向传播是把patch中最大的值传递给后一层,而其他像素的值直接被舍弃掉。那么 反向传播也就是把梯度直接传给前一层某一个像素,而其他像素不接受梯度,也就是为0。 所以max pooling操作和mean pooling操作不同点在于需要记录下池化操作时到底哪个像素的值是最大,也就是max id,这个变量就是记录最大值所在位置的,因为在反向传播中要用到,那么假设前向传播和反向传播的过程就如下图所示 :
28、细粒度分类
29、LSTM&RNN
30、解释LSTM结构(相对于RNN)的好处
31、RNN的梯度消失原因和解决办法
32、Object Detection
33、Unet的介绍
34、FCN和Unet的区别
35、RCNN系列的算法流程和区别
36、Fast RCNN中 bbox 回归的损失函数什么
37、解释 ROI Pooling 和 ROI Align
38、Mask RCNN中 mask branch 如何接入 Faster RCNN中
39、解释 FPN
40、解释 ROI Align
41、简述 YOLO 和 SSD
42、简述 Hough 直线检测、Sobel 边缘检测算法流程
43、Mask RCNN中的anchors如何判定为正负样本
44、简述 NMS 算法流程
45、attention起源是用在哪里?pixel还是frame,是soft还是hard
46、anchor的正负样本比是多少
47、算法和激活函数等
48、BN的原理和作用
49、BN层反向传播,怎么求导
50、BN 的作用和缺陷,以及针对batch_size小的情况的改进(GN)
51、BN层,先加BN还是激活,有什么区别
52、手推BP
53、优化算法举例和他们的区别(SGD、SGDM、RMSprop、Adam)
54、随机梯度下降和梯度下降
55、训练不收敛的原因有哪些
56、简述 SVM 流程、核函数寻参及常见的核函数举例
57、batch_size 和 learning rate 的关系(怎么平衡和调整二者)
58、解释过拟合和欠拟合,以及解决方法
59、激活函数有哪些,各自区别
60、损失函数有哪些
61、Sigmoid 和 ReLu 对比(各自优缺点)
62、为什么不用sigmoid而用relu?做出了哪些改进?
63、梯度消失和梯度爆炸的原因和解决方法
64、Precision 和 Recall 的定义
65、精确率高、召回率低是为什么
66、SVM,线性回归和逻辑回归的原理及区别
67、PCA原理,PCA和SVD的区别和联系
68、正则化怎么选择,有哪些方式
69、L1、L2范数,区别
70、boost、Adaboost
71、dropout和batch normalization
72、讲一下决策树和随机森林
73、讲一下GBDT的细节,写出GBDT的目标函数。 GBDT和Adaboost的区别与联系
74、偏差、方差
75、距离度量公式哪些,区别
76、多标签识别怎么做
77、data argumentation怎么处理的
78、数据不均衡怎么处理、只有少量带标签怎么处理
79、权重初始化方法都有哪些
80、权值衰减这个参数怎么设置
81、分类问题有哪些评价指标?每种的适用场景。
82、无监督学习了解哪些
83、图像处理Opencv
84、边缘检测算子有哪些
85、霍夫变换
86、直方图是什么
87、canny算子是怎么做的
88、图像的特征提取有哪些算法,适用范围、优缺点
参考:
https://blog.csdn.net/bluesliuf/article/details/89389117
https://zhuanlan.hu.com/p/107279000
https://zhuanlan.hu.com/p/56475281
③ 卷积神经网络为什么适合图像处理
神经网络的本质就在于做信息形式的变换,而要想做数据的处理,首要解决的问题就是如何将数据张量化,问题就在于卷积神经网络要处理的数据必须是向量形式,对于图像这种数据类型来说,如果将其展开成一维的向量,且不说得到向量的维数过高,网络太深导致网络中参数太多,图像中的空间信息也会丢失。
而卷积神经网络能够用卷积的方式从原信息中提取"部分特定的信息(信息跟卷积核相关)",且对于二维的图像来说是原生支持的(不需要处理),这就保留了图像中的空间信息,而空间信息是具有可平移性质的.。
并且卷积神经网络的参数就只是卷积核的参数以及偏置(Bias),而卷积核的参数可以做到共享,卷积核也可以用多个,从多个角度对原图像解读。
这就是卷积神经网络的几个特点:局部感知,参数共享,多核,平移不变性正是因为这些特点,在图像领域处理上,卷积神经网络取代了人工神经网络。
卷积神经网络 (CNN) 是当今最流行的模型之一。这种神经网络计算模型使用多层感知器的变体,并包含一个或多个可以完全连接或池化的卷积层。这些卷积层创建了记录图像区域的特征图,该区域最终被分成矩形并发送出去进行非线性处理。
优点:
图像识别问题的非常高的准确性。自动检测重要特征,无需任何人工监督。权重共享。
缺点:
CNN 不对物体的位置和方向进行编码。缺乏对输入数据空间不变的能力。需要大量的训练数据。
④ CNN之Lenet5
LeNet诞生于 1994 年,是最早的卷积神经网络之一,并且推动了深度学习领域的发展。
LeNet-5是Yann LeCun等人在多次研究后提出的最终卷积神经网络结构,主要用于手写数字识别
LeNet5的网络结构如下所示:
LeNet-5包含七层,不包括输入,每一层都包含可训练参数(权重),当时使用的输入数据是32*32像素的图像。下面逐层介绍LeNet-5的结构,并且,卷积层将用Cx表示,子采样层则被标记为Sx,全连接层被标记为Fx,其中x是层索引。
该层使用了6个卷积核,每个卷积核的大小为5×5,这样就得到了6个feature map(特征图)。
每个卷积核(5×5)与原始的输入图像(32×32)进行卷积,这样得到的feature map(特征图)大小为(32-5+1)×(32-5+1)= 28×28
卷积核与输入图像按卷积核大小逐个区域进行匹配计算,匹配后原始输入图像的尺寸将变小,因为边缘部分卷积核无法越出界,只能匹配一次,匹配计算后的尺寸变为Cr×Cc=(Ir-Kr+1)×(Ic-Kc+1),其中Cr、Cc,Ir、Ic,Kr、Kc分别表示卷积后结果图像、输入图像、卷积核的行列大小。
由于参数(权值)共享的原因,对于同个卷积核每个神经元均使用相同的参数,因此,参数个数为(5×5+1)×6= 156,其中5×5为卷积核参数,1为偏置参数
卷积后的图像大小为28×28,因此每个特征图有28×28个神经元,每个卷积核参数为(5×5+1)×6,因此,该层的连接数为(5×5+1)×6×28×28=122304
这一层主要是做池化或者特征映射(特征降维),池化单元为2×2,因此,6个特征图的大小经池化后即变为14×14。池化单元之间没有重叠,在池化区域内进行聚合统计后得到新的特征值,因此经2×2池化后,每两行两列重新算出一个特征值出来,相当于图像大小减半,因此卷积后的28×28图像经2×2池化后就变为14×14。
这一层的计算过程是:2×2 单元里的值相加,然后再乘以训练参数w,再加上一个偏置参数b(每一个特征图共享相同的w和b),然后取sigmoid值(S函数:0-1区间),作为对应的该单元的值。卷积操作与池化的示意图如下:
S2层由于每个特征图都共享相同的w和b这两个参数,因此需要2×6=12个参数
下采样之后的图像大小为14×14,因此S2层的每个特征图有14×14个神经元,每个池化单元连接数为2×2+1(1为偏置量),因此,该层的连接数为(2×2+1)×14×14×6 = 5880
C3层有16个卷积核,卷积模板大小为5×5。
与C1层的分析类似,C3层的特征图大小为(14-5+1)×(14-5+1)= 10×10
需要注意的是,C3与S2并不是全连接而是部分连接,有些是C3连接到S2三层、有些四层、甚至达到6层,通过这种方式提取更多特征,连接的规则如下表所示:
例如第一列表示C3层的第0个特征图(feature map)只跟S2层的第0、1和2这三个feature maps相连接,计算过程为:用3个卷积模板分别与S2层的3个feature maps进行卷积,然后将卷积的结果相加求和,再加上一个偏置,再取sigmoid得出卷积后对应的feature map了。其它列也是类似(有些是3个卷积模板,有些是4个,有些是6个)。因此,C3层的参数数目为(5×5×3+1)×6 +(5×5×4+1)×9 +5×5×6+1 = 1516
卷积后的特征图大小为10×10,参数数量为1516,因此连接数为1516×10×10= 151600
与S2的分析类似,池化单元大小为2×2,因此,该层与C3一样共有16个特征图,每个特征图的大小为5×5。
与S2的计算类似,所需要参数个数为16×2 = 32
连接数为(2×2+1)×5×5×16 = 2000
该层有120个卷积核,每个卷积核的大小仍为5×5,因此有120个特征图。由于S4层的大小为5×5,而该层的卷积核大小也是5×5,因此特征图大小为(5-5+1)×(5-5+1)= 1×1。这样该层就刚好变成了全连接,这只是巧合,如果原始输入的图像比较大,则该层就不是全连接了。
与前面的分析类似,本层的参数数目为120×(5×5×16+1) = 48120
由于该层的特征图大小刚好为1×1,因此连接数为48120×1×1=48120
F6层有84个单元,之所以选这个数字的原因是来自于输出层的设计,对应于一个7×12的比特图,如下图所示,-1表示白色,1表示黑色,这样每个符号的比特图的黑白色就对应于一个编码。
该层有84个特征图,特征图大小与C5一样都是1×1,与C5层全连接。
由于是全连接,参数数量为(120+1)×84=10164。跟经典神经网络一样,F6层计算输入向量和权重向量之间的点积,再加上一个偏置,然后将其传递给sigmoid函数得出结果。
由于是全连接,连接数与参数数量一样,也是10164。
Output层也是全连接层,共有10个节点,分别代表数字0到9。如果第i个节点的值为0,则表示网络识别的结果是数字i。
该层采用径向基函数(RBF)的网络连接方式,假设x是上一层的输入,y是RBF的输出,则RBF输出的计算方式是:
上式中的Wij的值由i的比特图编码确定,i从0到9,j取值从0到7×12-1。RBF输出的值越接近于0,表示当前网络输入的识别结果与字符i越接近。
由于是全连接,参数个数为84×10=840
由于是全连接,连接数与参数个数一样,也是840
from skimage import io,transform
import os
import glob
import numpy as np
import tensorflow as tf
#将所有的图片重新设置尺寸为32*32
w = 32
h = 32
c = 1
#mnist数据集中训练数据和测试数据保存地址
train_path = "E:/data/datasets/mnist/train/"
test_path = "E:/data/datasets/mnist/test/"
#读取图片及其标签函数
'''os.listdir()返回指定的文件夹包含的文件或文件夹的名字,存放于一个列表中;os.path.isdir()判断某一路径是否为目录
enumerate()将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,数据下标和相应数据'''
def read_image(path):
label_dir = [path+x for x in os.listdir(path) if os.path.isdir(path+x)]
images = []
labels = []
for index,folder in enumerate(label_dir):
for img in glob.glob(folder+'/*.png'):
print("reading the image:%s"%img)
image = io.imread(img)
image = transform.resize(image,(w,h,c))
images.append(image)
labels.append(index)
return np.asarray(images,dtype=np.float32),np.asarray(labels,dtype=np.int32)
#读取训练数据及测试数据
train_data,train_label = read_image(train_path)
test_data,test_label = read_image(test_path)
#打乱训练数据及测试数据 np.arange()返回一个有终点和起点的固定步长的排列,
train_image_num = len(train_data)
train_image_index = np.arange(train_image_num) ##起始点0,结束点train_image_num,步长1,返回类型array,一维
np.random.shuffle(train_image_index)
train_data = train_data[train_image_index]
train_label = train_label[train_image_index]
test_image_num = len(test_data)
test_image_index = np.arange(test_image_num)
np.random.shuffle(test_image_index)
test_data = test_data[test_image_index]
test_label = test_label[test_image_index]
#搭建CNN 此函数可以理解为形参,用于定义过程,在执行的时候再赋具体的值,形参名X,y_
x = tf.placeholder(tf.float32,[None,w,h,c],name='x')
y_ = tf.placeholder(tf.int32,[None],name='y_')
def inference(input_tensor,train,regularizer):
#第一层:卷积层,过滤器的尺寸为5×5,深度为6,不使用全0补充,步长为1。
#尺寸变化:32×32×1->28×28×6
'''参数的初始化:tf.truncated_normal_initializer()或者简写为tf.TruncatedNormal()、tf.RandomNormal() 去掉_initializer,大写首字母即可
生成截断正态分布的随机数,这个初始化方法好像在tf中用得比较多mean=0.0, stddev=1.0 正态分布
http://www.mamicode.com/info-detail-1835147.html'''
with tf.variable_scope('layer1-conv1'):
conv1_weights = tf.get_variable('weight',[5,5,c,6],initializer=tf.truncated_normal_initializer(stddev=0.1))
conv1_biases = tf.get_variable('bias',[6],initializer=tf.constant_initializer(0.0))
conv1 = tf.nn.conv2d(input_tensor,conv1_weights,strides=[1,1,1,1],padding='VALID')
relu1 = tf.nn.relu(tf.nn.bias_add(conv1,conv1_biases))
#第二层:池化层,过滤器的尺寸为2×2,使用全0补充,步长为2。
#尺寸变化:28×28×6->14×14×6
with tf.name_scope('layer2-pool1'):
pool1 = tf.nn.max_pool(relu1,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
#第三层:卷积层,过滤器的尺寸为5×5,深度为16,不使用全0补充,步长为1。
#尺寸变化:14×14×6->10×10×16
with tf.variable_scope('layer3-conv2'):
conv2_weights = tf.get_variable('weight',[5,5,6,16],initializer=tf.truncated_normal_initializer(stddev=0.1))
conv2_biases = tf.get_variable('bias',[16],initializer=tf.constant_initializer(0.0))
conv2 = tf.nn.conv2d(pool1,conv2_weights,strides=[1,1,1,1],padding='VALID')
relu2 = tf.nn.relu(tf.nn.bias_add(conv2,conv2_biases))
#第四层:池化层,过滤器的尺寸为2×2,使用全0补充,步长为2。
#尺寸变化:10×10×6->5×5×16
with tf.variable_scope('layer4-pool2'):
pool2 = tf.nn.max_pool(relu2,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
#将第四层池化层的输出转化为第五层全连接层的输入格式。第四层的输出为5×5×16的矩阵,然而第五层全连接层需要的输入格式
#为向量,所以我们需要把代表每张图片的尺寸为5×5×16的矩阵拉直成一个长度为5×5×16的向量。
#举例说,每次训练64张图片,那么第四层池化层的输出的size为(64,5,5,16),拉直为向量,nodes=5×5×16=400,尺寸size变为(64,400)
pool_shape = pool2.get_shape().as_list()
nodes = pool_shape[1]*pool_shape[2]*pool_shape[3]
reshaped = tf.reshape(pool2,[-1,nodes])
#第五层:全连接层,nodes=5×5×16=400,400->120的全连接
#尺寸变化:比如一组训练样本为64,那么尺寸变化为64×400->64×120
#训练时,引入dropout,dropout在训练时会随机将部分节点的输出改为0,dropout可以避免过拟合问题。
#这和模型越简单越不容易过拟合思想一致,和正则化限制权重的大小,使得模型不能任意拟合训练数据中的随机噪声,以此达到避免过拟合思想一致。
#本文最后训练时没有采用dropout,dropout项传入参数设置成了False,因为训练和测试写在了一起没有分离,不过大家可以尝试。
'''tf.matmul()这个函数是专门矩阵或者tensor乘法,而不是矩阵元素对应元素相乘
tf.multiply()两个矩阵中对应元素各自相乘
tf.nn.dropout(x, keep_prob):TensorFlow里面为了防止或减轻过拟合而使用的函数,它一般用在全连接层,
x:指输入;keep_prob: 设置神经元被选中的概率,使输入tensor中某些元素变为0,其它没变0的元素变为原来的1/keep_prob大小,可以想象下,比如某些元素弃用
在初始化时keep_prob是一个占位符,keep_prob = tf.placeholder(tf.float32).
tensorflow在run时设置keep_prob具体的值,例如keep_prob: 0.5,train的时候才是dropout起作用的时候
keep_prob: A scalar Tensor with the same type as x. The probability that each element is kept.'''
with tf.variable_scope('layer5-fc1'):
fc1_weights = tf.get_variable('weight',[nodes,120],initializer=tf.truncated_normal_initializer(stddev=0.1))
if regularizer != None:
tf.add_to_collection('losses',regularizer(fc1_weights))
fc1_biases = tf.get_variable('bias',[120],initializer=tf.constant_initializer(0.1))
fc1 = tf.nn.relu(tf.matmul(reshaped,fc1_weights) + fc1_biases)
if train:
fc1 = tf.nn.dropout(fc1,0.5)
#第六层:全连接层,120->84的全连接
#尺寸变化:比如一组训练样本为64,那么尺寸变化为64×120->64×84
'''tf.add_to_collection:把变量放入一个集合,把很多变量变成一个列表
tf.get_collection:从一个结合中取出全部变量,是一个列表
tf.add_n:把一个列表的东西都依次加起来'''
with tf.variable_scope('layer6-fc2'):
fc2_weights = tf.get_variable('weight',[120,84],initializer=tf.truncated_normal_initializer(stddev=0.1))
if regularizer != None:
tf.add_to_collection('losses',regularizer(fc2_weights))
fc2_biases = tf.get_variable('bias',[84],initializer=tf.truncated_normal_initializer(stddev=0.1))
fc2 = tf.nn.relu(tf.matmul(fc1,fc2_weights) + fc2_biases)
if train:
fc2 = tf.nn.dropout(fc2,0.5)
#第七层:全连接层(近似表示),84->10的全连接
#尺寸变化:比如一组训练样本为64,那么尺寸变化为64×84->64×10。最后,64×10的矩阵经过softmax之后就得出了64张图片分类于每种数字的概率,
#即得到最后的分类结果。
with tf.variable_scope('layer7-fc3'):
fc3_weights = tf.get_variable('weight',[84,10],initializer=tf.truncated_normal_initializer(stddev=0.1))
if regularizer != None:
tf.add_to_collection('losses',regularizer(fc3_weights))
fc3_biases = tf.get_variable('bias',[10],initializer=tf.truncated_normal_initializer(stddev=0.1))
logit = tf.matmul(fc2,fc3_weights) + fc3_biases
return logit
#正则化,交叉熵,平均交叉熵,损失函数,最小化损失函数,预测和实际equal比较,tf.equal函数会得到True或False,
#accuracy首先将tf.equal比较得到的布尔值转为float型,即True转为1.,False转为0,最后求平均值,即一组样本的正确率。
#比如:一组5个样本,tf.equal比较为[True False True False False],转化为float型为[1. 0 1. 0 0],准确率为2./5=40%。
'''规则化可以帮助防止过度配合,提高模型的适用性。(让模型无法完美匹配所有的训练项。)(使用规则来使用尽量少的变量去拟合数据)
规则化就是说给需要训练的目标函数加上一些规则(限制),让他们不要自我膨胀。
TensorFlow会将L2的正则化损失值除以2使得求导得到的结果更加简洁
如tf.contrib.layers.apply_regularization/l1_regularizer/l2_regularizer/sum_regularizer
https://blog.csdn.net/liushui94/article/details/73481112
sparse_softmax_cross_entropy_with_logits()是将softmax和cross_entropy放在一起计算
https://blog.csdn.net/ZJRN1027/article/details/80199248'''
regularizer = tf.contrib.layers.l2_regularizer(0.001)
y = inference(x,False,regularizer)
cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y,labels=y_)
cross_entropy_mean = tf.rece_mean(cross_entropy)
loss = cross_entropy_mean + tf.add_n(tf.get_collection('losses'))
train_op = tf.train.AdamOptimizer(0.001).minimize(loss)
correct_prediction = tf.equal(tf.cast(tf.argmax(y,1),tf.int32),y_)
accuracy = tf.rece_mean(tf.cast(correct_prediction,tf.float32))
#每次获取batch_size个样本进行训练或测试
def get_batch(data,label,batch_size):
for start_index in range(0,len(data)-batch_size+1,batch_size):
slice_index = slice(start_index,start_index+batch_size)
yield data[slice_index],label[slice_index]
#创建Session会话
with tf.Session() as sess:
#初始化所有变量(权值,偏置等)
sess.run(tf.global_variables_initializer())
#将所有样本训练10次,每次训练中以64个为一组训练完所有样本。
#train_num可以设置大一些。
train_num = 10
batch_size = 64
for i in range(train_num):
train_loss,train_acc,batch_num = 0, 0, 0
for train_data_batch,train_label_batch in get_batch(train_data,train_label,batch_size):
_,err,acc = sess.run([train_op,loss,accuracy],feed_dict={x:train_data_batch,y_:train_label_batch})
train_loss+=err;train_acc+=acc;batch_num+=1
print("train loss:",train_loss/batch_num)
print("train acc:",train_acc/batch_num)
test_loss,test_acc,batch_num = 0, 0, 0
for test_data_batch,test_label_batch in get_batch(test_data,test_label,batch_size):
err,acc = sess.run([loss,accuracy],feed_dict={x:test_data_batch,y_:test_label_batch})
test_loss+=err;test_acc+=acc;batch_num+=1
print("test loss:",test_loss/batch_num)
print("test acc:",test_acc/batch_num)
⑤ 深度学习为什么不过拟合
深度学习:过拟合
为了得到一致假设而使假设变得过度复杂称为过拟合。想象某种学习算法产生了一个过拟合的分类器,这个分类器能够百分之百的正确分类样本数据(即再拿样本中的文档来给它,它绝对不会分错),但也就为了能够对样本完全正确的分类,使得它的构造如此精细复杂,规则如此严格,以至于任何与样本数据稍有不同的文档它全都认为不属于这个类别。
标准定义:给定一个假设空间H,一个假设h属于H,如果存在其他的假设h’属于H,使得在训练样例上h的错误率比h’小,但在整个实例分布上h’比h的错误率小,那么就说假设h过度拟合训练数据。 —-《Machine Learning》Tom M.Mitchell
假设我们用深度学习来判断西瓜,过拟合会使得你判断西瓜更加严厉,导致在某些西瓜数据上与你准备的数据有些出入(差别并不会太大),从而结果判定不是西瓜。。。
-----------------
深度学习防止过拟合的方法
过拟合即在训练误差很小,而泛化误差很大,因为模型可能过于的复杂,使其”记住”了训练样本,然而其泛化误差却很高,在传统的机器学习方法中有很大防止过拟合的方法,同样这些方法很多也适合用于深度学习中,同时深度学习中又有一些独特的防止过拟合的方法,下面对其进行简单的梳理.
1. 参数范数惩罚
范数正则化是一种非常普遍的方法,也是最常用的方法,假如优化:
minObj(θ)=L(y,f(x))+αG(θ)
其中L为经验风险,其为在训练样本上的误差,而G为对参数的惩罚,也叫结构风险.α是平衡两者,如果太大则对应的惩罚越大,如过太小,甚至接近与0,则没有惩罚.
最常用的范数惩罚为L1,L2正则化,L1又被成为Lasso:
||w||1=|w1|+|w2|+...
即绝对值相加,其趋向于是一些参数为0.可以起到特征选择的作用.
L2正则化为:
||w||2=w12+w22+...−−−−−−−−−−−−√
其趋向与,使权重很小.其又成为ridge.
关于更多可以参考:机器学习中的范数规则化之(一)L0、L1与L2范数
2. 数据增强
让模型泛化的能力更好的最好办法就是使用更多的训练数据进行训练,但是在实践中,我们拥有的数据是有限的,解决这一问题可以人为的创造一些假数据添加到训练集中.
一个具体的例子:
在AlexNet中,将256*256图像随机的截取224*224大小,增加了许多的训练样本,同时可以对图像进行左右翻转,增加样本的个数,实验的结果可以可降低1%的误差.
在神经网络中输入噪声也可以看做是数据增强的一种方式.
3. 提前终止
如下图所示(图片来源deep learning),当随着模型的能力提升,训练集的误差会先减小再增大,这样可以提前终止算法减缓过拟合现象.关于算法的具体流程参考deep learning.
提前终止是一种很常用的缓解过拟合的方法,如在决策树的先剪枝的算法,提前终止算法,使得树的深度降低,防止其过拟合.
4. 参数绑定与参数共享
在卷积神经网络CNN中(计算机视觉与卷积神经网络 ),卷积层就是其中权值共享的方式,一个卷积核通过在图像上滑动从而实现共享参数,大幅度减少参数的个数,用卷积的形式是合理的,因为对于一副猫的图片来说,右移一个像素同样还是猫,其具有局部的特征.这是一种很好的缓解过拟合现象的方法.
同样在RNN中用到的参数共享,在其整条时间链上可以进行参数的共享,这样才使得其能够被训练.
5. bagging 和其他集成方法
其实bagging的方法是可以起到正则化的作用,因为正则化就是要减少泛化误差,而bagging的方法可以组合多个模型起到减少泛化误差的作用.
在深度学习中同样可以使用此方法,但是其会增加计算和存储的成本.
6. Dropout
Dropout提供了一种廉价的Bagging集成近似,能够训练和评估指数级数量的神经网络。dropout可以随机的让一部分神经元失活,这样仿佛是bagging的采样过程,因此可以看做是bagging的廉价的实现.
但是它们训练不太一样,因为bagging,所有的模型都是独立的,而dropout下所有模型的参数是共享的.
通常可以这样理解dropout:假设我们要判别一只猫,有一个神经元说看到有毛就是猫,但是如果我让这个神经元失活,它还能判断出来是猫的话,这样就比较具有泛化的能力,减轻了过拟合的风险.
7. 辅助分类节点(auxiliary classifiers)
在Google Inception V1中,采用了辅助分类节点的策略,即将中间某一层的输出用作分类,并按一个较小的权重加到最终的分类结果中,这样相当于做了模型的融合,同时给网络增加了反向传播的梯度信号,提供了额外的正则化的思想.
8. Batch Normalization
在Google Inception V2中所采用,是一种非常有用的正则化方法,可以让大型的卷积网络训练速度加快很多倍,同事收敛后分类的准确率也可以大幅度的提高.
BN在训练某层时,会对每一个mini-batch数据进行标准化(normalization)处理,使输出规范到N(0,1)的正太分布,减少了Internal convariate shift(内部神经元分布的改变),传统的深度神经网络在训练是,每一层的输入的分布都在改变,因此训练困难,只能选择用一个很小的学习速率,但是每一层用了BN后,可以有效的解决这个问题,学习速率可以增大很多倍.
未完待续…
参考资料:
deep learning
tensorflow实战
机器学习中的范数规则化之(一)L0、L1与L2范数
⑥ 联合检测恶意域和受感染的客户端
感染恶意软件的计算机的连接和基于加密的HTTPS流量的恶意web域的检测是具有挑战性的问题,因为只有地址、时间戳和数据量是可见的。检测问题是耦合的,因为受感染的客户端往往与恶意域交互。流量数据可以大规模收集,反病毒工具可以用来识别受感染的客户端。相反,域必须在取证分析后单独标记。探讨了基于闸网络的转移学习方法;这使得检测模型来引导对方。在一项大规模的实验研究中,我们发现该模型比已知的参考模型性能更好,可以检测到以前未知的恶意软件、以前未知的恶意软件家族和以前未知的恶意域。
1介绍
恶意软件侵犯了用户的隐私,获取密码和个人信息,可以加密用户的文件索取赎金,用于实施点击欺诈,并通过在社交媒体上推广特定内容来促进政治议程(Kogan, 2015)。基于客户机的防病毒工具使用特定于供应商的混合方法,包括基于签名的分析、可移植可执行文件的静态分析、仿真(在实际操作系统中执行之前不访问实际系统资源的部分执行)和基于动态行为的分析来检测恶意软件(Swinnen和Mesbahi, 2014)。网络流量分析是杀毒软件的补充,广泛应用于企业网络。流量分析允许组织在整个网络中一致地实施可接受使用和安全策略,并最小化管理开销。流量分析使得将恶意软件检测封装到网络设备或云服务中成为可能,这些设备或云服务可以检测多态恶意软件(Karim et al., 2005)以及基于URL模式(Bartos和Sofka, 2015)的未知恶意软件。
然而,恶意软件可以很容易地阻止分析其HTTP有效载荷使用加密的HTTPS协议。HTTPS本身的使用并不引人注目,因为谷歌、Facebook、LinkedIn和许多其他流行的网站默认加密它们的网络流量,而且HTTPS的全球数据量已经超过了HTTP (Finley, 2017)。为了对HTTPS流量进行网络流量分析,现在的组织必须对其网络进行配置,以便所有web流量都通过web安全服务器进行路由。该服务器的根证书必须作为可信证书安装在所有客户端计算机上,这允许服务充当客户端和主机之间的中间人。它可以解密、检查和重新加密HTTPS请求。这种方法在大型网络上的伸缩性很差,因为加密操作的计算开销很大,而且会给网络带来潜在的漏洞。
在不破坏加密的情况下,HTTPS流量的观察者只能看到客户端和主机的IP地址和端口,以及数据包的时间戳和数据量。网络设备将一对IP地址和端口之间交换的TCP/IP数据包聚合到网络流中,地址、时间和数据量信息保存到日志文件中。大多数情况下,观察者还可以看到未加密的主机域名。HTTP有效负载(包括HTTP头字段和URL)被加密。
网络主机参与了广泛的非法活动,将已知的恶意域和IP地址的流量列入黑名单是对抗恶意软件的有效机制。恶意域可以承载银行木马和金融诈骗、点击欺诈服务器或恶意内容分发中心的后端。将一个域识别为恶意需要一个复杂的取证分析。分析人员必须收集关于承载域、软件和使用的技术的服务器的信息,并且可以研究域和共同承载域的所有权,以及观察主机的行为。
由于许多类型的恶意活动涉及与基于客户机的恶意软件的交互,因此检测恶意主机和受感染的客户机是耦合问题。在神经网络环境中,相关任务的标记数据常常被设计成共享部分参数的耦合网络。在水闸网络中(Ruder et al., 2017),参数共享的程度本身由参数控制,这使得辅助数据可以作为手头任务的灵活先验。
本文其余部分的结构如下。第二节回顾相关工作。我们在第3节中描述我们的操作环境和数据,在第4节中描述问题设置。在第5节中,我们推导了恶意软件和恶意域的联合检测模型,并描述了参考方法。第六部分是实验,第七部分是结论。
2相关工作
之前的HTTP日志分析工作(Nguyen和Armitage, 2008)已经解决了识别命令和控制服务器(Nelms et al., 2013)、无监督检测恶意软件(Kohout和Pevny, 2015b;Bartos等人,2016),并监督检测恶意软件使用领域黑名单作为标签(Franc等人,2015;Bartos and Sofka, 2015)。HTTP日志文件包含完整的URL字符串,从中可以提取大量的信息特性(Bartos和Sofka, 2015)。
最近的大量工作都是通过网络流量分析来检测Android恶意软件。Arora等人(2014)使用平均包大小、平均流持续时间和一小组其他特征来识别一小组48个恶意Android应用程序,具有一定的准确性。Lashkari等(2015)收集了1500个良性和400个恶意的Android应用程序,提取了流量持续时间和流量特征,并从Weka库中应用了几种机器学习算法。他们观察到个别流量水平的高精度值。Demontis等人(2018)针对这种检测机制建立了不同类型的攻击模型,并设计了一个特征学习范式来缓解这些攻击。Malik和Kaushal(2016)通过众包领域声誉服务(信任网络)和应用程序的资源许可来汇总应用程序的排名。
之前关于HTTPS日志的工作旨在识别应用层协议(Wright et al., 2006;Crotti et al., 2007;Dusi等人,2009)。为了对承载类似应用程序的web服务器进行集群化,Kohout和Pevny (2015a)开发了从可见时间间隔和连接数据量的直方图派生出来的特性。Lokoc等人(2016)利用这种特征表示,开发了一个近似的k-NN分类器来识别被恶意软件连接的服务器。被恶意软件联系的主机不一定是恶意的。恶意软件使用URL转发和其他技术,通过合法的主机路由其流量,并可能联系合法的服务,只是为了稀释其网络流量。不过,我们将使用直方图特征作为参考特征表示。
基于图的分类方法(如Anderson et al., 2011)已经被探索过,但不能应用到我们的操作环境中。在我们的操作环境中,云Web安全服务器只观察组织内的网络流量。为了感知网络图的一个重要部分,公司将不得不交换他们的网络流量数据,这在逻辑和隐私方面是不切实际的。
之前关于网络流分析的神经网络的工作(Pevny和Somol, 2016)使用客户端计算机的标签(已感染和未感染)——这导致了一个多实例学习问题。相比之下,我们的操作环境允许我们观察流和可执行文件之间的关联。利用域名的word2vec嵌入和长短期内存网络(LSTMs)相结合的方法,研究了来自HTTPS流量的恶意软件检测(Prasse et al., 2017)。我们将把这种方法作为实验的参考。最近的研究结果表明,卷积神经网络(CNNs)更强的鲁棒性超过了LSTMs考虑长期依赖关系的能力(Gehring et al., 2017)。这激发了我们对卷积架构的探索。神经网络也被应用于静态恶意软件分析(Pascanu et al., 2015)。
在深度学习环境中,多任务学习通常通过隐藏层的软、硬参数共享来实现。在硬参数共享中,所有任务的模型可以共享卷积层(Long and Wang, 2015),甚至所有隐层(Caruana, 1993),这可以显着增加用于优化大部分参数的样本量(Baxter, 1997)。相比之下,软参数共享可以作为分层贝叶斯建模在神经网络中的直接应用来实现:在所有任务中,每个参数都被正则化为其平均值(Duong et al., 2015;杨和Hospedales, 2016)。 Cross-stitch (Misra et al., 2016)和水闸网sluice networks络(Ruder et al., 2017)允许网络中不同部分的任务耦合程度由参数控制。水闸网络具有比十字绣网络更一般的形式,因为它们有额外的参数,允许特定任务的网络层加权。
神经网络的替代转移学习方法加强了在不同任务之间不变的中间表示(Ganin et al., 2016)。除了深度学习之外,lasso正则化器组还加强了子空间共享,并研究了多种用于多任务学习的方法,这些方法基于层次贝叶斯模型(如Finkel和Manning, 2009)、学习任务不变特征(如Argyriou等,2007)、任务相似核(Evgeniou等,2005)和学习实例特定权重(如Bickel等,2008)。
3操作环境
本节描述我们的应用程序环境。为了保护组织的所有计算机,云Web安全(CWS)服务提供了组织的私有网络和internet之间的接口。客户端计算机建立到CWS服务的VPN连接,来自组织内任何客户端的所有外部HTTP和HTTPS连接都将通过该服务进行路由。该服务可以基于主机域和组织的可接受使用策略阻止HTTP和HTTPS请求。CWS服务将阻止所有恶意域之间的所有流量。当在客户端检测到恶意软件时,它会发出警告。由于安全分析师必须处理恶意软件警告,所有发布的警告中,假警报的比例必须很小。
在应用层,HTTPS使用HTTP协议,但是所有消息都通过传输层安全性(TLS)协议或其前身安全套接字层(SSL)协议进行加密。CWS服务将单个客户端计算机、客户端端口、主机IP地址和主机端口之间的所有TCP/IP包聚合起来,这些包来自单个HTTP请求或HTTPS请求的TLS/SSL隧道到网络流。对于每个网络流,将一行写入日志文件,其中包括数据量、时间戳、客户机和主机地址以及持续时间信息。对于未加密的HTTP流量,这一行也包含完整的URL字符串。对于HTTPS流量,它包含域名——如果该名称可以通过以下机制之一观察到的话。
使用服务器名称指示协议扩展(SNI)的客户机在建立连接时发布未加密的主机域名。SNI被广泛使用,因为它需要验证承载多个域的服务器的证书,就像大多数web服务器一样。当网络使用透明的DNS代理(Blum和Lueker, 2001)时,该服务器缓存DNS请求-响应对,并可以将IP地址映射到以前解析的域名。日志文件行的结果序列作为恶意软件和恶意域检测模型的输入。
3.1数据收集
在我们的实验中,我们结合了大量的HTTPS网络流(Prasse et al., 2017),它们被标记为是否来自一个恶意的合法应用程序,以及一个由Cisco的取证专家维护的域黑名单。
Prasse等人(2017)收集了340个公司网络中通过CWS服务器的HTTPS网络流。这些网络中的客户机运行一个VPN客户机,该客户机监视进程表和网络接口,并记录哪个可执行文件创建每个网络流。回顾过去,可执行文件已经用多种防病毒工具进行了分析。结果数据集由已知客户端(由组织和VPN帐户标识)、域(完全合格的域名)、数据量和时间戳以及一个标签组成,该标签指示生成流量的应用程序是否被防病毒工具识别为恶意软件。我们按时间顺序对训练和测试数据进行分层。训练数据包含了2016年7月为期5天的171个小型到大型计算机网络的完整HTTPS流量。测试数据包含了2016年9月为期8天的169个不同计算机网络的完整HTTPS流量。思科的取证专家一直在调查可疑的主机名、二级域名和服务器IP地址,这些都被各种各样的机制标记过。这包括对托管软件和使用的技术、注册表记录、URL和流量模式的分析,以及对特定域可用的任何附加信息的分析。我们相信域几乎从不被错误地评定为恶意的,但是由于昂贵的分析过程,恶意域的黑名单必然是不完整的。所有来自或转至恶意服务的通讯都很容易被ws服务拦截。网络流量不包含任何流向在收集流量数据时已在我们的黑名单上的域的流量。流量数据集包含与4,340个恶意主机名、二级域名和服务器IP地址之间的网络流,这些恶意主机名、二级域名和服务器IP地址在收集数据后被添加到黑名单中。
3.2数据的定量分析
表1和表2总结了良性和恶意网络流、客户机计算机、受感染计算机、具有唯一散列的应用程序和组织的数量。
表3给出了最常见的恶意软件家族的统计数据。它列举了发生的变化的数量、受感染的客户机的数量,括号内是训练数据中受感染的客户机的数量。
总的来说,只有不到18000台电脑被恶意软件感染,并与当时未被列入黑名单的域名进行通信,这几乎相当于0.6%。
在流量数据中,记录流量数据后加入黑名单的域名有4340个。表4详细列出了所有数据和训练数据中出现的恶意主机名、二级域和服务器IP地址的类型。
⑦ CNN和Transformer相结合的模型
©作者 | 小欣
CNN广泛应用于计算机视觉的各种任务中,比如分类,检测,分割,CNN通过共享卷积核提取特征,减少网络参数数量,提高模型效率,另一方面CNN具有平移不变性,即无论特征被移动到图像的哪个位置,网络都能检测到这些特征。
尽管CNN存在很多优势,但是其感受野通常很小,不利于捕获全局特征。
视觉Transformer由于能够捕获一张图片的全局信息,因此在许多视觉任务中超越许多CNN结构。
ViT是第一个替代CNN,使用纯Transformer的结构,输入一张224×224×3的图片,ViT将其分成14×14=196个非重叠的patches,每个patch的大小是16×16×3,然后将这些patch输入到堆叠的多个transformer编码器中。
CNN的成功依赖于其两个固有的归纳偏置,即平移不变性和局部相关性,而视觉Transformer结构通常缺少这种特性,导致通常需要大量数据才能超越CNN的表现,CNN在小数据集上的表现通常比纯Transformer结构要好。
CNN感受野有限导致很难捕获全局信息,而Transformer可以捕获长距离依赖关系,因此ViT出现之后有许多工作尝试将CNN和Transformer结合,使得网络结构能够继承CNN和Transformer的优点,并且最大程度保留全局和局部特征。
Transformer是一种基于注意力的编码器-解码器结构,最初应用于自然语言处理领域,一些研究最近尝试将Transformer应用到计算机视觉领域。
在Transformer应用到视觉之前,卷积神经网络是主要研究内容。受到自注意力在NLP领域的影响,一些基于CNN的结构尝试通过加入自注意力层捕获长距离依赖关系,也有另外一些工作直接尝试用自注意力模块替代卷积,但是纯注意力模块结构仍然没有最先进的CNN结构表现好。
Transformer中有两个主要部分,多头自注意力层和全连接层,最近,Cordonnier et al.在研究中表明卷积可以通过使用多头自注意力层达到同样的效果。
Transformer 理论上比CNN能得到更好的模型表现,但是因为计算全局注意力导致巨大的计算损失,特别是在浅层网络中,特征图越大,计算复杂度越高,因此一些方法提出将Transformer插入到CNN主干网络中,或者使用一个Transformer模块替代某一个卷积模块。
BoTNet.[1] 通过使用Multi-Head Self-Attention(MHSA)替代ResNet Bottleneck中的3×3卷积,其他没有任何改变,形成新的网络结构,称为Bottleneck Transformer,相比于ResNet等网络提高了在分类,目标检测等任务中的表现,在ImageNet分类任务中达到84.7%的准确率,并且比EfficientNet快1.64倍。
BoTNet中使用的MHSA和Transformer中的MHSA有一定的区别,首先,BoTNet中使用Batch Normalization,而Transformer中使用Layer Normalization,其次,Transformer中使用一个在全连接层中使用一个非线性激活,BoT(Bottleneck Transformer)模块中使用三个非线性激活,最后Transformer中的MHSA模块包含一个输出映射,而BoT中的MHSA没有。
CNN有局部性和平移不变性,局部性关注特征图中相邻的点,平移不变性就是对于不同区域使用相同的匹配规则,虽然CNN的归纳偏差使得网络在少量数据上表现较好,但是这也限制了在充分数据上的表现,因此有一些工作尝试将CNN的归纳偏差引入Transformer加速网络收敛。
DeiT.[2] 为了减小ViT对于大量数据的依赖,Touvron et al.提出了Data-efficient image Transformer(Deit),提高网络在小量数据上的表现,通过使用数据增强和正则化技术,与此同时还引入了蒸馏策略,即使用一个教师网络去指导学生网络,通常来说使用CNN要比Transformer作为教师模型效果要好,CNN模型可以将其归纳偏置引入到Transformer。
作者使用两种蒸馏方式,一种是硬蒸馏,一种是软蒸馏 ,软蒸馏通过计算学生模型和教师模型分别经过softmax之后的KL散度,硬蒸馏通过使用教师模型的预测作为真实标签。
DeiT中引入了一个新的distillation token,和class token的作用类似,和其他token之间通过自注意力交互,作者发现class token和distillation token会收敛于不同的向量,余弦距离为0.06,说明这两个token希望得到相似但不相同的目标,为了证明distillation token的有效性是由于知识蒸馏的作用,通过对比实验将distillation token换成class token,就是使用两个class token,最终效果不如加入distillation token。
对比卷积神经网络和Transformer在Imagenet上的分类表现:
ConViT.[3] 通过引入gated positional self-attention(GPSA)层模仿卷积层带来的局部性,将GPSA替代一部分 self-attention层,然后每一个注意力头通过调整可学习的门控参数来调整对于位置信息和上下文信息的关注程度。GPSA层的输出可以表示为:
其中,
是一个可学习的向量去模仿卷积,
是一个固定的相对位置编码,
是一个可学习门控参数去调整对上下文和位置信息的关注程度。
Cordonnier et al.[4] 在论文中证明多头自注意机制可通过调整头的数量和可学习的位置编码来近似达到卷积层的效果。
对比ConViT和DeiT在Imagenet-1k上的表现,以及不同大小训练集对结果的影响
CeiT.[5] 改变了patch到token的方式,先将图片通过卷积和最大池化再切分成patch,最开始对图片使用卷积操作可以捕获图片的低级特征,即I2
并且使用了Layer-wise class token Attention(LCA)去结合多层特征,提出了Locally-Enhanced Feed-Forward Netword(LeFF),将最开始的全连接层(Feed-forward network)替换成了LeFF层,MSA(Multi-head self-attention)层保持不变,用于捕获全局信息,LeFF层用于捕获局部信息,最终的效果要比DeiT好。
Early Conv.[6] Xiao et al.通过使用多个步长为2的3×3卷积核替代ViT中最初的stem(步长为16的16×16卷积),使得网络在ImageNet-1k上取得1-2%的提高,并且稳定性和泛化能力在下游任务中都有所提高,对于学习率的选择和优化器的选择没有那么敏感,并且收敛速度也更快。
这篇文章表面在ViT模型中使用一个小的卷积核相比于最初的ViT使得模型有更好的泛化能力。
CoAtNet.[7] Dai et al. 提出a Convolution and Attention NetWord(CoAtNet),通过引入深度卷积到注意力模块中,深度卷积中一个卷积核负责一个通道,一个通道只被一个卷积核计算,相比于正常卷积,其参数和运算成本相对比较低,在浅层网络中堆叠卷积层,比较了不同的堆叠方式,比如C-C-C-T,C-T-T-T,C-C-C-T,其中C代表卷积模块,T代表Transformer模块。
通过综合考虑模型泛化能力,迁移能力,模型在训练集上的表现,最后使用C-C-T-T 这种堆叠方式。在没有额外训练数据的情况下,CoAtNet达到了86%的准确率,在ImageNet-21K上预训练时,达到了88.56%的准确率。
参考文献
[1] A. Srinivas, T.-Y. Lin, N. Parmar, J. Shlens, P. Abbeel, and A. Vaswani, “Bottleneck transformers for visual recognition.” in Proc. CVPR, 2021.
[2] H. Touvron, M. Cord, D. Matthijs, F. Massa, A. Sablayrolles, and H. Jegou, “Training data-effificient image transformers & distillation through attention,” in Proc. ICLR, 2021.
[3] S. d’Ascoli, H. Touvron, M. Leavitt, A. Morcos, G. Biroli, and L. Sa gun, “Convit: Improving vision transformers with soft convolutional inctive biases,” in Proc. ICLR, 2021.
[4] Cordonnier, J.-B., Loukas, A., and Jaggi, M. On the relationship between self-attention and convolutional layers. arXiv preprint arXiv:1911.03584, 2019.
[5] K. Yuan, S. Guo, Z. Liu, A. Zhou, F. Yu, and W. Wu, “Incorporating convolution designs into visual transformers,” in Proc. ICCV, 2021.
[6] T. Xiao, M. Singh, E. Mintun, T. Darrell, P. Dollar, and R. B. Girshick, “Early convolutions help transformers see better,” ArXiv, vol. abs/2106.14881, 2021.
[7] Z. Dai, H. Liu, Q. V. Le, and M. Tan, “Coatnet: Marrying convolution and attention for all data sizes,” arXiv preprint arXiv:2106.04803, 2021.
私信我领取 目标检测与R-CNN/数据分析的应用/电商数据分析/数据分析在医疗领域的应用/NLP学员项目展示/中文NLP的介绍与实际应用/NLP系列直播课/NLP前沿模型训练营等 干货学习资源。
⑧ 循环神经网络
花书中关于RNN的内容记录于 https://www.jianshu.com/p/206090600f13 。
在前馈神经网络中,信息的传递是单向的,这种限制虽然使得网络变得更容易学习,但在一定程度上也减弱了神经网络模型的能力。在生物神经网络中,神经元之间的连接关系要复杂的多。 前馈神经网络可以看作是一个复杂的函数,每次输入都是独立的,即网络的输出只依赖于当前的输入。但是在很多现实任务中,网络的输入不仅和当前时刻的输入相关,也和其过去一段时间的输出相关 。因此,前馈网络难以处理时序数据,比如视频、语音、文本等。时序数据的长度一般是不固定的,而前馈神经网络要求输入和输出的维数都是固定的,不能任意改变。因此,当处理这一类和时序相关的问题时,就需要一种能力更强的模型。
循环神经网络(Recurrent Neural Network,RNN)是一类具有短期记忆能力的神经网络。在循环神经网络中,神经元不但可以接受其它神经元的信息,也可以接受自身的信息,形成具有环路的网络结构。 和前馈神经网络相比,循环神经网络更加符合生物神经网络的结构。循环神经网络已经被广泛应用在语音识别、语言模型以及自然语言生成等任务上。循环神经网络的参数学习可以通过 随时间反向传播算法 来学习。
为了处理这些时序数据并利用其历史信息,我们需要让网络具有短期记忆能力。而前馈网络是一个静态网络,不具备这种记忆能力。
一种简单的利用历史信息的方法是建立一个额外的延时单元,用来存储网络的历史信息(可以包括输入、输出、隐状态等)。比较有代表性的模型是延时神经网络。
延时神经网络是在前馈网络中的非输出层都添加一个延时器,记录最近几次神经元的输出。在第 个时刻,第 层神经元和第 层神经元的最近 次输出相关,即:
延时神经网络在时间维度上共享权值,以降低参数数量。因此对于序列输入来讲,延时神经网络就相当于卷积神经网络 。
自回归模型(Autoregressive Model,AR) 是统计学上常用的一类时间序列模型,用一个变量 的历史信息来预测自己:
其中 为超参数, 为参数, 为第 个时刻的噪声,方差 和时间无关。
有外部输入的非线性自回归模型(Nonlinear Autoregressive with ExogenousInputs Model,NARX) 是自回归模型的扩展,在每个时刻 都有一个外部输入 ,产生一个输出 。NARX通过一个延时器记录最近几次的外部输入和输出,第 个时刻的输出 为:
其中 表示非线性函数,可以是一个前馈网络, 和 为超参数。
循环神经网络通过使用带自反馈的神经元,能够处理任意长度的时序数据。
给定一个输入序列 ,循环神经网络通过下面
公式更新带反馈边的隐藏层的活性值 :
其中 , 为一个非线性函数,也可以是一个前馈网络。
从数学上讲,上式可以看成一个动力系统。动力系统(Dynamical System)是一个数学上的概念,指 系统状态按照一定的规律随时间变化的系统 。具体地讲,动力系统是使用一个函数来描述一个给定空间(如某个物理系统的状态空间)中所有点随时间的变化情况。因此, 隐藏层的活性值 在很多文献上也称为状态(State)或隐状态(Hidden States) 。理论上,循环神经网络可以近似任意的非线性动力系统。
简单循环网络(Simple Recurrent Network,SRN)是一个非常简单的循环神经网络,只有一个隐藏层的神经网络。
在一个两层的前馈神经网络中,连接存在相邻的层与层之间,隐藏层的节点之间是无连接的。而 简单循环网络增加了从隐藏层到隐藏层的反馈连接 。
假设在时刻 时,网络的输入为 ,隐藏层状态(即隐藏层神经元活性值) 不仅和当前时刻的输入 相关,也和上一个时刻的隐藏层状态 相关:
其中 为隐藏层的净输入, 是非线性激活函数,通常为Logistic函数或Tanh函数, 为状态-状态权重矩阵, 为状态-输入权重矩阵, 为偏置。上面两式也经常直接写为:
如果我们把每个时刻的状态都看作是前馈神经网络的一层的话,循环神经网络可以看作是在时间维度上权值共享的神经网络 。下图给出了按时间展开的循环神经网络。
由于循环神经网络具有短期记忆能力,相当于存储装置,因此其计算能力十分强大。 前馈神经网络可以模拟任何连续函数,而循环神经网络可以模拟任何程序。
定义一个完全连接的循环神经网络,其输入为 ,输出为 :
其中 为隐状态, 为非线性激活函数, 和 为网络参数。
这样一个完全连接的循环神经网络可以近似解决所有的可计算问题 。
循环神经网络可以应用到很多不同类型的机器学习任务。根据这些任务的特点可以分为以下几种模式: 序列到类别模式、同步的序列到序列模式、异步的序列到序列模式 。
序列到类别模式主要用于序列数据的分类问题:输入为序列,输出为类别。比如在文本分类中,输入数据为单词的序列,输出为该文本的类别。
假设一个样本 为一个长度为 的序列,输出为一个类别 。我们可以将样本 按不同时刻输入到循环神经网络中,并得到不同时刻的隐藏状态 。我们可以将 看作整个序列的最终表示(或特征),并输入给分类器 进行分类:
其中 可以是简单的线性分类器(比如Logistic 回归)或复杂的分类器(比如多层前馈神经网络)
除了将最后时刻的状态作为序列表示之外,我们还可以对整个序列的所有状态进行平均,并用这个平均状态来作为整个序列的表示:
同步的序列到序列模式 主要用于序列标注(Sequence Labeling)任务,即每一时刻都有输入和输出,输入序列和输出序列的长度相同 。比如词性标注(Partof-Speech Tagging)中,每一个单词都需要标注其对应的词性标签。
输入为序列 ,输出为序列 。样本 按不同时刻输入到循环神经网络中,并得到不同时刻的隐状态 。每个时刻的隐状态 代表当前和历史的信息,并输入给分类器 得到当前时刻的标签 。
异步的序列到序列模式也称为 编码器-解码器(Encoder-Decoder)模型,即输入序列和输出序列不需要有严格的对应关系,也不需要保持相同的长度。 比如在机器翻译中,输入为源语言的单词序列,输出为目标语言的单词序列。
在异步的序列到序列模式中,输入为长度为 的序列 ,输出为长度为 的序列 。经常通过 先编码后解码 的方式来实现。先将样本 按不同时刻输入到一个循环神经网络(编码器)中,并得到其编码 。然后再使用另一个循环神经网络(解码器)中,得到输出序列 。为了建立输出序列之间的依赖关系,在解码器中通常使用非线性的自回归模型。
其中 分别为用作编码器和解码器的循环神经网络, 为分类器, 为预测输出 的向量表示。
循环神经网络的参数可以通过梯度下降方法来进行学习。给定一个训练样本 ,其中 为长度是 的输入序列, 是长度为 的标签序列。即在每个时刻 ,都有一个监督信息 ,我们定义时刻 的损失函数为:
其中 为第 时刻的输出, 为可微分的损失函数,比如交叉熵。那么整个序列上损失函数为:
整个序列的损失函数 关于参数 的梯度为:
即每个时刻损失 对参数 的偏导数之和。
循环神经网络中存在一个递归调用的函数 ,因此其计算参数梯度的方式和前馈神经网络不太相同。在循环神经网络中主要有两种计算梯度的方式: 随时间反向传播(BPTT)和实时循环学习(RTRL)算法。
随时间反向传播(Backpropagation Through Time,BPTT) 算法的主要思想是通过类似前馈神经网络的错误反向传播算法来进行计算梯度。
BPTT算法将循环神经网络看作是一个展开的多层前馈网络,其中“每一层”对应循环网络中的“每个时刻”。在“展开”的前馈网络中,所有层的参数是共享的,因此参数的真实梯度是将所有“展开层”的参数梯度之和 。
因为参数 和隐藏层在每个时刻 的净输入 有关,因此第 时刻的损失函数 关于参数 的梯度为:
其中 表示“直接”偏导数,即公式 中保持 不变,对 求偏导数,得到:
其中 为第 时刻隐状态的第 维; 除了第 个值为 外,其余都为 的行向量。
定义误差项 为第 时刻的损失对第 时刻隐藏神经层的净输入 的导数,则:
从而:
写成矩阵形式为:
由此得到整个序列的损失函数 关于参数 的梯度:
同理可得, 关于权重 和偏置 的梯度为:
在BPTT算法中,参数的梯度需要在一个完整的“前向”计算和“反向”计算后才能得到并进行参数更新。如下图所示。
与反向传播的BPTT算法不同的是,实时循环学习(Real-Time Recurrent Learning)是通过前向传播的方式来计算梯度。
假设循环神经网络中第 时刻的状态 为:
其关于参数 的偏导数为:
RTRL算法从第1 个时刻开始,除了计算循环神经网络的隐状态之外,还依次前向计算偏导数 。
两种学习算法比较:
RTRL算法和BPTT算法都是基于梯度下降的算法,分别通过前向模式和反向模式应用链式法则来计算梯度。 在循环神经网络中,一般网络输出维度远低于输入维度,因此BPTT算法的计算量会更小,但BPTT算法需要保存所有时刻的中间梯度,空间复杂度较高。RTRL算法不需要梯度回传,因此非常适合于需要在线学习或无限序列的任务中 。
循环神经网络在学习过程中的主要问题是由于 梯度消失或爆炸问题 ,很难建模长时间间隔(Long Range)的状态之间的依赖关系。
在BPTT算法中,我们有:
如果定义 ,则:
若 ,当 时, ,会造成系统不稳定,称为梯度爆炸问题;相反,若 ,当 时, ,会出现和深度前馈神经网络类似的梯度消失问题。
虽然简单循环网络理论上可以建立长时间间隔的状态之间的依赖关系,但是由于梯度爆炸或消失问题,实际上只能学习到短期的依赖关系。这样,如果t时刻的输出 依赖于 时刻的输入 ,当间隔 比较大时,简单神经网络很难建模这种长距离的依赖关系,称为 长程依赖问题(Long-Term dependencies Problem) 。
一般而言,循环网络的梯度爆炸问题比较容易解决,一般 通过权重衰减或梯度截断来避免。 权重衰减是通过给参数增加 或 范数的正则化项来限制参数的取值范围,从而使得 。梯度截断是另一种有效的启发式方法,当梯度的模大于一定阈值时,就将它截断成为一个较小的数。
梯度消失是循环网络的主要问题。除了使用一些优化技巧外,更有效的方式就是改变模型,比如让 ,同时使用 ,即:
其中 是一个非线性函数, 为参数。
上式中, 和 之间为线性依赖关系,且权重系数为1,这样就不存在梯度爆炸或消失问题。但是,这种改变也丢失了神经元在反馈边上的非线性激活的性质,因此也降低了模型的表示能力。
为了避免这个缺点,我们可以采用一种更加有效的改进策略:
这样 和 之间为既有线性关系,也有非线性关系,并且可以缓解梯度消失问题。但这种改进依然存在两个问题:
为了解决这两个问题,可以通过引入 门控机制 来进一步改进模型。
为了改善循环神经网络的长程依赖问题,一种非常好的解决方案是引入门控机制来控制信息的累积速度,包括 有选择地加入新的信息,并有选择地遗忘之前累积的信息 。这一类网络可以称为基于门控的循环神经网络(Gated RNN)。本节中,主要介绍两种基于门控的循环神经网络: 长短期记忆网络和门控循环单元网络。
长短期记忆(Long Short-Term Memory,LSTM)网络 是循环神经网络的一个变体,可以有效地解决简单循环神经网络的梯度爆炸或消失问题。
在 基础上,LSTM网络主要改进在以下两个方面:
其中 和 三个门(gate)来控制信息传递的路径; 为向量元素乘积; 为上一时刻的记忆单元; 是通过非线性函数得到的候选状态:
在每个时刻 ,LSTM网络的内部状态 记录了到当前时刻为止的历史信息。
在数字电路中,门(Gate)为一个二值变量{0, 1},0代表关闭状态,不许任何信息通过;1代表开放状态,允许所有信息通过。LSTM网络中的“门”是一种“软”门,取值在(0, 1) 之间,表示 以一定的比例运行信息通过 。LSTM网络中三个门的作用为:
(1)遗忘门 控制上一个时刻的内部状态 需要遗忘多少信息。
(2)输入门 控制当前时刻的候选状态 有多少信息需要保存。
(3)输出门