DeepLearning-CheatSheet
DeepLearning CheatSheet | 深度学习概念备忘
深度学习正在逐步地改变世界,从网络搜索、广告推荐这样传统的互联网业务到健康医疗、自动驾驶等不同的行业领域。百年前的电气革命为社会带来了新的支柱产业,而如今 AI 正是新时代的电力基础,驱动社会技术的快速发展。
对于支持向量机、Logistics 回归这样经典的机器学习算法而言,在数据量从零递增的初始阶段,其性能会不断提升;不过很快就会触碰到天花板,此时性能很难再随着数据集的增长而提升。而伴随着移动互联网时代的到来,我们能够从网站、移动应用或者其他安装在电子终端设备上的传感器中获取到海量的数据;这些数据在开启大数据时代的同时也为深度学习的发展提供了坚实的基础。我们在上图中也可以看出,越是大型的神经网络随着数据量的增加,其性能提升的越快,并且其性能天花板也是越高。
深度学习崛起的另一个重要基石就是计算能力的提升,这里不仅指新一代 CPU 或者 GPU 设备,还有是在许多基础优化算法上的革新,都使得我们能够更快地训练出神经网络。譬如早期我们会使用 Sigmod 函数作为神经网络的激活函数,随着 x 的增大其梯度会逐渐趋近于零,这就导致了模型收敛变得相对缓慢;而 ReLU 则能较好地避免这个问题,其在正无穷大时梯度值依然保持恒定。简单地从 Sigmod 函数迁移到 ReLU 即能够为模型训练带来极大的效率提升,这也方便了我们构建出更复杂的神经网络。
神经网络的分类很多,不过截止到目前大多数的有价值的神经网络都还是基于机器学习中所谓的有监督学习(Supervised Learning)。在有监督学习中,我们的训练数据集中已知了特征与结果输出之间的对应关系,而目标就是寻找正确的输入与输出之间的关系表示。譬如目前最赚钱的深度学习应用之一,在线广告中就是输入有关于网站展示的信息以及部分用户的信息,神经网络会预测用户是否会点击该广告;通过为不同的用户展示他们最感兴趣的广告,来增加用户的实际点击率。
深度学习是目前实现图像识别、语音识别类任务的最佳技术路线,至于自然语言处理、商业趋势的分析预测等场景虽然都取得了不错的成绩,但要取得更好的效果往往需要领域的强力支持。
Neural Networks | 神经网络
神经网络其实是一个非常宽泛的称呼,它包括两类,一类是用计算机的方式去模拟人脑,这就是我们常说的 ANN(人工神经网络),另一类是研究生物学上的神经网络,又叫生物神经网络;在人工神经网络之中,又分为前馈神经网络和反馈神经网络这两种。神经网络由大量神经元组成。每个神经元获得线性组合的输入,经过非线性的激活函数,然后得到非线性的输出;线性结果加上值相关(Element wise)非线性结果,我们才能去模拟任意的复杂图形。
生物神经元可以通过刺激产生冲动、传导冲动;并可以合成化学物质(神经递质、神经激素等),通过他的轴突输送到特定部位并释放,从而产生一个反应。
第一个正式的人工神经元模型是由沃伦·麦卡洛克(Warren Maculloach)和沃尔特·皮茨(Walter Pitts)于 1943 年提出的。这个模型看起来很像组成计算机的逻辑门。人工神经元示意图如图 1-2 所示。人工神经元本质上是一组向量的加权求和,并通过激活函数产生一个输出。单个的神经元模型无法从数据中学习。第一个正式的人工神经元模型是由沃伦·麦卡洛克(Warren Maculloach)和沃尔特·皮茨(Walter Pitts)于 1943 年提出的。这个模型看起来很像组成计算机的逻辑门。人工神经元示意图如图 1-2 所示。人工神经元本质上是一组向量的加权求和,并通过激活函数产生一个输出。单个的神经元模型无法从数据中学习。
2006 年,Hinton 在《Science》期刊上发表了论文《用神经网络降低数据维数》,首次提出了“深度信念网络”的概念。与传统的训练方式不同,“深度信念网络”有一个“预训练”(pre-training)的过程,这可以方便的让神经网络中的权值找到一个接近最优解的值,之后再使用“微调”(fine-tuning)技术来对整个网络进行优化训练。
神经网络往往由多层堆叠而成,主要分为输入层(Input Layer),隐层(Hidden Layer)以及输出层(Output Layer)这三种。输入层中的每个节点代表了数据集中的每条数据的某个特征,隐层中的每个节点则是接收上层传来的特征向量,将其与权重向量进行点乘,传入激活函数得到该节点对应的特征值;输出层则是将前隐层的输出转化为单一的输出值。
在实际计算中,假设 $X$ 是 $N _ features_num$ 维度的数据集,即包含了 $N$ 条数据,每条数据包含了 $features_num$ 个特征。而隐层总的权重矩阵维度为 $features_num _ hiddenlayer_nodes_num$,即每个隐层节点包含了形为 $features_num * 1$ 的权重向量;输入的数据特征向量与权重向量点乘后得到单一值。换言之,如果隐层共包含了 $hiddenlayer_nodes_num$ 个节点,那么某条数据经过隐层变换后输入的数据就成了形为 $1 * hidden_layer_nodes_num$ 的特征向量。在包含偏置值(bais)的隐层中,每个节点的偏置值为 b,那么整个隐层的 偏置向量就是形为 $1 \times hidden_layer_nodes_num$ 的向量,与点乘得到的特征向量相加,得到某条数据经过该隐层后最终的特征向量。
# 数据集
X = tf.placeholder(tf.float32, shape=(None,features_num))
# Weight, 权重矩阵
W = tf.Variable(tf.random_normal(shape=[features_num, hidden_layer_nodes_num]))
# 偏移量矩阵
B = tf.Variable(tf.ones(shape=([hidden_layer_nodes_num])))
# 构建神经网络计算图
XW = tf.matmul(X,W)
# Activation Function | 激活函数
A = tf.sigmoid(Z)
激活函数
在早期,Sigmoid 函数和 tanh 函数是人们经常使用的激活函数。近年来,随着神经网络的隐层不断增加后,人们偏向于使用 ReLU 函数作为激活函数,这是因为 ReLU 函数的在 x 轴正向的导数是 1,不容易产生梯度消失问题(见 8.3 节)。这里值得一提的是,如果使用 ReLU 函数作为激活函数,则最后生成的拟合函数为分片线性函数。
关于激活函数的解释和讨论,机器学习领域及互联网上有很多文章进行过解释,都是解释为“激活函数的主要作用是提供网络的非线性建模能力,提供了分层的非线性映射学习能力”等等。
从数学上看,深度神经网络就是一个多层复合函数。在机器学习中,这个复合函数的好坏依赖于对目标函数最大化或者最小化的过程,我们常常把最小化的目标函数称为损失函数(Loss function),它主要用于衡量机器学习模型(此处为深度神经网络)的预测能力。常见的损失函数有均方误差(L2 误差)、平均绝对误差(L1 误差)、分位数损失、交叉熵、对比损失等。损失函数的选取依赖于参数的数量、异常值、机器学习算法、梯度下降的效率、导数求取的难易和预测的置信度等若干方面。这里就不展开讨论。
给定了一批训练数据,计算神经网络的问题就是通过极小化损失函数来找到网络中的所有权值参数(包括偏置参数)。这个过程本质上就是利用这个神经网络函数来拟合这些数据,这个过程也称为“训练”或“学习”。
误差反向传播算法(Error Back Propagation,BP)是神经网络训练时采用的一种通用方法。本质是随机梯度下降法。最早见于如下论文:
[8-1] David E. Rumelhart, Geoffrey E. Hinton, and Ronald J. Williams. Learning internal representations by back-propagating errors. Nature, 323(99): 533-536, 1986.
由于整个网络是一个复合函数,因此,训练的过程就是不断地应用“复合函数求导”(链式法则)及“梯度下降法”。反向传播算法从神经网络的输出层开始,利用递推公式根据后一层的误差计算本层的误差,通过误差计算本层参数的梯度值,然后将差项传播到前一层。然后根据这些误差来更新这些系数参数。
,算法过程中计算误差项时每一层都要乘以本层激活函数的导数,因此,会发生很多次的导数连乘。如果激活函数的导数的绝对值小于 1,多次连乘之后误差项很快会衰减到接近于 0;而参数的梯度值由误差项计算得到,从而导致前面层的权重梯度接近于 0,参数不能得到有效更新,这称为“梯度消失”问题。与之相反,如果激活函数导数的绝对值大于 1,多次连乘后权重值会趋向于非常大的数,这称为“梯度爆炸”。长期以来,这两个问题一直困扰神经网络层次无法变得很深。
最近几年,ReLU 函数被经常使用作为深度神经网络的激活函数。有两个主要理由:
-
该函数的导数为sgn(忽略在0处不可导的情形),计算简单,在正半轴导数为1,有效的缓解了梯度消失问题;
-
虽然它是一个分段线性函数,但它具有非线性逼近能力;使用ReLU激活函数的深度网络的本质是用分段(分片)线性函数(超平面)去逼近目标。
后来,人们在 ReLU 的基础上又改进得到各种其他形式的激活函数,包括 ELU、PReLU 等。
激活函数计算量大,反向传播求误差梯度时,求导涉及除法。反向传播时,很容易就会出现梯度消失的情况,从而无法完成深层网络的训练。一个非常大的梯度流过一个 ReLU 神经元,更新过参数之后,这个神经元再也不会对任何数据有激活现象了,那么这个神经元的梯度就永远都会是 0。
Softmax 函数则是用于多分类神经网络输出:
$$ \sigma(z)j = \frac{e^{z_j}}{\sum{k=1}^Ke^{z_k}} $$
梯度下降
梯度下降法 Gradient Descent 是一种常用的一阶(first-order)优化方法,是求解无约束优化问题最简单、最经典的方法之一。考虑无约束优化问题$min_xf(x)$,其中$f(x)$为连续可微函数。如果能构造出一个序列$x^0,x^1,…,x^t$满足:
$$ f(x^{t+1}) < f(x^t),t=0,1,2… $$
则不断执行该过程即可以收敛到局部极小点。而根据泰勒展示我们可以知道:
$$ f(x+\Delta x) \simeq f(x) + \Delta x^T \nabla f(x) $$
于是,如果要满足 $f(x+\Delta x) < f(x)$,可以选择:
$$ \Delta x = -{step} \nabla f(x) $$
其中$step$是一个小常数,表示步长。以求解目标函数最小化为例,梯度下降算法可能存在一下几种情况:
- 当目标函数为凸函数时,局部极小点就对应着函数全局最小值时,这种方法可以快速的找到最优解;
- 当目标函数存在多个局部最小值时,可能会陷入局部最优解。因此需要从多个随机的起点开始解的搜索。
- 当目标函数不存在最小值点,则可能陷入无限循环。因此,有必要设置最大迭代次数。
CNN | 卷积神经网络
传统的图像特征提取(特征工程)主要是基于各种先验模型,通过提取图像关键点、生成描述子特征数据、进行数据匹配或者机器学习方法对特征数据二分类/多分类实现图像的对象检测与识别。卷积神经网络通过计算机自动提取特征(表示工程)实现图像特征的提取与抽象,通过 MLP 实现数据的回归与分类。
卷积神经网络经过池化层操作对单位像素迁移和亮度影响进行了校正,做到了图像的迁移与亮度不变性的特征提取、而且在池化过程中通过不断的降低图像分辨率,构建了图像的多尺度特征,所以还具备尺度空间不变性,完成了图像不变性特征提取工作。
卷积层
卷积层是一系列滤波器集合(filters set)、它的输出结果被称为特征映射(feature maps),每个 feature map 都一个 filter 在图像上卷积得到的输出。一般情况下都会输出结果加线性修正,对卷积层常用就是 ReLU。
卷积是一个线性操作,我们需要一个非线性组合,否则两个卷积卷积层还不如一个卷积层。
池化层
在卷积层提取到的特征数据不具备空间不变性(尺度与迁移不变性特征),只有通过了池化层之后才会具备空间不变性特征。池化层是针对每个 feature map 进行池化操作,池化操作的窗口大小可以指定为任意尺寸,主要有两种类型的池化操作:
-
下采样池化(均值池化)
-
最大值池化
无论是选择哪种池化方式都会输出一个新低分辨率 feature map,多数时候这个过程中会包含一定的信息损失,所以卷积神经网络一般通过扩展深度(增加 feature map 的数量)来补偿。
在进行池化的时候我们如果选择步长为 1 进行池化,通过这样的池化方式输出的结果我们称为重叠池化输出,它不利于特征的稀疏生成,重叠窗口池化与均值池化都有这样的缺点,所以经常采样的是最大值池化,同时不会进行窗口重叠,有实验结果表明,在卷积层保持相同 feature map 与参数的情况下,最大值池化的结果明显优于重叠池化与均值池化,而且网络的深度越深,两者之间的准确度差异越大。
RNN | 循环神经网络
循环神经网络最大的特点就在于循环神经网路的隐含层的每个节点的状态或输出除了与当前时刻的输入有关,还有上一个时刻的状态或者输出有关,隐含层节点之间存在循环连接。这使得循环神经网络具有对时间序列的记忆能力。 实际应用中最有效的序列模型称为门控 RNN(gated RNN)。包括基于长短期记忆(LSTM:long short-term memory)和基于门控循环单元(GRU:gated recurrent unit)的网络。门控 RNN 主要是解决一般 RNN 的梯度消失或者梯度爆炸的问题。
LSTM
不同于普通的 RNN 节点单元,LSTM 引入了遗忘门(总共有 3 个门,输入们、遗忘门和输出们)用来决定我们需要从节点单元中抛弃哪些信息以及保留哪些信息。