1.CNN的卷积核是单层还是多层的?

描述网络模型中某层的厚度,通常用名词通道channel数或者特征图feature map数。不过人们更习惯把作为数据输入的前层的厚度称之为通道数(比如RGB三色图层称为输入通道数为3),把作为卷积输出的后层的厚度称之为特征图数。

卷积核的厚度H, 一般等于前层厚度M(输入通道数或feature map数). 特殊情况M > H。

卷积核的个数N, 一般等于后层厚度(后层feature maps数,因为相等所以也用N表示)。

卷积核通常从属于后层,为后层提供了各种查看前层特征的视角,这个视角是自动形成的。

卷积核厚度等于1时为2D卷积,对应平面点相乘然后把结果加起来,相当于点积运算;

卷积核厚度大于1时为3D卷积,每片分别平面点求卷积,然后把每片结果加起来,作为3D卷积结果;

1x1卷积属于3D卷积的一个特例,有厚度无面积, 直接把每片单个点乘以权重再相加。

归纳之,卷积的意思就是把一个区域,不管是一维线段,二维方阵,还是三维长方块,全部按照卷积核的维度形状,对应逐点相乘再求和,浓缩成一个标量值也就是降到零维度,作为下一层的一个feature map的一个点的值! 可以比喻一群渔夫坐一个渔船撒网打鱼,鱼塘是多层水域,每层鱼儿不同。 船每次移位一个stride到一个地方,每个渔夫撒一网,得到收获,然后换一个距离stride再撒,如此重复直到遍历鱼塘。 A渔夫盯着鱼的品种,遍历鱼塘后该渔夫描绘了鱼塘的鱼品种分布; B渔夫盯着鱼的重量,遍历鱼塘后该渔夫描绘了鱼塘的鱼重量分布; 还有N-2个渔夫,各自兴趣各干各的; 最后得到N个特征图,描述了鱼塘的一切!

2.什么是卷积?

对图像(不同的数据窗口数据)和滤波矩阵(一组固定的权重:因为每个神经元的多个权重固定,所以又可以看做一个恒定的滤波器filter)做内积(逐个元素相乘再求和)的操作就是所谓的『卷积』操作,也是卷积神经网络的名字来源。

CNN加层数 cnn层数选择_权重

3.什么是CNN的池化

池化,简言之,即取区域平均或最大,如下图所示(图引自cs231n)

CNN加层数 cnn层数选择_权重_02

上图所展示的是取区域最大,即上图左边部分中 左上角2x2的矩阵中6最大,右上角2x2的矩阵中8最大,左下角2x2的矩阵中3最大,右下角2x2的矩阵中4最大,所以得到上图右边部分的结果:6 8 3 4。

4.简述下什么是生成对抗网络?

GAN之所以是对抗的,是因为GAN的内部是竞争关系,一方叫generator,它的主要工作是生成图片,并且尽量使得其看上去是来自于训练样本的。另一方是discriminator,其目标是判断输入图片是否属于真实训练样本。 更直白的讲,将generator想象成假币制造商,而discriminator是警察。generator目的是尽可能把假币造的跟真的一样,从而能够骗过discriminator,即生成样本并使它看上去好像来自于真实训练样本一样。

CNN加层数 cnn层数选择_权重_03

5.请介绍下tensorflow的计算图

Tensorflow是一个通过计算图的形式来表述计算的编程系统,计算图也叫数据流图,可以把计算图看做是一种有向图,Tensorflow中的每一个节点都是计算图上的一个Tensor, 也就是张量,而节点之间的边描述了计算之间的依赖关系(定义时)和数学操作(运算时)。如下两图表示:

a=x*y; b=a+z; c=tf.reduce_sum(b);

CNN加层数 cnn层数选择_激活函数_04

CNN加层数 cnn层数选择_激活函数_05

6.deeplearning 调参经验?

一、参数初始化 下面几种方式,随便选一个,结果基本都差不多。但是一定要做。否则可能会减慢收敛速度,影响收敛结果,甚至造成Nan等一系列问题。 下面的n_in为网络的输入大小,n_out为网络的输出大小,n为n_in或(n_in+n_out)*0.5

Xavier初始法论文:http://jmlr.org/proceedings/papers/v9/glorot10a/glorot10a.pdf

He初始化论文:https://arxiv.org/abs/1502.01852 uniform均匀分布初始化:w = np.random.uniform(low=-scale, high=scale, size=[n_in,n_out])

Xavier初始法,适用于普通激活函数(tanh,sigmoid):scale = np.sqrt(3/n)

He初始化,适用于ReLU:scale = np.sqrt(6/n) normal高斯分布初始化:w = np.random.randn(n_in,n_out) * stdev # stdev为高斯分布的标准差,均值设为0

Xavier初始法,适用于普通激活函数 (tanh,sigmoid):stdev = np.sqrt(n)

He初始化,适用于ReLU:stdev = np.sqrt(2/n)

svd初始化:对RNN有比较好的效果。参考论文:https://arxiv.org/abs/1312.6120

二、数据预处理方式 zero-center ,这个挺常用的.X -= np.mean(X, axis = 0) # zero-centerX /= np.std(X, axis = 0) # normalize PCA whitening,这个用的比较少.

三、训练技巧 要做梯度归一化,即算出来的梯度除以minibatch size clip c(梯度裁剪): 限制最大梯度,其实是value = sqrt(w1^2+w2^2….),如果value超过了阈值,就算一个衰减系系数,让value的值等于阈值: 5,10,15

dropout对小数据防止过拟合有很好的效果,值一般设为0.5,小数据上dropout+sgd在我的大部分实验中,效果提升都非常明显.因此可能的话,建议一定要尝试一下。

dropout的位置比较有讲究, 对于RNN,建议放到输入->RNN与RNN->输出的位置.关于RNN如何用dropout,可以参考这篇论文:http://arxiv.org/abs/1409.2329 adam,adadelta等,在小数据上,我这里实验的效果不如sgd, sgd收敛速度会慢一些,但是最终收敛后的结果,一般都比较好。

如果使用sgd的话,可以选择从1.0或者0.1的学习率开始,隔一段时间,在验证集上检查一下,如果cost没有下降,就对学习率减半. 我看过很多论文都这么搞,我自己实验的结果也很好. 当然,也可以先用ada系列先跑,最后快收敛的时候,更换成sgd继续训练.同样也会有提升.据说adadelta一般在分类问题上效果比较好,adam在生成问题上效果比较好。

除了gate之类的地方,需要把输出限制成0-1之外,尽量不要用sigmoid,可以用tanh或者relu之类的激活函数.1. sigmoid函数在-4到4的区间里,才有较大的梯度。之外的区间,梯度接近0,很容易造成梯度消失问题。2. 输入0均值,sigmoid函数的输出不是0均值的。 rnn的dim和embdding size,一般从128上下开始调整. batch size,一般从128左右开始调整.batch size合适最重要,并不是越大越好. word2vec初始化,在小数据上,不仅可以有效提高收敛速度,也可以可以提高结果.

四、尽量对数据做shuffle LSTM 的forget gate的bias,用1.0或者更大的值做初始化,可以取得更好的结果,来自这篇论文:http://jmlr.org/proceedings/papers/v37/jozefowicz15.pdf, 我这里实验设成1.0,可以提高收敛速度.实际使用中,不同的任务,可能需要尝试不同的值. Batch Normalization据说可以提升效果,不过我没有尝试过,建议作为最后提升模型的手段,参考论文:Accelerating Deep Network Training by Reducing Internal Covariate Shift

如果你的模型包含全连接层(MLP),并且输入和输出大小一样,可以考虑将MLP替换成Highway Network,我尝试对结果有一点提升,建议作为最后提升模型的手段,原理很简单,就是给输出加了一个gate来控制信息的流动,详细介绍请参考论文: http://arxiv.org/abs/1505.00387    一轮加正则,一轮不加正则,反复进行。

五、Ensemble Ensemble是论文刷结果的终极核武器,深度学习中一般有以下几种方式 同样的参数,不同的初始化方式 不同的参数,通过cross-validation,选取最好的几组 同样的参数,模型训练的不同阶段,即不同迭代次数的模型。 不同的模型,进行线性融合. 例如RNN和传统模型.

7.CNN为什么可以应用在CV、NLP、SPEECH乃至ALPHA GO中?

以上几个不相关问题的相关性在于,都存在局部与整体的关系,由低层次的特征经过组合,组成高层次的特征,并且得到不同特征之间的空间相关性。如下图:低层次的直线/曲线等特征,组合成为不同的形状,最后得到汽车的表示。

CNN加层数 cnn层数选择_CNN加层数_06

CNN抓住此共性的手段主要有四个:局部连接/权值共享/池化操作/多层次结构。 局部连接使网络可以提取数据的局部特征;权值共享大大降低了网络的训练难度,一个Filter只提取一个特征,在整个图片(或者语音/文本) 中进行卷积;池化操作与多层次结构一起,实现了数据的降维,将低层次的局部特征组合成为较高层次的特征,从而对整个图片进行表示。如下图:

CNN加层数 cnn层数选择_权重_07

上图中,如果每一个点的处理使用相同的Filter,则为全卷积,如果使用不同的Filter,则为Local-Conv。

8.LSTM为什么比RNN好?

因为LSTM有进有出且当前的cell informaton是通过input gate控制之后叠加的,RNN是叠乘,因此LSTM可以防止梯度消失或者爆炸。

9.Sigmiod、Relu、Tanh三个激活函数的缺点和不足,有没有更好的激活函数?

sigmoid、Tanh、ReLU的缺点在121问题中已有说明,为了解决ReLU的dead cell的情况,发明了Leaky Relu, 即在输入小于0时不让输出为0,而是乘以一个较小的系数,从而保证有导数存在。同样的目的,还有一个ELU,函数示意图如下。

CNN加层数 cnn层数选择_激活函数_08

 还有一个激活函数是Maxout,即使用两套w,b参数,输出较大值。本质上Maxout可以看做Relu的泛化版本,因为如果一套w,b全都是0的话,那么就是普通的ReLU。Maxout可以克服Relu的缺点,但是参数数目翻倍。

CNN加层数 cnn层数选择_权重_09

10.为什么引入非线性激活函数?

第一,对于神经网络来说,网络的每一层相当于f(wx+b)=f(w'x),对于线性函数,其实相当于f(x)=x,那么在线性激活函数下,每一层相当于用一个矩阵去乘以x,那么多层就是反复的用矩阵去乘以输入。根据矩阵的乘法法则,多个矩阵相乘得到一个大矩阵。所以线性激励函数下,多层网络与一层网络相当。比如,两层的网络f(W1*f(W2x))=W1W2x=Wx。 第二,非线性变换是深度学习有效的原因之一。原因在于非线性相当于对空间进行变换,变换完成后相当于对问题空间进行简化,原来线性不可解的问题现在变得可以解了。 下图可以很形象的解释这个问题,左图用一根线是无法划分的。经过一系列变换后,就变成线性可解的问题了。

CNN加层数 cnn层数选择_初始化_10

如果不用激励函数(其实相当于激励函数是f(x) = x),在这种情况下你每一层输出都是上层输入的线性函数,很容易验证,无论你神经网络有多少层,输出都是输入的线性组合,与没有隐藏层效果相当,这种情况就是最原始的感知机(Perceptron)了。 正因为上面的原因,我们决定引入非线性函数作为激励函数,这样深层神经网络就有意义了(不再是输入的线性组合,可以逼近任意函数)。最早的想法是sigmoid函数或者tanh函数,输出有界,很容易充当下一层输入(以及一些人的生物解释)。

11.relu为何好过sigmoid和tanh?

先看sigmoid、tanh和RelU的函数图:

CNN加层数 cnn层数选择_权重_11

第一,采用sigmoid等函数,算激活函数时(指数运算),计算量大,反向传播求误差梯度时,求导涉及除法和指数运算,计算量相对大,而采用Relu激活函数,整个过程的计算量节省很多。

第二,对于深层网络,sigmoid函数反向传播时,很容易就会出现梯度消失的情况(在sigmoid接近饱和区时,变换太缓慢,导数趋于0,这种情况会造成信息丢失),这种现象称为饱和,从而无法完成深层网络的训练。而ReLU就不会有饱和倾向,不会有特别小的梯度出现。

第三,Relu会使一部分神经元的输出为0,这样就造成了网络的稀疏性,并且减少了参数的相互依存关系,缓解了过拟合问题的发生(以及一些人的生物解释balabala)。当然现在也有一些对relu的改进,比如prelu,random relu等,在不同的数据集上会有一些训练速度上或者准确率上的改进。

12.为什么LSTM中既存在tanh和sigmoid,而不同意采用一样的。

CNN加层数 cnn层数选择_激活函数_12

sigmoid 用在了各种gate上,产生0~1之间的值,这个一般只有sigmoid最直接了。 tanh 用在了状态和输出上,是对数据的处理,这个用其他激活函数或许也可以。

13.如何解决RNN梯度消失和弥散的情况?

为了解决梯度爆炸问题,Thomas Mikolov首先提出了一个简单的启发性的解决方案,就是当梯度大于一定阈值的的时候,将它截断为一个较小的数。具体如算法1所述: 算法:当梯度爆炸时截断梯度(伪代码)

CNN加层数 cnn层数选择_初始化_13

下图可视化了梯度截断的效果。它展示了一个小的rnn(其中W为权值矩阵,b为bias项)的决策面。这个模型是一个一小段时间的rnn单元组成;实心箭头表明每步梯度下降的训练过程。当梯度下降过程中,模型的目标函数取得了较高的误差时,梯度将被送到远离决策面的位置。截断模型产生了一个虚线,它将误差梯度拉回到离原始梯度接近的位置。

CNN加层数 cnn层数选择_激活函数_14

梯度爆炸,梯度截断可视化 为了解决梯度弥散的问题,我们介绍了两种方法。第一种方法是将随机初始化

CNN加层数 cnn层数选择_初始化_15

改为一个有关联的矩阵初始化。第二种方法是使用ReLU(Rectified Linear Units)代替sigmoid函数。ReLU的导数不是0就是1.因此,神经元的梯度将始终为1,而不会当梯度传播了一定时间之后变小。

14.什么样的资料集不适合深度学习?

1、数据集太小,数据样本不足时,深度学习相对其它机器学习算法,没有明显优势。

2、数据集没有局部相关特性,目前深度学习表现比较好的领域主要是图像/语音/自然语言处理等领域,这些领域的一个共性是局部相关性。图像中像素组成物体,语音信号中音位组合成单词,文本数据中单词组合成句子,这些特征元素的组合一旦被打乱,表示的含义同时也被改变。对于没有这样的局部相关性的数据集,不适于使用深度学习算法进行处理。举个例子:预测一个人的健康状况,相关的参数会有年龄、职业、收入、家庭状况等各种元素,将这些元素打乱,并不会影响相关的结果。

15.如何解决梯度消失和梯度爆炸?

(1)梯度消失: 根据链式法则,如果每一层神经元对上一层的输出的偏导乘上权重结果都小于1的话,那么即使这个结果是0.99,在经过足够多层传播之后,误差对输入层的偏导会趋于0 可以采用ReLU激活函数有效的解决梯度消失的情况,也可以用Batch Normalization解决这个问题。关于深度学习中 Batch Normalization为什么效果好?参见:https://www.zhihu.com/question/38102762

(2)梯度膨胀 :根据链式法则,如果每一层神经元对上一层的输出的偏导乘上权重结果都大于1的话,在经过足够多层传播之后,误差对输入层的偏导会趋于无穷大 可以通过RELU激活函数来解决,或用Batch Normalization解决这个问题。

16.CNN常用的几个简单模型



17.梯度爆炸会引发什么?

在深度多层感知机网络中,梯度爆炸会引起网络不稳定,最好的结果是无法从训练数据中学习,而最坏的结果是出现无法再更新的 NaN 权重值。 梯度爆炸导致学习过程不稳定。—《深度学习》,2016. 在循环神经网络中,梯度爆炸会导致网络不稳定,无法利用训练数据学习,最好的结果是网络无法学习长的输入序列数据。

有很多方法可以解决梯度爆炸问题,本节列举了一些最佳实验方法。

1. 重新设计网络模型 在深度神经网络中,梯度爆炸可以通过重新设计层数更少的网络来解决。 使用更小的批尺寸对网络训练也有好处。 在循环神经网络中,训练过程中在更少的先前时间步上进行更新(沿时间的截断反向传播,truncated Backpropagation through time)可以缓解梯度爆炸问题。

2. 使用 ReLU 激活函数 在深度多层感知机神经网络中,梯度爆炸的发生可能是因为激活函数,如之前很流行的 Sigmoid 和 Tanh 函数。 使用 ReLU 激活函数可以减少梯度爆炸。采用 ReLU 激活函数是最适合隐藏层的新实践。

3. 使用长短期记忆网络 在循环神经网络中,梯度爆炸的发生可能是因为某种网络的训练本身就存在不稳定性,如随时间的反向传播本质上将循环网络转换成深度多层感知机神经网络。 使用长短期记忆(LSTM)单元和相关的门类型神经元结构可以减少梯度爆炸问题。 采用 LSTM 单元是适合循环神经网络的序列预测的最新最好实践。

4. 使用梯度截断(Gradient Clipping) 在非常深且批尺寸较大的多层感知机网络和输入序列较长的 LSTM 中,仍然有可能出现梯度爆炸。如果梯度爆炸仍然出现,你可以在训练过程中检查和限制梯度的大小。这就是梯度截断。 处理梯度爆炸有一个简单有效的解决方案:如果梯度超过阈值,就截断它们。 ——《Neural Network Methods in Natural Language Processing》,2017. 具体来说,检查误差梯度的值是否超过阈值,如果超过,则截断梯度,将梯度设置为阈值。 梯度截断可以一定程度上缓解梯度爆炸问题(梯度截断,即在执行梯度下降步骤之前将梯度设置为阈值)。 ——《深度学习》,2016. 在 Keras 深度学习库中,你可以在训练之前设置优化器上的 clipnorm 或 clipvalue 参数,来使用梯度截断。 默认值为 clipnorm=1.0 、clipvalue=0.5。详见:https://keras.io/optimizers/。

5. 使用权重正则化(Weight Regularization) 如果梯度爆炸仍然存在,可以尝试另一种方法,即检查网络权重的大小,并惩罚产生较大权重值的损失函数。该过程被称为权重正则化,通常使用的是 L1 惩罚项(权重绝对值)或 L2 惩罚项(权重平方)。 对循环权重使用 L1 或 L2 惩罚项有助于缓解梯度爆炸。 ——On the difficulty of training recurrent neural networks,2013. 在 Keras 深度学习库中,你可以通过在层上设置 kernel_regularizer 参数和使用 L1 或 L2 正则化项进行权重正则化。

18.什么是RNN

RNNs的目的使用来处理序列数据。在传统的神经网络模型中,是从输入层到隐含层再到输出层,层与层之间是全连接的,每层之间的节点是无连接的。但是这种普通的神经网络对于很多问题却无能无力。例如,你要预测句子的下一个单词是什么,一般需要用到前面的单词,因为一个句子中前后单词并不是独立的。 RNNs之所以称为循环神经网路,即一个序列当前的输出与前面的输出也有关。具体的表现形式为网络会对前面的信息进行记忆并应用于当前输出的计算中,即隐藏层之间的节点不再无连接而是有连接的,并且隐藏层的输入不仅包括输入层的输出还包括上一时刻隐藏层的输出。 理论上,RNNs能够对任何长度的序列数据进行处理。但是在实践中,为了降低复杂性往往假设当前的状态只与前面的几个状态相关,下图便是一个典型的RNNs:

CNN加层数 cnn层数选择_初始化_16

RNNs包含输入单元(Input units),输入集标记为{x0,x1,...,xt,xt+1,...},而输出单元(Output units)的输出集则被标记为{y0,y1,...,yt,yt+1.,..}。RNNs还包含隐藏单元(Hidden units),我们将其输出集标记为{s0,s1,...,st,st+1,...},这些隐藏单元完成了最为主要的工作。你会发现,在图中:有一条单向流动的信息流是从输入单元到达隐藏单元的,与此同时另一条单向流动的信息流从隐藏单元到达输出单元。在某些情况下,RNNs会打破后者的限制,引导信息从输出单元返回隐藏单元,这些被称为“Back Projections”,并且隐藏层的输入还包括上一隐藏层的状态,即隐藏层内的节点可以自连也可以互连。

CNN加层数 cnn层数选择_初始化_17

上图将循环神经网络进行展开成一个全神经网络。例如,对一个包含5个单词的语句,那么展开的网络便是一个五层的神经网络,每一层代表一个单词。对于该网络的计算过程如下: 1. xt表示第t,t=1,2,3...步(step)的输入。比如,x1为第二个词的one-hot向量(根据上图,x0为第一个词); 2. st为隐藏层的第t步的状态,它是网络的记忆单元。 st根据当前输入层的输出与上一步隐藏层的状态进行计算。st=f(Uxt+Wst−1),其中f一般是非线性的激活函数,如tanh或ReLU,在计算s0时,即第一个单词的隐藏层状态,需要用到s−1,但是其并不存在,在实现中一般置为0向量; 3. ot是第t步的输出,如下个单词的向量表示,ot=softmax(Vst).

19.什么是LSTM网络?

Long Short Term 网络—— 一般就叫做 LSTM ——是一种 RNN 特殊的类型,可以学习长期依赖信息。如@寒小阳所说:LSTM和基线RNN并没有特别大的结构不同,但是它们用了不同的函数来计算隐状态。LSTM的“记忆”我们叫做细胞/cells,你可以直接把它们想做黑盒,这个黑盒的输入为前状态ht−1和当前输入xt。这些“细胞”会决定哪些之前的信息和状态需要保留/记住,而哪些要被抹去。实际的应用中发现,这种方式可以有效地保存很长时间之前的关联信息。 LSTM 由Hochreiter & Schmidhuber (1997)提出,并在近期被Alex Graves进行了改良和推广。在很多问题,LSTM 都取得相当巨大的成功,并得到了广泛的使用。 LSTM 通过刻意的设计来避免长期依赖问题。记住长期的信息在实践中是 LSTM 的默认行为,而非需要付出很大代价才能获得的能力! 所有 RNN 都具有一种重复神经网络模块的链式的形式。在标准的 RNN 中,这个重复的模块只有一个非常简单的结构,例如一个 tanh 层。

CNN加层数 cnn层数选择_CNN加层数_18

标准 RNN 中的重复模块包含单一的层 LSTM 同样是这样的结构,但是重复的模块拥有一个不同的结构。不同于 单一神经网络层,这里是有四个,以一种非常特殊的方式进行交互。

CNN加层数 cnn层数选择_初始化_19

LSTM 中的重复模块包含四个交互的层 不必担心这里的细节。我们会一步一步地剖析 LSTM 解析图。现在,我们先来熟悉一下图中使用的各种元素的图标。

CNN加层数 cnn层数选择_CNN加层数_20

LSTM 中的图标 在上面的图例中,每一条黑线传输着一整个向量,从一个节点的输出到其他节点的输入。粉色的圈代表 pointwise 的操作,诸如向量的和,而黄色的矩阵就是学习到的神经网络层。合在一起的线表示向量的连接,分开的线表示内容被复制,然后分发到不同的位置。 四、LSTM 的核心思想 LSTM 的关键就是细胞状态,水平线在图上方贯穿运行。 细胞状态类似于传送带。直接在整个链上运行,只有一些少量的线性交互。信息在上面流传保持不变会很容易。

CNN加层数 cnn层数选择_CNN加层数_21

LSTM 有通过精心设计的称作为“门”的结构来去除或者增加信息到细胞状态的能力。门是一种让信息选择式通过的方法。他们包含一个 sigmoid 神经网络层和一个 pointwise 乘法操作。

CNN加层数 cnn层数选择_初始化_22

Sigmoid 层输出 0 到 1 之间的数值,描述每个部分有多少量可以通过。0 代表“不许任何量通过”,1 就指“允许任意量通过”! LSTM 拥有三个门,来保护和控制细胞状态。 在我们 LSTM 中的第一步是决定我们会从细胞状态中丢弃什么信息。这个决定通过一个称为忘记门层完成。该门会读取 h_{t-1} 和 x_t,输出一个在 0 到 1 之间的数值给每个在细胞状态 C_{t-1} 中的数字。1 表示“完全保留”,0 表示“完全舍弃”。 让我们回到语言模型的例子中来基于已经看到的预测下一个词。在这个问题中,细胞状态可能包含当前主语的性别,因此正确的代词可以被选择出来。当我们看到新的主语,我们希望忘记旧的主语。

CNN加层数 cnn层数选择_CNN加层数_23

决定丢弃信息 下一步是确定什么样的新信息被存放在细胞状态中。这里包含两个部分。第一,sigmoid 层称 “输入门层” 决定什么值我们将要更新。然后,一个 tanh 层创建一个新的候选值向量,\tilde{C}_t,会被加入到状态中。下一步,我们会讲这两个信息来产生对状态的更新。 在我们语言模型的例子中,我们希望增加新的主语的性别到细胞状态中,来替代旧的需要忘记的主语。

CNN加层数 cnn层数选择_初始化_24

确定更新的信息 现在是更新旧细胞状态的时间了,C_{t-1} 更新为 C_t。前面的步骤已经决定了将会做什么,我们现在就是实际去完成。 我们把旧状态与 f_t 相乘,丢弃掉我们确定需要丢弃的信息。接着加上 i_t * \tilde{C}_t。这就是新的候选值,根据我们决定更新每个状态的程度进行变化。 在语言模型的例子中,这就是我们实际根据前面确定的目标,丢弃旧代词的性别信息并添加新的信息的地方。

CNN加层数 cnn层数选择_激活函数_25

更新细胞状态 最终,我们需要确定输出什么值。这个输出将会基于我们的细胞状态,但是也是一个过滤后的版本。首先,我们运行一个 sigmoid 层来确定细胞状态的哪个部分将输出出去。接着,我们把细胞状态通过 tanh 进行处理(得到一个在 -1 到 1 之间的值)并将它和 sigmoid 门的输出相乘,最终我们仅仅会输出我们确定输出的那部分。 在语言模型的例子中,因为他就看到了一个 代词,可能需要输出与一个 动词 相关的信息。例如,可能输出是否代词是单数还是负数,这样如果是动词的话,我们也知道动词需要进行的词形变化。

CNN加层数 cnn层数选择_CNN加层数_26

输出信息

20.详细说说CNN工作原理

1 人工神经网络

1.1 神经元 神经网络由大量的神经元相互连接而成。每个神经元接受线性组合的输入后,最开始只是简单的线性加权,后来给每个神经元加上了非线性的激活函数,从而进行非线性变换后输出。每两个神经元之间的连接代表加权值,称之为权重(weight)。不同的权重和激活函数,则会导致神经网络不同的输出。 举个手写识别的例子,给定一个未知数字,让神经网络识别是什么数字。此时的神经网络的输入由一组被输入图像的像素所激活的输入神经元所定义。在通过非线性激活函数进行非线性变换后,神经元被激活然后被传递到其他神经元。重复这一过程,直到最后一个输出神经元被激活。从而识别当前数字是什么字。 神经网络的每个神经元如下

CNN加层数 cnn层数选择_权重_27

基本wx + b的形式,其中 x1、x2表示输入向量 w1、w2为权重,几个输入则意味着有几个权重,即每个输入都被赋予一个权重 b为偏置bias g(z) 为激活函数 a 为输出 如果只是上面这样一说,估计以前没接触过的十有八九又必定迷糊了。事实上,上述简单模型可以追溯到20世纪50/60年代的感知器,可以把感知器理解为一个根据不同因素、以及各个因素的重要性程度而做决策的模型。 举个例子,这周末北京有一草莓音乐节,那去不去呢?决定你是否去有二个因素,这二个因素可以对应二个输入,分别用x1、x2表示。此外,这二个因素对做决策的影响程度不一样,各自的影响程度用权重w1、w2表示。一般来说,音乐节的演唱嘉宾会非常影响你去不去,唱得好的前提下 即便没人陪同都可忍受,但如果唱得不好还不如你上台唱呢。所以,我们可以如下表示: x1:是否有喜欢的演唱嘉宾。x1 = 1 你喜欢这些嘉宾,x1 = 0 你不喜欢这些嘉宾。嘉宾因素的权重w1 = 7 x2:是否有人陪你同去。x2 = 1 有人陪你同去,x2 = 0 没人陪你同去。是否有人陪同的权重w2 = 3。 这样,咱们的决策模型便建立起来了:g(z) = g(w1*x1 + w2*x2 + b ),g表示激活函数,这里的b可以理解成 为更好达到目标而做调整的偏置项。 一开始为了简单,人们把激活函数定义成一个线性函数,即对于结果做一个线性变化,比如一个简单的线性激活函数是g(z) = z,输出都是输入的线性变换。后来实际应用中发现,线性激活函数太过局限,于是人们引入了非线性激活函数。1.2 激活函数 常用的非线性激活函数有sigmoid、tanh、relu等等,前两者sigmoid/tanh比较常见于全连接层,后者relu常见于卷积层。这里先简要介绍下最基础的sigmoid函数(btw,在本博客中SVM那篇文章开头有提过)。 sigmoid的函数表达式如下

其中z是一个线性组合,比如z可以等于:b + w1*x1 + w2*x2。通过代入很大的正数或很小的负数到g(z)函数中可知,其结果趋近于0或1。 因此,sigmoid函数g(z)的图形表示如下( 横轴表示定义域z,纵轴表示值域g(z) ):

CNN加层数 cnn层数选择_初始化_28

也就是说,sigmoid函数的功能是相当于把一个实数压缩至0到1之间。当z是非常大的正数时,g(z)会趋近于1,而z是非常小的负数时,则g(z)会趋近于0。 压缩至0到1有何用处呢?用处是这样一来便可以把激活函数看作一种“分类的概率”,比如激活函数的输出为0.9的话便可以解释为90%的概率为正样本。 举个例子,如下图(图引自Stanford机器学习公开课)

CNN加层数 cnn层数选择_初始化_29

z = b + w1*x1 + w2*x2,其中b为偏置项 假定取-30,w1、w2都取为20

CNN加层数 cnn层数选择_激活函数_30

如果x1 = 0 x2 = 0,则z = -30,g(z) = 1/( 1 + e^-z )趋近于0。此外,从上图sigmoid函数的图形上也可以看出,当z=-30的时候,g(z)的值趋近于0 如果x1 = 0 x2 = 1,或x1 =1 x2 = 0,则z = b + w1*x1 + w2*x2 = -30 + 20 = -10,同样,g(z)的值趋近于0 如果x1 = 1 x2 = 1,则z = b + w1*x1 + w2*x2 = -30 + 20*1 + 20*1 = 10,此时,g(z)趋近于1。 换言之,只有和都取1的时候,g(z)→1,判定为正样本;或取0的时候,g(z)→0,判定为负样本,如此达到分类的目的。

1.3 神经网络 将下图的这种单个神经元

CNN加层数 cnn层数选择_激活函数_31

组织在一起,便形成了神经网络。下图便是一个三层神经网络结构

CNN加层数 cnn层数选择_激活函数_32

上图中最左边的原始输入信息称之为输入层,最右边的神经元称之为输出层(上图中输出层只有一个神经元),中间的叫隐藏层。 啥叫输入层、输出层、隐藏层呢? 输入层(Input layer),众多神经元(Neuron)接受大量非线形输入讯息。输入的讯息称为输入向量。 输出层(Output layer),讯息在神经元链接中传输、分析、权衡,形成输出结果。输出的讯息称为输出向量。 隐藏层(Hidden layer),简称“隐层”,是输入层和输出层之间众多神经元和链接组成的各个层面。如果有多个隐藏层,则意味着多个激活函数。 同时,每一层都可能由单个或多个神经元组成,每一层的输出将会作为下一层的输入数据。比如下图中间隐藏层来说,隐藏层的3个神经元a1、a2、a3皆各自接受来自多个不同权重的输入(因为有x1、x2、x3这三个输入,所以a1 a2 a3都会接受x1 x2 x3各自分别赋予的权重,即几个输入则几个权重),接着,a1、a2、a3又在自身各自不同权重的影响下 成为的输出层的输入,最终由输出层输出最终结果。

CNN加层数 cnn层数选择_激活函数_33

上图(图引自Stanford机器学习公开课)中

CNN加层数 cnn层数选择_激活函数_34

表示第j层第i个单元的激活函数/神经元

CNN加层数 cnn层数选择_激活函数_35

表示从第j层映射到第j+1层的控制函数的权重矩阵 此外,输入层和隐藏层都存在一个偏置(bias unit),所以上图中也增加了偏置项:x0、a0。针对上图,有如下公式

CNN加层数 cnn层数选择_初始化_36

此外,上文中讲的都是一层隐藏层,但实际中也有多层隐藏层的,即输入层和输出层中间夹着数层隐藏层,层和层之间是全连接的结构,同一层的神经元之间没有连接。

CNN加层数 cnn层数选择_CNN加层数_37

2 卷积神经网络之层级结构 cs231n课程里给出了卷积神经网络各个层级结构,如下图

CNN加层数 cnn层数选择_初始化_38

上图中CNN要做的事情是:给定一张图片,是车还是马未知,是什么车也未知,现在需要模型判断这张图片里具体是一个什么东西,总之输出一个结果:如果是车 那是什么车 所以 最左边是数据输入层,对数据做一些处理,比如去均值(把输入数据各个维度都中心化为0,避免数据过多偏差,影响训练效果)、归一化(把所有的数据都归一到同样的范围)、PCA/白化等等。CNN只对训练集做“去均值”这一步。 中间是 CONV:卷积计算层,线性乘积 求和。 RELU:激励层,上文2.2节中有提到:ReLU是激活函数的一种。 POOL:池化层,简言之,即取区域平均或最大。 最右边是 FC:全连接层 这几个部分中,卷积计算层是CNN的核心,下文将重点阐述。3 CNN之卷积计算层 3.1 CNN怎么进行识别 当我们给定一个"X"的图案,计算机怎么识别这个图案就是“X”呢?一个可能的办法就是计算机存储一张标准的“X”图案,然后把需要识别的未知图案跟标准"X"图案进行比对,如果二者一致,则判定未知图案即是一个"X"图案。 而且即便未知图案可能有一些平移或稍稍变形,依然能辨别出它是一个X图案。如此,CNN是把未知图案和标准X图案一个局部一个局部的对比,如下图所示 [图来自参考文案25]

CNN加层数 cnn层数选择_CNN加层数_39

而未知图案的局部和标准X图案的局部一个一个比对时的计算过程,便是卷积操作。卷积计算结果为1表示匹配,否则不匹配。 接下来,我们来了解下什么是卷积操作。 3.2 什么是卷积 对图像(不同的数据窗口数据)和滤波矩阵(一组固定的权重:因为每个神经元的多个权重固定,所以又可以看做一个恒定的滤波器filter)做内积(逐个元素相乘再求和)的操作就是所谓的『卷积』操作,也是卷积神经网络的名字来源。 非严格意义上来讲,下图中红框框起来的部分便可以理解为一个滤波器,即带着一组固定权重的神经元。多个滤波器叠加便成了卷积层。

CNN加层数 cnn层数选择_CNN加层数_40

OK,举个具体的例子。比如下图中,图中左边部分是原始输入数据,图中中间部分是滤波器filter,图中右边是输出的新的二维数据。

CNN加层数 cnn层数选择_CNN加层数_41

分解下上图

CNN加层数 cnn层数选择_初始化_42

对应位置上是数字先相乘后相加

CNN加层数 cnn层数选择_CNN加层数_43

=

CNN加层数 cnn层数选择_初始化_44

中间滤波器filter与数据窗口做内积,其具体计算过程则是:4*0 + 0*0 + 0*0 + 0*0 + 0*1 + 0*1 + 0*0 + 0*1 + -4*2 = -8 3.3 图像上的卷积 在下图对应的计算过程中,输入是一定区域大小(width*height)的数据,和滤波器filter(带着一组固定权重的神经元)做内积后等到新的二维数据。 具体来说,左边是图像输入,中间部分就是滤波器filter(带着一组固定权重的神经元),不同的滤波器filter会得到不同的输出数据,比如颜色深浅、轮廓。相当于如果想提取图像的不同特征,则用不同的滤波器filter,提取想要的关于图像的特定信息:颜色深浅或轮廓。 如下图所示

CNN加层数 cnn层数选择_激活函数_45

3.4 GIF动态卷积图 在CNN中,滤波器filter(带着一组固定权重的神经元)对局部输入数据进行卷积计算。每计算完一个数据窗口内的局部数据后,数据窗口不断平移滑动,直到计算完所有数据。这个过程中,有这么几个参数: a. 深度depth:神经元个数,决定输出的depth厚度。同时代表滤波器个数。 b. 步长stride:决定滑动多少步可以到边缘。 c. 填充值zero-padding:在外围边缘补充若干圈0,方便从初始位置以步长为单位可以刚好滑倒末尾位置,通俗地讲就是为了总长能被步长整除。

CNN加层数 cnn层数选择_权重_46