1 卷积神经网络原理
卷积神经网络(Convolutional Neural Networks,CNN),是由Hubel和Wiesel在研究猫脑皮层中用于局部敏感和方向选择的神经元时发现其独特的网络结构可以有效地降低反馈神经网络的复杂性,继而提出了卷积神经网络。
一般地,CNN的基本结构包括两层,一为特征提取层,每个神经元的输入与前一层的局部接受域相连,并提取该局部的特征;一旦该局部特征被提取后,它与其它特征间的位置关系也随之确定下来;二是特征映射层,网络的每个计算层由多个特征映射组成,每个特征映射是一个平面,平面上所有神经元的权值相等。特征映射结构采用影响函数核小的sigmoid函数作为卷积网络的激活函数,使得特征映射具有位移不变性。此外,由于一个映射面上的神经元共享权值,因而减少了网络自由参数的个数。卷积神经网络中的每一个卷积层都紧跟着一个用来求局部平均与二次提取的计算层,这种特有的两次特征提取结构减小了特征分辨率。
一个典型的卷积网络,由卷积层、池化层、全连接层组成。其中卷积层与池化层配合,组成多个卷积组,逐层提取特征,最终通过若干个全连接层完成分类。卷积层完成的操作,可以认为是受局部感受野概念的启发,而池化层,主要是为了降低数据维度。综合来说,CNN通过卷积来模拟特征区分,并且通过卷积的权值共享及池化,来降低网络参数的数量级,最后通过传统神经网络完成分类等任务。
卷积部分强烈推荐博客:NLP实践-Task7
1.1 降低参数量级
为什么要降低参数量级?从下面的例子就可以很容易理解了。
如果我们使用传统神经网络方式,对一张图片进行分类,那么,我们把图片的每个像素都连接到隐藏层节点上,那么对于一张1000*1000像素的图片,如果我们有1M隐藏层单元,那么一共有10^12个参数,这显然是不能接受的。
但在CNN里,可以大大减少参数个数,我们基于以下两个假设:
1)最底层特征都是局部性的,即用10*10这样大小的过滤器就能表示边缘等底层特征;
2)图像上不同大小片段,以及不同图像上的小片段的特征是类似的,即我们能用同样的一组分类器来描述各种各样不同的图像。
1.2 卷积(Convolution)
卷积运算的定义如下图所示:
如图所示,对于一个5*5的图像,用一个3*3的卷积核,来对图像进行卷积操作(即把卷积核与对应的图像像素做乘积然后求和),然后得到3*3的卷积结果。
这个过程可理解为我们使用一个过滤器(卷积核)来过滤图像的各个小区域,从而得到这些小区域的特征值。在实际训练过程中,卷积核的值是在学习过程中的学习到的。
在具体应用中,往往有多个卷积核,可以认为,每个卷积核代表了一种图像模式,如果某个图像块与此卷积核卷积出的值大,则认为此图像块十分接近于此卷积核。如果我们设计了6个卷积核,可以理解:我们认为这个图像上有6种底层纹理模式,即我们用6种基础模式就能描绘出一副图像。
1.3 池化(Pooling)
如图即为一个池化的过程:
上图中,可以看到,原始图片是20*20的,我们对其进行下采样,采样窗口为10*10,最终将其采样成为一个2*2大小的特征图。
下采样的目的是为了降低数据维度,虽然数据维度降低了,但特征的统计属性仍能够描述图像,而且由于降低了数据维度,有效地避免了过拟合。在实际应用中,池化根据下采样的方法,分为最大值下采样(Max-Pooling)与平均值下采样(Mean-Pooling)。
1.4 训练过程
卷积神经网络的训练过程与传统神经网络类似,也是参照了反向传播算法。
第一阶段,前向传播阶段:
a)从样本集中取一个样本,将X输入网络;
b)计算相应的实际输出.
在此阶段,信息从输入层经过逐级的变换,传送到输出层。这个过程也是网络在完成训练后正常运行时执行的过程。在此过程中,网络执行的是计算(实际上就是输入与每层的权值矩阵相点乘,得到最后的输出结果):
第二阶段,向后传播阶段
a)算实际输出与相应的理想输出
的差;
b)按极小化误差的方法反向传播调整权矩阵。
1.5 卷积神经网络的优点
1)输入图像和网络的拓扑结构能够很好的吻合;
2)特征提取和模式分类同时进行,并同时在训练中产生;
3)权重共享可以减少网络的训练参数,使神经网络结构变得更简单,适应性更强。
上述纯属整理自博客:深度学习简介(一)——卷积神经网络
Deep Learning(深度学习)学习笔记整理系列之(七)
CNN理论推导的博客:Deep Learning论文笔记之(四)CNN卷积神经网络推导和实现
2 常见的几种卷积神经网络
2.1 LeNet
主要用来进行手写字符的识别与分类。其网络结构如图:
上图为LeNet结构图,是一个6层网络结构:三个卷积层,两个下采样层和一个全连接层(图中C表示卷积层,S代表下采样层,F代表全连接层)。其中,C5层也可以看成是一个全连接层,因为C5的卷积核大小和输入图像的大小一致,都是5*5。
网络特点:
1)每个卷积层包括三部分:卷积、池化和非线性激活函数(sigmoid激活函数)
2)使用卷积提取空间特征;
3)降采样层使用平均池化;
2.1 AlexNet
AlexNet由hinton的学生Alex Krizhevsky于2012年提出,这证明了卷积神经网络在复杂模型下的有效性,确立了深度学习,或卷积神经网络在计算机视觉的统治地位。其网络结构如图:
AlexNet的结构及参数如上图所示,是8层网络结构(忽略激活,池化,LRN,和dropout层),有5个卷积层和3个全连接层,第一个卷积层使用大的卷积核,大小为11*11,步长为4,第二卷积层使用5*5的卷积核大小,步长为1。激活函数使用ReLU,池化层使用重叠的最大池化,大小为3*3,步长为2。在全连接层加了dropout,第一次将其实用化。(AlexNet详解)
网络特点:
1)使用两块GPU并行加速训练,大大降低了训练时间;
2)成功使用ReLu作为激活函数,解决了网络较深时的梯度弥散问题;
3)使用数据增强、dropout和LRN层来防止网络过拟合,增强了网络的泛化能力;
2.3 VggNet
VGGNET是牛津大学计算机视觉组和Google DeepMind公司一起研发的深度卷积神经网络。此网络特点是泛化性能很好,容易迁移到其他的图像设别项目上,可以下载VGGNet训练好的参数进行很好的初始化权重操作,很多卷积神经网络都是以该网络为基础,比如FCN,UNet,SegNet等。
上图为VGG16的网络结构,共16层(不包括池化和softmax层),所有的卷积核都使用3*3的大小,池化都使用大小为2*2,步长为2的最大池化,卷积层深度依次为64-->128-->256-->512-->512.
网络特点:
与AlexNet有点像,不同在于:
1)主要区别:网络的深度。将网络层数加到了16-19层(不包括池化和softmax层),而AlexNet是8层结构;
2)将卷积层提升到卷积块的概念。卷积块有2~3个卷积层构成,使网络有更大感受野的同时能降低网络参数,同时多次使用ReLu激活函数有更多的线性变换,学习能力更强;
3)在训练时和预测时使用Multi-Scale做数据增强。训练时将同一张图片缩放到不同的尺寸,在随机剪裁到224*224的大小,能够增加数据量。预测时将同一张图片缩放到不同尺寸做预测,最后取平均值。
2.4 ResNet
ResNet(残差神经网络)由微软研究院的何凯明等4名华人于2015年提出,成功训练了152层超级深的卷积神经网络,效果非常突出,而且容易结合到其他网络结构中。其网络结构为:
上图为残差神经网络的基本模块(也叫残差学习单元),输入x,输出F(x)+x,F(x)戴表网络中数据的一系列乘、加操作,假设神经网络最优的拟合结果输出为H(x)=F(x)+x,那么神经网络最优的F(x)即为H(x)与x的残差,通过拟合残差来提升网络效果。因为训练的时候至少可以保证残差为0,保证增加残差学习单元不会降低网络性能,假设一个浅层网络达到了饱和的准确率,后面再加上这个残差学习单元,起码误差不会增加。(参考:ResNet详细解释)
通过不断堆叠这个基本模块,就可以得到最终的ResNet模型,理论上可以无限堆叠而不改变网络的性能。下图为一个34层的ResNet网络。
网络特点
1)使得训练超级深的神经网络成为可能,避免了加深神经网络,准确率达到了饱和的现象(后来将层数增加到了1000层);
2)输入可以直接连接到输出,使得整个网络只需要学习残差,简化学习目标和难度。
3)ResNet是一个推广性非常好的网络结构,容易和其他网络结合。
论文地址:
1. LeNet论文
2. AlexNet论文
3. VGGNet论文
4. ResNet论文
3 TextCNN原理
Yoon Kim在论文Convolutional Neural Networks for Sentence Classification提出TextCNN。将卷积神经网络CNN应用到文本分类任务,利用多个不同的size的kernel来提取句子中的关键信息(类似于多窗口大小的ngram),从而能够更好地捕捉局部相关性。
网络结构:
TextCNN详解原理如下:
TextCNN详细过程:
1)Embedding:第一层是图中最左边的7*5的句子矩阵,每行是词向量,维度为5,这个可以类比为图像中的原始像素点;
2)Convolution:然后经过kernel_sizes=(2,3,4)的一维卷积层,每个kernel_size有两个输出channel;
3)MaxPolling:第三层是一个1-max pooling层,这样不同长度句子经过pooling层之后都能变成定长的表示;
4)FullConnection and Softmax:最后接一岑全连接的softmax层,输出每个类别的概率。
通道(channels):
1)图像中可以利用(R,G,B)作为不同channel;
2)文本的输入channel通常是不同方式的embedding方式(比如word2vec或Glove),实践中也有利用静态词向量和fine-tunning词向量作为不同channel的做法;
一维卷积(conv-1d):
1)图像为二位数据
2)文本是一维数据,因此在TextCNN卷积用的是一维卷积(在word-level上是一维卷积;虽然文本经过词向量表达后是二维i而数据,但是在embedding-level上的二维卷积没有意义)。一维卷积带来的问题是需要通过设计不同的kernel_size的filter获取不同宽度的视野。
Pooling层:
利用CNN解决文本分类问题的文章海参很多的,比如这篇A Convolutional Neural Network for Modelling Sentences最有意思的输入是在 pooling 改成 (dynamic) k-max pooling ,pooling阶段保留 k 个最大的信息,保留了全局的序列信息。
上述来自博客:[NLP] TextCNN模型原理和实现
4 TextCNN模型来进行文本分类
基于Keras深度学习框架的实现代码:
# encoding:utf-8
import logging # 输入运行日志
from keras import Input
from keras.layers import Conv1D,MaxPool1D,Dense,Flatten,concatenate,Embedding
from keras.models import Model
from keras.utils import plot_model
def textcnn(max_sequence_length,
max_token_num,
embedding_dim,
output_dim,
model_img_path=None,
embedding_matrix=None):
"""
TextCNN:1.embedding layers, 2. convolution layer 3.max-pooling, 4.softmax layer
:return:
"""
x_input = Input(shape(max_sequence_length,))
logging.info('x_input.shape:%s'%str(x_input.shape)) #(?,60)
if embedding_matrix is None:
x_emb = Embedding(input_dim=max_token_num,output_dim=embedding_dim,
input_length=max_sequence_length)(x_input)
else:
x_emb = Embedding(input_dim=max_token_num,output_dim=embedding_dim,
input_length=max_sequence_length,weights=[embedding_matrix],
trainable=True)(x_input)
logging.info('x_emb.shape:%s'%str(x_emb.shape)) # (?,60,300)
pool_output = []
kernel_sizes = [2,3,4]
for kernel_size in kernel_sizes:
c = Conv1D(filters=2,kernel_size=kernel_size,strides=1)(x_emb)
p = MaxPool1D(pool_size=int(c.shape[1]))(c)
pool_output.append(p)
logging.info('kernel_size:%s \t c.shape:%s \t p.shape: %s'%
(kernel_size,str(c.shape),str(p.shape)))
pool_output = concatenate([p for p in pool_output])
logging.info('pool_output.shape:%s'%str(pool_output.shape)) #(?,1,6)
x_flatten = Flatten()(pool_output) # (?,6)
y = Dense(output_dim,activation='softmax')(x_flatten) #(?,2)
logging.info('y.shape:%s \n'%str(y.shape))
model = Model([x_input],outputs=[y])
if model_img_path:
plot_model(model,to_file=model_img_path,show_shapes=True,show_layer_names=False)
model.summary()
return model
用于cnews的textcnn文本分类代码:https://github.com/Yuanyiyi/NLP_learning/blob/master/textCNN_pred.py