一、前言

这篇卷积神经网络是前面介绍的多层神经网络的进一步深入,它将深度学习的思想引入到了神经网络当中,通过卷积运算来由浅入深的提取图像的不同层次的特征,而利用神经网络的训练过程让整个网络自动调节卷积核的参数,从而无监督的产生了最适合的分类特征。这个概括可能有点抽象,我尽量在下面描述细致一些,但如果要更深入了解整个过程的原理,需要去了解DeepLearning。

这篇文章会涉及到卷积的原理与图像特征提取的一般概念,并详细描述卷积神经网络的实现。但是由于精力有限,没有对人类视觉的分层以及机器学习等原理有进一步介绍,后面会在深度学习相关文章中展开描述。

二、卷积

卷积是分析数学中一种很重要的运算,其实是一个很简单的概念,但是很多做图像处理的人对这个概念都解释不清,为了简单起见,这里面我们只介绍离散形式的卷积,那么在图像上,对图像用一个卷积核进行卷积运算,实际上是一个滤波的过程。我们先看一下卷积的基本数学表示:

f(x,y)∘w(x,y)=∑s=−aa∑t=−bbw(s,t)f(x−s,y−t)f(x,y)∘w(x,y)=∑s=−aa∑t=−bbw(s,t)f(x−s,y−t)

其中I=f(x,y)I=f(x,y)是一个图像,f(x,y)f(x,y)是图像I上面xx行yy列上点的灰度值。而w(x,y)w(x,y)有太多名字叫了,滤波器、卷积核、响应函数等等,而aa和bb定义了卷积核即w(x,y)w(x,y)的大小。

从上面的式子中,可以很明显的看到,卷积实际上是提供了一个权重模板,这个模板在图像上滑动,并将中心依次与图像中每一个像素对齐,然后对这个模板覆盖的所有像素进行加权,并将结果作为这个卷积核在图像上该点的响应。所以从整个卷积运算我们可以看到以下几点:

1)卷积是一种线性运算

2)卷积核的大小,定义了图像中任何一点参与运算的邻域的大小。

3)卷积核上的权值大小说明了对应的邻域点对最后结果的贡献能力,权重越大,贡献能力越大。

4)卷积核沿着图像所有像素移动并计算响应,会得到一个和原图像等大图像。

5)在处理边缘上点时,卷积核会覆盖到图像外层没有定义的点,这时候有几种方法设定这些没有定义的点,可以用内层像素镜像复制,也可以全设置为0。

三、卷积特征层

其实图像特征提取在博客里的一些其他文章都有提过,这里我想说一下图像特征提取与卷积的关系。其实大部分的图像特征提取都依赖于卷积运算,比如显著的边缘特征就是用各种梯度卷积算子对图像进行滤波的结果。一个图像里目标特征主要体现在像素与周围像素之间形成的关系,这些邻域像素关系形成了线条、角点、轮廓等。而卷积运算正是这种用邻域点按一定权重去重新定义该点值的运算。

水平梯度的卷积算子:

竖直梯度的卷积算子:

根据深度学习关于人的视觉分层的理论,人的视觉对目标的辨识是分层的,低层会提取一些边缘特征,然后高一些层次进行形状或目标的认知,更高层的会分析一些运动和行为。也就是说高层的特征是低层特征的组合,从低层到高层的特征表示越来越抽象,越来越能表现语义或者意图。而抽象层面越高,存在的可能猜测就越少,就越利于分类。

而深度学习就是通过这种分层的自动特征提取来达到目标分类,先构建一些基本的特征层,然后用这些基础特征去构建更高层的抽象,更精准的分类特征。

那整个卷积神经网络的结构也就很容易理解了,它在普通的多层神经网络的前面加了2层特征层,这两层特征层是通过权重可调整的卷积运算实现的。

四、卷积神经网络

在原来的多层神经网络结构中,每一层的所有结点会按照连续线的权重向前计算,成为下一层结点的输出。而每一条权重连结线都彼此不同,互不共享。每一个下一层结点的值与前一层所有结点都相关。

与普通多层神经网络不同的是,卷积神经网络里,有特征抽取层与降维层,这些层的结点连结是部分连接且,一幅特征图由一个卷积核生成,这一幅特征图上的所有结点共享这一组卷积核的参数。

这里我们设计一个5层的卷积神经网络,一个输入层,一个输出层,2个特征提取层,一个全连接的隐藏层。下面详细说明每一层的设计思路。

在一般的介绍卷积神经网络的文章中你可能会看到在特征层之间还有2层降维层,在这里我们将卷积与降维同步进行,只用在卷积运算时,遍历图像中像素时按步长间隔遍历即可。

输入层:普通的多层神经网络,第一层就是特征向量。一般图像经过人为的特征挑选,通过特征函数计算得到特征向量,并作为神经网络的输入。而卷积神经网络的输出层则为整个图像,如上图示例29*29,那么我们可以将图像按列展开,形成841个结点。而第一层的结点向前没有任何的连结线。

第1层:第1层是特征层,它是由6个卷积模板与第一层的图像做卷积形成的6幅13*13的图像。也就是说这一层中我们算上一个偏置权重,一共有只有(5*5+1)*6=156权重参数,但是,第二层的结点是将6张图像按列展开,即有6*13*13=1014个结点。

而第2层构建的真正难点在于,连结线的设定,当前层的结点并不是与前一层的所有结点相连,而是只与25邻域点连接,所以第二层一定有(25+1)*13*13*6=26364条连线,但是这些连结线共享了156个权值。按前面多层网络C++的设计中,每个连线对象有2个成员,一个是权重的索引,一个是上一层结点的索引,所以这里面要正确的设置好每个连线的索引值,这也是卷积神经网络与一般全连结层的区别。

第2层:第2层也是特征层,它是由50个特征图像组成,每个特征图像是5*5的大小,这个特征图像上的每一点都是由前一层6张特征图像中每个图像取25个邻域点最后在一起加权而成,所以每个点也就是一个结点有(5*5+1)*6=156个连结线,那么当前层一共有5*5*50=1250个结点,所以一共有195000个权重连结线,但是只有(5*5+1)*6*50=7800个权重参数,每个权重连结线的值都可以在7800个权重参数数组中找到索引。

所以第3层的关键也是,如何建立好每根连结线的权重索引与与前一层连结的结点的索引。

第3层:和普通多神经网络没有区别了,是一个隐藏层,有100个结点构成,每个结点与上一层中1250个结点相联,共有125100个权重与125100个连结线。

第4层:输出层,它个结点个数与分类数目有关,假设这里我们设置为10类,则输出层为10个结点,相应的期望值的设置在多层神经网络里已经介绍过了,每个输出结点与上面隐藏层的100个结点相连,共有(100+1)*10=1010条连结线,1010个权重。

从上面可以看出,卷积神经网络的核心在于卷积层的创建,所以在设计CNNLayer类的时候,需要两种创建网络层的成员函数,一个用于创建普通的全连接层,一个用于创建卷积层。

 1 class CNNlayer
2 {
3 private:
4 CNNlayer* preLayer;
5 vector<CNNneural> m_neurals;
6 vector<double> m_weights;
7 public:
8 CNNlayer(){ preLayer = nullptr; }
9 // 创建卷积层
10 void createConvLayer(unsigned curNumberOfNeurals, unsigned preNumberOfNeurals, unsigned preNumberOfFeatMaps, unsigned curNumberOfFeatMaps);
11 // 创建 普通层
12 void createLayer(unsigned curNumberOfNeurals,unsigned preNumberOfNeurals);
13 void backPropagate(vector<double>& dErrWrtDxn, vector<double>& dErrWrtDxnm, double eta);
14 };

创建普通层,在前面介绍的多层神经网络中已经给出过代码,它接收两个参数,一个是前面一层结点数,一个是当前层结点数。

而卷积层的创建则复杂的多,所有连结线的索引值的确定需要对整个网络有较清楚的了解。这里设计的createConvLayer函数,它接收4个参数,分别对应,当前层结点数,前一层结点数,前一层特征图的个数和当前层特征图像的个数。

下面是C++代码,要理解这一部分可以会稍有点难度,因为特征图实际中都被按列展开了,所以邻域这个概念会比较抽象,我们考虑把特征图像还原,从图像的角度去考虑。

 1 void CNNlayer::createConvLayer
2 (unsigned curNumberOfNeurals, unsigned preNumberOfNeurals, unsigned preNumberOfFeatMaps, unsigned curNumberOfFeatMaps)
3 {
4 // 前一层和当前层特征图的结点数
5 unsigned preImgSize = preNumberOfNeurals / preNumberOfFeatMaps;
6 unsigned curImgSize = curNumberOfNeurals / curNumberOfFeatMaps;
7
8 // 初始化权重
9 unsigned numberOfWeights = preNumberOfFeatMaps*curNumberOfFeatMaps*(5 * 5 + 1);
10 for (unsigned i = 0; i != numberOfWeights; i++)
11 {
12 m_weights.push_back(0.05*rand() / RAND_MAX);
13 }
14 // 建立所有连结线
15
16 for (unsigned i = 0; i != curNumberOfFeatMaps; i++)
17 {
18 unsigned imgRow = sqrt(preImgSize); //上一层特征图像的大小 ,imgRow=imgCol
19 // 间隙2进行取样,邻域周围25个点
20 for (int c = 2; c < imgRow-2; c= c+ 2)
21 {
22 for (int r = 2; r < imgRow-2; r =r + 2)
23 {
24 CNNneural neural;
25 for (unsigned k = 0; k != preNumberOfNeurals; k++)
26 {
27 for (int kk = 0; kk < (5*5+1); kk ++)
28 {
29 CNNconnection connection;
30 // 权重的索引
31 connection.weightIdx = i*(curNumberOfFeatMaps*(5 * 5 + 1)) + k*(5 * 5 + 1) + kk;
32 // 结点的索引
33 connection.neuralIdx = k*preImgSize + c*imgRow + r;
34 neural.m_connections.push_back(connection);
35 }
36 m_neurals.push_back(neural);
37 }
38 }
39 }
40 }
41 }

五、训练与识别

整个网络结构搭建好以后,训练只用按照多层神经网络那样训练即可,其中的权值更新策略都是一致的。所以总体来说,卷积神经网络与普通的多层神经网络,就是结构上不同。卷积神经网络多了特征提取层与降维层,他们之间结点的连结方式是部分连结,多个连结线共享权重。而多层神经网络前后两层之间结点是全连结。除了这以外,权值更新、训练、识别都是一致的。

训练得到一组权值,也就是说在这组权值下网络可以更好的提取图像特征用于分类识别。

关于源码的问题:个人非常不推荐直接用别人的源码,所以我的博客里所有文章不会给出整个工程的源码,但是会给出一些核心函数的代码,如果你仔细阅读文章,一定能够很好的理解算法的核心思想。尝试着去自己实现,会对你的理解更有帮助。有什么疑问可以直接在下面留言。

from: http://www.cnblogs.com/ronny/p/ann_03.html

神经网络:卷积神经网络CNN的更多相关文章

  1. 深度学习原理与框架-Tensorflow卷积神经网络-卷积神经网络mnist分类 1.tf.nn.conv2d(卷积操作) 2.tf.nn.max_pool(最大池化操作) 3.tf.nn.dropout(执行dropout操作) 4.tf.nn.softmax_cross_entropy_with_logits(交叉熵损失) 5.tf.truncated_normal(两个标准差内的正态分布)

    1. tf.nn.conv2d(x, w, strides=[1, 1, 1, 1], padding='SAME')  # 对数据进行卷积操作 参数说明:x表示输入数据,w表示卷积核, stride ...

  2. 卷积神经网络CNN与深度学习常用框架的介绍与使用

    一.神经网络为什么比传统的分类器好 1.传统的分类器有 LR(逻辑斯特回归) 或者 linear SVM ,多用来做线性分割,假如所有的样本可以看做一个个点,如下图,有蓝色的点和绿色的点,传统的分类器 ...

  3. CNN学习笔记:卷积神经网络

    CNN学习笔记:卷积神经网络 卷积神经网络 基本结构 卷积神经网络是一种层次模型,其输入是原始数据,如RGB图像.音频等.卷积神经网络通过卷积(convolution)操作.汇合(pooling)操作 ...

  4. 深度学习之卷积神经网络CNN及tensorflow代码实例

    深度学习之卷积神经网络CNN及tensorflow代码实例 什么是卷积? 卷积的定义 从数学上讲,卷积就是一种运算,是我们学习高等数学之后,新接触的一种运算,因为涉及到积分.级数,所以看起来觉得很复杂 ...

  5. 卷积神经网络基础(CNN)【转载】

    作者: Sanjay Chan [ http://blog.csdn.net/chenzomi ] 背景 之前在网上搜索了好多好多关于CNN的文章,由于网络上的文章很多断章取义或者描述不清晰,看了很多 ...

  6. paper 162:卷积神经网络(CNN)解析

    卷积神经网络(CNN)解析: 卷积神经网络CNN解析 概揽 Layers used to build ConvNets 卷积层Convolutional layer 池化层Pooling Layer ...

  7. Tensorflow卷积神经网络[转]

    Tensorflow卷积神经网络 卷积神经网络(Convolutional Neural Network, CNN)是一种前馈神经网络, 在计算机视觉等领域被广泛应用. 本文将简单介绍其原理并分析Te ...

  8. Convolutional Neural Networks卷积神经网络

    转自:http://blog.csdn.net/zouxy09/article/details/8781543 9.5.Convolutional Neural Networks卷积神经网络 卷积神经 ...

  9. 深度学习、图像识别入门,从VGG16卷积神经网络开始

    刚开始接触深度学习.卷积神经网络的时候非常懵逼,不知道从何入手,我觉得应该有一个进阶的过程,也就是说,理应有一些基本概念作为奠基石,让你有底气去完全理解一个庞大的卷积神经网络: 本文思路: 一.我认为 ...

  10. 深度学习:卷积神经网络(convolution neural network)

    (一)卷积神经网络 卷积神经网络最早是由Lecun在1998年提出的. 卷积神经网络通畅使用的三个基本概念为: 1.局部视觉域: 2.权值共享: 3.池化操作. 在卷积神经网络中,局部接受域表明输入图 ...

随机推荐

  1. onSaveInstanceState() 和 onRestoreInstanceState()

    本文介绍Android中关于Activity的两个神秘方法:onSaveInstanceState() 和 onRestoreInstanceState(),并且在介绍这两个方法之后,再分别来实现使用 ...

  2. WebRTC之带宽控制部分学习(1) ------基本demo的介绍

    转自:http://blog.csdn.net/u013160228/article/details/46392037 WebRTC的代码真是非常之大啊,下载以及编译了我好几天才搞完..... 可以看 ...

  3. rotate the clock

    A program test: You are given N round clocks. Every clock has M hands, and these hands can point to ...

  4. BPM 应用系统开发案例实战

    概述 IBM BPM 的前身是 Lombardi,是由 IBM 于 2009 年收购的产品,之后产品更名为 IBM WebSphere Lombardi Edition,目前最新版本称为 IBM BP ...

  5. CMMI 配置管理

    配置库的相关知识 通过建立物理配置库的设立规范.各配置库目录的设立原则,确保配置库的统一与规范,确保项目产品得到有效的管理与运用,提高资源的共享与利用:通过 变更管理活动,保证产品的完整.正确.一致, ...

  6. Can&#39;t find file: &#39;./mysql/plugin.frm&#39; (errno: 13)[mysql数据目录迁移错位]错误解决

    大概需要4个步骤,其中第1步通过service mysql stop停止数据库,第4步通过service mysql start启动数据库. 第2步移动数据文件,不知道是否为Ubuntu智能的原因,移 ...

  7. Atom 扩展离线安装

    1.下载原始包 2.解压放入atom的packages文件夹中 3.通过nodejs的npm指令进行安装 运行->cmd 4.重启Atom就ok了

  8. 【转】Java 内部类种类及使用解析

    Java 内部类种类及使用解析 内部类Inner Class 将相关的类组织在一起,从而降低了命名空间的混乱. 一个内部类可以定义在另一个类里,可以定义在函数里,甚至可以作为一个表达式的一部分. Ja ...

  9. 了解Java并学会创建Java项目(一个菜鸟的成长历程)

    计算机语言分类:了解 1)低级语言:更接近于计算机的语言 1.1)机器语言:由0和1组成的 1.2)汇编语言:有一些助记符号2)高级语言:更接近于人的语言 2.1)面向过程的:C... 2.2)面向对 ...

  10. bzoj1015星球大战

    1015: [JSOI2008]星球大战starwar Description 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系.某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝 ...