精华内容
下载资源
问答
  • CNN深度学习-字符识别;可以进行单张样本的识别;源代码是进行批量的测试,无法进行单张测试;test_example_CNN_yhw.m可以直接运行
  • VC++直接编译运行的cnn深度学习代码,例子是数字学习,稍微修改可进行汉字等训练,
  • CNN深度学习基础

    千次阅读 2018-04-15 17:25:20
    当我2013年再次来到北京时,有一个词似乎比“机器学习”更火,那就是“深度学习”。    本博客内写过一些机器学习相关的文章,但上一篇技术文章“LDA主题模型”还是写于2014年11月份,毕竟...

    转自:v_JULY_v的博客


    1 前言

        2012年我在北京组织过8期machine learning读书会,那时“机器学习”非常火,很多人都对其抱有巨大的热情。当我2013年再次来到北京时,有一个词似乎比“机器学习”更火,那就是“深度学习”。

        本博客内写过一些机器学习相关的文章,但上一篇技术文章“LDA主题模型”还是写于2014年11月份,毕竟自2015年开始创业做在线教育后,太多的杂事、琐碎事,让我一直想再写点技术性文章但每每恨时间抽不开。然由于公司在不断开机器学习、深度学习等相关的在线课程,耳濡目染中,总会顺带着学习学习。

        我虽不参与讲任何课程(我所在公司“七月在线”的所有在线课程都是由目前讲师团队的60位讲师讲),但依然可以用最最小白的方式 把一些初看复杂的东西抽丝剥茧的通俗写出来。这算重写技术博客的价值所在。

        在dl中,有一个很重要的概念,就是卷积神经网络CNN,基本是入门dl必须搞懂的东西。本文基本根据斯坦福的机器学习公开课、cs231n、与七月在线寒小阳讲的5月dl班第4次课CNN与常用框架视频所写,是一篇课程笔记。

        一开始本文只是想重点讲下CNN中的卷积操作具体是怎么计算怎么操作的,但后面不断补充,包括增加不少自己的理解,故写成了关于卷积神经网络的通俗导论性的文章。有何问题,欢迎不吝指正。



    2 人工神经网络

    2.1 神经元

        神经网络由大量的神经元相互连接而成。每个神经元接受线性组合的输入后,最开始只是简单的线性加权,后来给每个神经元加上了非线性的激活函数,从而进行非线性变换后输出。每两个神经元之间的连接代表加权值,称之为权重(weight)。不同的权重和激活函数,则会导致神经网络不同的输出。

        举个手写识别的例子,给定一个未知数字,让神经网络识别是什么数字。此时的神经网络的输入由一组被输入图像的像素所激活的输入神经元所定义。在通过非线性激活函数进行非线性变换后,神经元被激活然后被传递到其他神经元。重复这一过程,直到最后一个输出神经元被激活。从而识别当前数字是什么字。

        神经网络的每个神经元如下

        基本wx + b的形式,其中

    • 表示输入向量
    • 为权重,几个输入则意味着有几个权重,即每个输入都被赋予一个权重
    • b为偏置bias
    • g(z) 为激活函数
    • a 为输出

        如果只是上面这样一说,估计以前没接触过的十有八九又必定迷糊了。事实上,上述简单模型可以追溯到20世纪50/60年代的感知器,可以把感知器理解为一个根据不同因素、以及各个因素的重要性程度而做决策的模型。

        举个例子,这周末北京有一草莓音乐节,那去不去呢?决定你是否去有二个因素,这二个因素可以对应二个输入,分别用x1、x2表示。此外,这二个因素对做决策的影响程度不一样,各自的影响程度用权重w1、w2表示。一般来说,音乐节的演唱嘉宾会非常影响你去不去,唱得好的前提下 即便没人陪同都可忍受,但如果唱得不好还不如你上台唱呢。所以,我们可以如下表示:

    • :是否有喜欢的演唱嘉宾。 = 1 你喜欢这些嘉宾, = 0 你不喜欢这些嘉宾。嘉宾因素的权重 = 7
    • :是否有人陪你同去。 = 1 有人陪你同去, = 0 没人陪你同去。是否有人陪同的权重 = 3。
        这样,咱们的决策模型便建立起来了:g(z) = g( + + b ),g表示激活函数,这里的b可以理解成 为更好达到目标而做调整的偏置项。
        一开始为了简单,人们把激活函数定义成一个线性函数,即对于结果做一个线性变化,比如一个简单的线性激活函数是g(z) = z,输出都是输入的线性变换。后来实际应用中发现,线性激活函数太过局限,于是人们引入了非线性激活函数。

    2.2 激活函数

        常用的非线性激活函数有sigmoid、tanhrelu等等,前两者sigmoid/tanh比较常见于全连接层,后者relu常见于卷积层。这里先简要介绍下最基础的sigmoid函数(btw,在本博客中SVM那篇文章开头有提过)。

        sigmoid的函数表达式如下

        其中z是一个线性组合,比如z可以等于:b +  + 通过代入很大的正数或很小的负数到g(z)函数中可知,其结果趋近于0或1

        因此,sigmoid函数g(z)的图形表示如下( 横轴表示定义域z,纵轴表示值域g(z) ):

        也就是说,sigmoid函数的功能是相当于把一个实数压缩至0到1之间。当z是非常大的正数时,g(z)会趋近于1,而z是非常小的负数时,则g(z)会趋近于0

        压缩至0到1有何用处呢?用处是这样一来便可以把激活函数看作一种“分类的概率”,比如激活函数的输出为0.9的话便可以解释为90%的概率为正样本。

        举个例子,如下图(图引自Stanford机器学习公开课

    逻辑与

        z = b +  + ,其中b为偏置项 假定取-30,都取为20

    • 如果 = 0  = 0,则z = -30,g(z) = 1/( 1 + e^-z )趋近于0。此外,从上图sigmoid函数的图形上也可以看出,当z=-30的时候,g(z)的值趋近于0
    • 如果 = 0 = 1,或 =1 = 0,则z = b +  +  = -30 + 20 = -10,同样,g(z)的值趋近于0
    • 如果 = 1 = 1,则z = b +  +  = -30 + 20*1 + 20*1 = 10,此时,g(z)趋近于1。

        换言之,只有都取1的时候,g(z)→1,判定为正样本;取0的时候,g(z)→0,判定为负样本如此达到分类的目的。

    2.3 神经网络

        将下图的这种单个神经元

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


        上图中最左边的原始输入信息称之为输入层,最右边的神经元称之为输出层(上图中输出层只有一个神经元),中间的叫隐藏层。

        啥叫输入层、输出层、隐藏层呢?

    • 输入层(Input layer),众多神经元(Neuron)接受大量非线形输入讯息。输入的讯息称为输入向量。
    • 输出层(Output layer),讯息在神经元链接中传输、分析、权衡,形成输出结果。输出的讯息称为输出向量。
    • 隐藏层(Hidden layer),简称“隐层”,是输入层和输出层之间众多神经元和链接组成的各个层面。如果有多个隐藏层,则意味着多个激活函数。

        同时,每一层都可能由单个或多个神经元组成,每一层的输出将会作为下一层的输入数据。比如下图中间隐藏层来说,隐藏层的3个神经元a1、a2、a3皆各自接受来自多个不同权重的输入(因为有x1、x2、x3这三个输入,所以a1 a2 a3都会接受x1 x2 x3各自分别赋予的权重,即几个输入则几个权重),接着,a1、a2、a3又在自身各自不同权重的影响下 成为的输出层的输入,最终由输出层输出最终结果。

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

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

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




    3 卷积神经网络之层级结构

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


        上图中CNN要做的事情是:给定一张图片,是车还是马未知,是什么车也未知,现在需要模型判断这张图片里具体是一个什么东西,总之输出一个结果:如果是车 那是什么车

        所以

    • 最左边是数据输入层,对数据做一些处理,比如去均值(把输入数据各个维度都中心化为0,避免数据过多偏差,影响训练效果)、归一化(把所有的数据都归一到同样的范围)、PCA/白化等等。CNN只对训练集做“去均值”这一步。

        中间是

    • CONV:卷积计算层,线性乘积 求和。
    • RELU:激励层,上文2.2节中有提到:ReLU是激活函数的一种。
    • POOL:池化层,简言之,即取区域平均或最大。

        最右边是

    • FC:全连接层
        这几个部分中,卷积计算层是CNN的核心,下文将重点阐述。



    4 CNN之卷积计算层

    4.1 CNN怎么进行识别

        当我们给定一个”X”的图案,计算机怎么识别这个图案就是“X”呢?一个可能的办法就是计算机存储一张标准的“X”图案,然后把需要识别的未知图案跟标准”X”图案进行比对,如果二者一致,则判定未知图案即是一个”X”图案。
        而且即便未知图案可能有一些平移或稍稍变形,依然能辨别出它是一个X图案。如此,CNN是把未知图案和标准X图案一个局部一个局部的对比,如下图所示 [图来自参考文案25]

        而未知图案的局部和标准X图案的局部一个一个比对时的计算过程,便是卷积操作。卷积计算结果为1表示匹配,否则不匹配。
        接下来,我们来了解下什么是卷积操作。

    4.2 什么是卷积

        对图像(不同的数据窗口数据)和滤波矩阵(一组固定的权重:因为每个神经元的多个权重固定,所以又可以看做一个恒定的滤波器filter)做内积(逐个元素相乘再求和)的操作就是所谓的『卷积』操作,也是卷积神经网络的名字来源。
        非严格意义上来讲,下图中红框框起来的部分便可以理解为一个滤波器,即带着一组固定权重的神经元。多个滤波器叠加便成了卷积层。
        OK,举个具体的例子。比如下图中,图中左边部分是原始输入数据,图中中间部分是滤波器filter,图中右边是输出的新的二维数据。

        分解下上图
    对应位置上是数字先相乘后相加 =
        中间滤波器filter与数据窗口做内积,其具体计算过程则是:4*0 + 0*0 + 0*0 + 0*0 + 0*1 + 0*1 + 0*0 + 0*1 + -4*2 = -8

    4.3 图像上的卷积

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

        如下图所示

      

    4.4 GIF动态卷积图

        在CNN中,滤波器filter(带着一组固定权重的神经元)对局部输入数据进行卷积计算。每计算完一个数据窗口内的局部数据后,数据窗口不断平移滑动,直到计算完所有数据。这个过程中,有这么几个参数: 
      a. 深度depth:神经元个数,决定输出的depth厚度。同时代表滤波器个数。
      b. 步长stride:决定滑动多少步可以到边缘。
      c. 填充值zero-padding:在外围边缘补充若干圈0,方便从初始位置以步长为单位可以刚好滑倒末尾位置,通俗地讲就是为了总长能被步长整除。 
      这里写图片描述 
        cs231n课程中有一张卷积动图,貌似是用d3js 和一个util 画的,我根据cs231n的卷积动图依次截取了18张图,然后用一gif 制图工具制作了一gif 动态卷积图。如下gif 图所示
        可以看到:
    • 两个神经元,即depth=2,意味着有两个滤波器。
    • 数据窗口每次移动两个步长取3*3的局部数据,即stride=2。
    • zero-padding=1。
        然后分别以两个滤波器filter为轴滑动数组进行卷积计算,得到两组不同的结果。
        如果初看上图,可能不一定能立马理解啥意思,但结合上文的内容后,理解这个动图已经不是很困难的事情:
    • 左边是输入(7*7*3中,7*7代表图像的像素/长宽,3代表R、G、B 三个颜色通道)
    • 中间部分是两个不同的滤波器Filter w0、Filter w1
    • 最右边则是两个不同的输出

        随着左边数据窗口的平移滑动,滤波器Filter w0 / Filter w1对不同的局部数据进行卷积计算。

        值得一提的是:

    1. 左边数据在变化,每次滤波器都是针对某一局部的数据窗口进行卷积,这就是所谓的CNN中的局部感知机制。
    • 打个比方,滤波器就像一双眼睛,人类视角有限,一眼望去,只能看到这世界的局部。如果一眼就看到全世界,你会累死,而且一下子接受全世界所有信息,你大脑接收不过来。当然,即便是看局部,针对局部里的信息人类双眼也是有偏重、偏好的。比如看美女,对脸、胸、腿是重点关注,所以这3个输入的权重相对较大。
    与此同时,数据窗口滑动,导致输入在变化,但中间滤波器Filter w0的权重(即每个神经元连接数据窗口的权重)是固定不变的,这个权重不变即所谓的CNN中的参数(权重)共享机制。
    • 再打个比方,某人环游全世界,所看到的信息在变,但采集信息的双眼不变。btw,不同人的双眼 看同一个局部信息 所感受到的不同,即一千个读者有一千个哈姆雷特,所以不同的滤波器 就像不同的双眼,不同的人有着不同的反馈结果。

        我第一次看到上面这个动态图的时候,只觉得很炫,另外就是据说计算过程是“相乘后相加”,但到底具体是个怎么相乘后相加的计算过程 则无法一眼看出,网上也没有一目了然的计算过程。本文来细究下。

        首先,我们来分解下上述动图,如下图

        接着,我们细究下上图的具体计算过程。即上图中的输出结果1具体是怎么计算得到的呢?其实,类似wx + b,w对应滤波器Filter w0,x对应不同的数据窗口,b对应Bias b0,相当于滤波器Filter w0与一个个数据窗口相乘再求和后,最后加上Bias b0得到输出结果1,如下过程所示:

    1* 0 + 10 + -1

    +

    -10 + 00 + 11

    +

    -10 + -10 + 01


    +

    -10 + 00 + -10

    +

    00 + 01 + -11

    +

    10 + -10 + 02


    +

    00 + 10 + 00

    +

    10 + 02 + 10

    +

    00 + -10 + 10


    +

     

    1

    =

    1

        然后滤波器Filter w0固定不变,数据窗口向右移动2步,继续做内积计算,得到0的输出结果

        最后,换做另外一个不同的滤波器Filter w1、不同的偏置Bias b1,再跟图中最左边的数据窗口做卷积,可得到另外一个不同的输出。



    5 CNN之激励层与池化层

    5.1 ReLU激励

        2.2节介绍了激活函数sigmoid,但实际梯度下降中,sigmoid容易饱和、造成终止梯度传递,且没有0中心化。咋办呢,可以尝试另外一个激活函数:ReLU,其图形表示如下

        ReLU的优点是收敛快,求梯度简单。

    5.2 池化pool层

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


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



    6 后记

        本文基本上边看5月dl班寒讲的CNN视频边做笔记,之前断断续续看过不少CNN相关的资料(包括cs231n),但看过视频之后,才系统了解CNN到底是个什么东西,作为听众 寒讲的真心赞、清晰。然后在写CNN相关的东西时,发现一些前置知识(比如神经元、多层神经网络等也需要介绍下),包括CNN的其它层次机构(比如激励层),所以本文本只想简要介绍下卷积操作的,但考虑到知识之间的前后关联,所以越写越长,便成本文了。

        此外,在写作本文的过程中,请教了我们讲师团队里的寒、冯两位,感谢他两。同时,感谢爱可可老师的微博转发,感谢七月在线所有同事。

          

        以下是修改日志:

    • 2016年7月5日,修正了一些笔误、错误,以让全文更通俗、更精准。有任何问题或槽点,欢迎随时指出。
    • 2016年7月7日,第二轮修改完毕。且根据cs231n的卷积动图依次截取了18张图,然后用制图工具制作了一gif 动态卷积图,放在文中4.3节。
    • 2016年7月16日,完成第三轮修改。本轮修改主要体现在sigmoid函数的说明上,通过举例和统一相关符号让其含义更一目了然、更清晰。
    • 2016年8月15日,完成第四轮修改,增补相关细节。比如补充4.3节GIF动态卷积图中输入部分的解释,即7*7*3的含义(其中7*7代表图像的像素/长宽,3代表R、G、B 三个颜色通道)。不断更易懂。
    • 2016年8月22日,完成第五轮修改。本轮修改主要加强滤波器的解释,及引入CNN中滤波器的通俗比喻。
        July、最后修改于二零一六年八月二十二日中午于七月在线办公室。



    7 参考文献及推荐阅读

    1. 人工神经网络wikipedia
    2. 斯坦福机器学习公开课
    3. http://neuralnetworksanddeeplearning.com/
    4. 雨石 卷积神经网络:http://blog.csdn.net/stdcoutzyx/article/details/41596663
    5. cs231n 神经网络结构与神经元激励函数:http://cs231n.github.io/neural-networks-1/中译版
    6. cs231n 卷积神经网络:http://cs231n.github.io/convolutional-networks/
    7. 七月在线寒老师讲的5月dl班第4次课CNN与常用框架视频,已经剪切部分放在七月在线官网:julyedu.com
    8. 七月在线5月深度学习班第5课CNN训练注意事项部分视频:https://www.julyedu.com/video/play/42/207
    9. 七月在线5月深度学习班:https://www.julyedu.com/course/getDetail/37
    10. 七月在线5月深度学习班课程笔记——No.4《CNN与常用框架》:http://blog.csdn.net/joycewyj/article/details/51792477
    11. 七月在线6月数据数据挖掘班第7课视频:数据分类与排序
    12. 手把手入门神经网络系列(1)从初等数学的角度初探神经网络:http://blog.csdn.net/han_xiaoyang/article/details/50100367
    13. 深度学习与计算机视觉系列(6)神经网络结构与神经元激励函数:http://blog.csdn.net/han_xiaoyang/article/details/50447834
    14. 深度学习与计算机视觉系列(10)_细说卷积神经网络:http://blog.csdn.net/han_xiaoyang/article/details/50542880
    15. zxy 图像卷积与滤波的一些知识点:http://blog.csdn.net/zouxy09/article/details/49080029
    16. zxy 深度学习CNN笔记:http://blog.csdn.net/zouxy09/article/details/8781543/
    17. http://www.wildml.com/2015/11/understanding-convolutional-neural-networks-for-nlp/中译版
    18. 《神经网络与深度学习》中文讲义:http://vdisk.weibo.com/s/A_pmE4iIPs9D
    19. ReLU与sigmoid/tanh的区别:https://www.zhihu.com/question/29021768
    20. CNN、RNN、DNN内部网络结构区别:https://www.zhihu.com/question/34681168
    21. 理解卷积:https://www.zhihu.com/question/22298352
    22. 神经网络与深度学习简史:1 感知机和BP算法4 深度学习的伟大复兴
    23. 在线制作gif 动图:http://www.tuyitu.com/photoshop/gif.htm
    24. 支持向量机通俗导论(理解SVM的三层境界)
    25. CNN究竟是怎样一步一步工作的? 本博客把卷积操作具体怎么个计算过程写清楚了,但这篇把为何要卷积操作也写清楚了,而且配偶图非常形象,甚赞。
    展开全文
  • 仅为效果,学习计算机视觉 CNN ,可以关注楼主 AI工匠
  • 基于 Faster R-CNN深度学习的物体检测 这个例子展示如何使用一个称为 Faster R-CNN (区域卷积神经网络) 的深度学习的技巧训练物体检测器。 综述 这个例子展示如何训练一个 Faster R-CNN 物体检测器,用于检测车辆...

    基于 Faster R-CNN深度学习的物体检测

    这个例子展示如何使用一个称为 Faster R-CNN (区域卷积神经网络) 的深度学习的技巧训练物体检测器。

    综述

    这个例子展示如何训练一个 Faster R-CNN 物体检测器,用于检测车辆。Faster R-CNN1 是 R-CNN2 和 Fast R-CNN3 物体检测技巧的推广。所有这三个技巧都使用卷积神经网络 (CNN)。区别在于他们如何选择需要处理的区域,以及他们如何将这些区域进行分类。R-CNN 和 Fast R-CNN 使用区域建议算法作为运行 CNN 的预处理步骤。建议算法典型的例子有 EdgeBoxes4 或者选择性搜索5,独立于 CNN。在 Fast R-CNN 中,这种技巧变成了运行 CNN 的计算瓶颈。 Faster R-CNN 通过把区域建议机制用 CNN 实现,从而解决了这个问题,使得区域建议变成了 CNN 训练和预测的一部分。

    在本例中,汽车探测器用来自 计算机视觉系统工具箱TM trainFasterRCNNObjectDetector 函数来训练。这个例子有如下几个部分:

    • 载入数据集。
    • 设计卷积神经网络 (CNN)。
    • 配置训练选项。
    • 训练 Faster R-CNN 物体检测器。
    • 评价训练过的检测器。
      注意:这个例子需要计算机视觉系统工具箱TM,图像处理工具箱TM,和深度学习工具箱TM
      强烈推荐使用支持 CUDA 的 NVIDIATM GPU,计算匹配版本在 3.0 或更高。使用 GPU 需要并行计算工具箱TM

    载入数据集

    这个例子使用小车辆数据集,由 295 张图片组成。每一张图片有一到两个做过标记车辆的标签。小数据集有利于探索 Faster R-CNN 训练过程,但实践中,需要更多的图片,用以训练更强大的探测器。

    % 载入汽车数据集
    data = load('fasterRCNNVehicleTrainingData.mat')
    vehicleDatsaset = data.vehicleTrainingData;
    

    训练数据集存于一张表中。第一列含有图像文件的路径。余下的列含有车辆的 ROI 标签。

    % 显示数据集的前几列
    vehicleDataset(1:4, :)
    
    ans=4×2 table
              imageFilename             vehicle   
        __________________________    ____________
    
        'vehicles/image_00001.jpg'    [1x4 double]
        'vehicles/image_00002.jpg'    [1x4 double]
        'vehicles/image_00003.jpg'    [1x4 double]
        'vehicles/image_00004.jpg'    [1x4 double]
    

    从数据集中显示一张图片,以理解其中一张图片的类型:

    % 补全汽车数据集文件夹的完整路径
    dataDir = fullfile(toolboxdir('vision'),'visiondata');
    vehicleDataset.imageFilename = fullfile(dataDir, vehicleDataset.imageFilename);
    
    % 读取其中一张图片
    I = imread(vehicleDataset.imageFilename{10});
    
    % 插入 ROI 标签
    I = insertShape(I, 'Rectangle', vehicleDataset.vehicle{10});
    
    % 修改图片大小并显示
    I = imresize(I,3);
    figure
    imshow(I)
    

    在这里插入图片描述
    把数据集分割为训练集,用于训练检测器,以及用于评价检测器的测试集。选择 60% 的数据用于训练。余下的用于评价。

    % 把数据分为训练和测试集
    idx = floor(0.6 * height(vehicleDataset));
    trainingData = vehicleDataset(1:idx,:);
    testData = vehicleDataset(idx:end,:);
    

    训练卷积神经网络 (CNN)

    CNN 是 Faster R-CNN 物体检测器的根基。通过深度学习工具箱TM的函数一层一层建立 CNN。

    imageInputLayer 开始,它定义了输入的类型和大小。对分类任务,输入通常是训练图片的大小。对检测任务,CNN 需要分析更小的图片,所以,输入大小必须与数据集中最小的物体大小相似。在这个数据集中,所有物体都大于 [16 16],所以,选择输入尺寸为 [32 32]。这个输入尺寸是处理时间和空间细节之间的权衡后得出的结果。

    % 建立图像输入层
    inputLayer = imageInputLayer([32 32 3]);
    

    接下来,定义网络的中间层。中间层以 convolution2dLayer, reluLayer (整流线性单元),以及 maxPooling2dLayer 的重复构成。这些层是卷积神经网络的核心积木。

    % 定义卷积层参数
    filterSize = [3 3];
    numFilters = 32;
    
    % 建立中间层
    middleLayers = [
                    
        convolution2dLayer(filterSize, numFilters, 'Padding', 1)   
        reluLayer()
        convolution2dLayer(filterSize, numFilters, 'Padding', 1)  
        reluLayer() 
        maxPooling2dLayer(3, 'Stride',2)    
        
        ];
    

    你可以建立更深的神经网络,通过重复这些基本层。然而,为了避免数据过早降采样,不要用太多的池化层。在网络中过早降采样会造成有用信息的损失。

    CNN 的结束层通常是 fullyConnectedLayersoftmaxLayer 的结合。

    finalLayers = [
        
        % 增加一个全连接层,有 64 个神经元的输出。这层的输出大小是一个长度为 64 的数组。
        fullyConnectedLayer(64)
    
        % 增加一个 ReLU 非线性
        reluLayer()
    
        % 增加最后一个完全连接层。这时,网络必须产生输出,用以度量图像属于哪一个物体类别或者是背景。
        % 这种度量用后面我们会看到的损失层实现。
        fullyConnectedLayer(width(vehicleDataset))
    
        % 增加 softmax 损失层和分类层。
        softmaxLayer()
        classificationLayer()
    ];
    

    结合输入、中间、结束层。

    layers = [
        inputLayer
        middleLayers
        finalLayers
        ]
    
    layers = 
      11x1 Layer array with layers:
    
         1   ''   Image Input             32x32x3 images with 'zerocenter' normalization
         2   ''   Convolution             32 3x3 convolutions with stride [1  1] and padding [1  1  1  1]
         3   ''   ReLU                    ReLU
         4   ''   Convolution             32 3x3 convolutions with stride [1  1] and padding [1  1  1  1]
         5   ''   ReLU                    ReLU
         6   ''   Max Pooling             3x3 max pooling with stride [2  2] and padding [0  0  0  0]
         7   ''   Fully Connected         64 fully connected layer
         8   ''   ReLU                    ReLU
         9   ''   Fully Connected         2 fully connected layer
        10   ''   Softmax                 softmax
        11   ''   Classification Output   crossentropyex
    

    配置训练选项

    trainFasterRCNNObjectDetector 以四步训练检测器。头两步训练 Faster R-CNN 中需要的区域建议和检测网络。最后两步结合前面给出的两个网络,产生单个用于检测的网络1。训练每一步都可能会有不同的收敛率,所以,每一步设置不同的参数是有好处的。为了明确网络训练的选项,使用 trainingOptions

    %1 步的选项
    optionsStage1 = trainingOptions('sgdm', ...
        'MaxEpochs', 10, ...
        'MiniBatchSize', 1, ...
        'InitialLearnRate', 1e-3, ...
        'CheckpointPath', tempdir);
    
    %2 步的选项
    optionsStage2 = trainingOptions('sgdm', ...
        'MaxEpochs', 10, ...
        'MiniBatchSize', 1, ...
        'InitialLearnRate', 1e-3, ...
        'CheckpointPath', tempdir);
    
    %3 步的选项
    optionsStage3 = trainingOptions('sgdm', ...
        'MaxEpochs', 10, ...
        'MiniBatchSize', 1, ...
        'InitialLearnRate', 1e-3, ...
        'CheckpointPath', tempdir);
    
    %4 步的选项
    optionsStage4 = trainingOptions('sgdm', ...
        'MaxEpochs', 10, ...
        'MiniBatchSize', 1, ...
        'InitialLearnRate', 1e-3, ...
        'CheckpointPath', tempdir);
    
    options = [
        optionsStage1
        optionsStage2
        optionsStage3
        optionsStage4
        ];
    

    这里,头两步的学习率比后两步的学习率高。因为后两步是精调步,网络权重可以比前两步调节得更慢。Faster R-CNN 中的小批次尺寸必须是 1,它在每一个迭代中对每一张图片都会处理多个图像区域。

    此外,'CheckpointPath' 是所有训练选项的暂存路径。这个名称-值对让我们保存训练到一半的检测器。如果训练被中断,比如突然断电或者系统崩溃,你仍然可以通过存档点继续训练。

    训练 Faster R-CNN

    现在 CNN 和训练选项都已经定义完毕,你可以用 trainFasterRCNNObjectDetector 训练检测器。

    训练过程中,训练图像中的多个图像区域被处理。采样图像中的区域数被 'NumRegionsToSample''PositiveOverlapRange''NegativeOverlapRange' 名称-值对控制了被用于训练的图像区域。正训练样本是与真相边界框重叠在 0.60.61.01.0 的范围,这通过边界框 IoU 度量求出。负样本是范围在 000.30.3 的样本。这些参数的最佳值应该通过验证集确定。

    对 Faster R-CNN 训练,使用 MATLAB 并行池以减少训练时间是强烈推荐的trainFasterRCNNObjectDetector 根据你的并行设置,自动建立并使用并行池。确保并行池在训练前已经启用。

    强烈推荐使用支持 CUDA 的 NVIDIATM GPU 进行训练,计算匹配版本在 3.0 或更高。

    为了节约运行这个例子的时间,我们从磁盘上读出一个预先训练好的网络。要训练自己的网络,可以配置 doTrainingAndEval 变量为真。

    % 为了节约本例的运算时间,我们从磁盘上读出预先训练好的网络。
    % 将此标记设为 true,以训练网络
    doTrainingAndEval = false;
    
    if doTrainingAndEval
        % 设置随机种子,以使得训练可以重复.
        rng(0);
        
        % 训练 Faster R-CNN 检测器. 选择 BoxPyramidScale 为 1.2 使得我们可以识别多尺度的物体。
        detector = trainFasterRCNNObjectDetector(trainingData, layers, options, ...
            'NegativeOverlapRange', [0 0.3], ...
            'PositiveOverlapRange', [0.6 1], ...
            'NumRegionsToSample', [256 128 256 128], ...
            'BoxPyramidScale', 1.2);
    else
        % 载入预先训练好的检测器
        detector = data.detector;
    end
    

    快速验证训练效果,可以在测试图像上运行检测器。

    % 读取一副测试图像
    I = imread(testData.imageFilename{1});
    
    % 运行检测器
    [bboxes,scores] = detect(detector,I);
    
    % 标记检测结果
    I = insertObjectAnnotation(I,'rectangle',bboxes,scores);
    figure
    imshow(I)
    

    在这里插入图片描述

    在测试集上评价检测器

    计算机视觉系统工具箱TM 提供物体检测器的常用的评价函数,如平均精度 (evaluateDetectionPrecision) 和对数平均错失率 (evaluateDetectionMissRate)。这里使用平均精度度量。平均精度给出了一个数值,结合了检测器进行正确分类的能力(精度)以及检测器找出所有相关物体的能力(召回)。

    检测器评价的第一步是收集检测结果,通过在测试集上运行检测器实现。为了避免长时间的等待。我们把评价结果直接从磁盘上读出。配置前一节中的 doTrainingAndEval 会执行评价的过程。

    if doTrainingAndEval
        % 在测试集上对每一张图片运行检测器,并且收集结果
        resultsStruct = struct([]);
        for i = 1:height(testData)
            
            % 读取图片
            I = imread(testData.imageFilename{i});
            
            % 运行检测器
            [bboxes, scores, labels] = detect(detector, I);
            
            % 收集结果
            resultsStruct(i).Boxes = bboxes;
            resultsStruct(i).Scores = scores;
            resultsStruct(i).Labels = labels;
        end
        
        % 转化为表格
        results = struct2table(resultsStruct);
    else
        % 从磁盘上直接读取
        results = data.results;
    end
    
    % 从测试集数据中读取期望的边界框
    expectedResults = testData(:, 2:end);
    
    % 用平均精度度量评价物体检测器
    [ap, recall, precision] = evaluateDetectionPrecision(results, expectedResults);
    

    精度/召回 (PR) 曲线突出显示了检测器在不同的召回率下的表现。理想状态下,在每一个召回水平上,精度都是 1。网络中额外的层会增加平均精度,但可能会需要更多的训练数据和训练时间。

    % 精度/召回曲线作图
    figure
    plot(recall,precision)
    xlabel('Recall')
    ylabel('Precision')
    grid on
    title(sprintf('Average Precision = %.2f', ap))
    

    在这里插入图片描述

    小结

    本例中给出了如何用深度学习训练一个汽车检测器。你可以用相似的过程训练交通信号灯、行人,或者其他物体。

    参考文献


    1. Ren, S., K. He, R. Gershick, and J. Sun. “Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks.” IEEE Transactions of Pattern Analysis and Machine Intelligence. Vol. 39, Issue 6, June 2017, pp. 1137-1149. ↩︎ ↩︎

    2. Girshick, R., J. Donahue, T. Darrell, and J. Malik. “Rich Feature Hierarchies for Accurate Object Detection and Semantic Segmentation.” Proceedings of the 2014 IEEE Conference on Computer Vision and Pattern Recognition. Columbus, OH, June 2014, pp. 580-587. ↩︎

    3. Girshick, R. “Fast R-CNN.” Proceedings of the 2015 IEEE International Conference on Computer Vision. Santiago, Chile, Dec. 2015, pp. 1440-1448. ↩︎

    4. Zitnick, C. L., and P. Dollar. “Edge Boxes: Locating Object Proposals from Edges.” European Conference on Computer Vision. Zurich, Switzerland, Sept. 2014, pp. 391-405. ↩︎

    5. Uijlings, J. R. R., K. E. A. van de Sande, T. Gevers, and A. W. M. Smeulders. “Selective Search for Object Recognition.” International Journal of Computer Vision. Vol. 104, Number 2, Sept. 2013, pp. 154-171. ↩︎

    展开全文
  • tensorflow是谷歌开源的深度学习框架,是进行深度学习的坚船利炮。此文基于“搜狗实验数据库”的海量新闻数据,全流程展示如何基于tensorflow采用CNN算法实现文章的分类。方便学习者全面地理解深度学习及NLP文本分析...

    一、项目简介

    tensorflow是谷歌开源的深度学习框架,是进行深度学习的坚船利炮。此文基于“搜狗实验数据库”的海量新闻数据,全流程展示如何基于tensorflow采用CNN算法实现文章的分类。方便学习者全面地理解深度学习及NLP文本分析的原理和实现步骤。
    github源码地址:https://github.com/Willsgao

    二、数据预处理

    预处理数据小结

    • 到该阶段已基本获取所需要的纯文本文件,走完了万里长征第一步
    • 文本预处理阶段主要是细节问题比较多包括以下方面:
    • 1、xml标签的处理
    • 2、文本的编码格式要注意
    • 3、os.walk和os.makedirs的使用

    三、数据清洗

    • 在数据预处理基础之上进一步对数据格式进行清洗
    • 包括删除特殊字符,去除标点和中文分词等工作
    • 需要自定义函数,并使用相关工具包如jieba等

    1、提取文本中的汉字数据

    • 此处可以直接通过提取文章中的汉字方式过滤数字和特殊符号
    • 去除中文停用词
    有些项目可能会专门去除数据中的url及无效数字和标点
    # 导入字符串匹配需要的工具包
    import re
    import jieba
    
    # 获取停用词列表
    with open('files/stopwords_1208.txt','r',
              encoding='utf-8-sig') as f:
       stopwords = f.readlines()
       
    # 判断词语是否为汉字
    def isHans(strs):
        pat = r'[\u4e00-\u9fa5]+'
        return bool(re.match(pat, strs))
    
    # 判断分词的基本特征
    def check(word):
        word = word.strip().replace(' ','')
        if isHans(word):
            return True
        else:
            return False
    
    # 综合处理
    def preprocessing(sens):
        res = []
        for word in sens:
            if check(word):
                res.append(word)
        return res
    

    2、获取训练集及测试集的分类数据

    • 为使项目结构更加清晰可以建立多层文件夹路径
    • 主要利用os.walk和os.makedirs等方法
    # 读取处理文件数据
    def handle_files(file_path,new_path):
        # 创建new_path存储处理好后的文件
        if not os.path.exists(new_path):
            os.makedirs(new_path)
        # 进入预处理后的主文件夹sougou_after
        for _,dirs,_ in os.walk(file_path):
            print(dirs)
            for d in dirs:
                d_path = file_path+'./'+d
                new_d_path = new_path+'./'+d
                # 在new_path文件夹中穿件各种分类文件夹
                if not os.path.exists(new_d_path):
                    os.makedirs(new_d_path)
                # 进入各种分类文件夹
                for _,_,files in os.walk(d_path):
                    for file in files:
                        d_p_file = d_path+'./'+file
                        n_d_file = new_d_path+'./'+file
                        # 打开分类文件夹中的文件
                        with open(d_p_file,'r',encoding='utf-8') as f1:
                            docs = f1.readlines()
                            # 创建一个空列表收集处理后的句子
                            res_docs = []
                            # 读取每一行的数据
                            for doc in docs:
                                # 将每行的数据进行分词
                                sens = jieba.cut(doc)
                                # 提取文本中的汉语数据
                                res = preprocessing(sens)
                                result = ' '.join(res)
                                result += '\n'
                                res_docs.append(result)
                            print(len(res_docs))
                            # 将处理好后的res_docs里的句子写入新的文件夹
                            with open(n_d_file,'a+',
                                      encoding='utf-8') as f2:
                                for docum in res_docs:
                                    f2.write(docum)
                                print('文件写入小结')
        print('文章处理完毕')    
    
    # 训练文本数据格式化
    # test_path = './sougoo'
    train_new_path = 'train_final'
    handle_files(path,train_new_path)
    
    # 测试文本数据格式化
    test_new_path = 'test_final'
    handle_files(test_path,test_new_path)
    

    3、列表化训练集和测试集数据

    # 定义测试数据矩阵函数
    def label_cont2list(data_path):
        # 定义根目录内容和标签列表
        dir_cont_list,dir_label_list = [],[]
        for _,dirs,_ in os.walk(data_path):
            for d in dirs:
                # 进入分类的子文件夹
                d_dir = data_path+'/'+d
                for _,_,files in os.walk(d_dir):
                    # 定义子文件夹内容列表
                    d_cont_list = []
                    for file in files:
                        file_name = d_dir+'/'+file
                        # 读取分类子文件夹内的文件
                        with open(file_name,encoding='utf-8') as f:
                            # 将文件内的每行数据作为元素存入列表
                            d_c_list = [k.strip() for k in f.readlines()]
                        d_cont_list.extend(d_c_list)
                # 分类文件夹级别内容列表合并
                dir_cont_list.extend(d_cont_list)
                # 将每个子文件夹的所有标签列表元素进行统一化后合并
                dir_label_list.extend(
                    [str(d) for _ in range(len(d_cont_list))])
        return dir_label_list,dir_cont_list
    
    # 获取训练数据集的标签列表和内容列表
    train_path = 'train_final'
    train_label_list,train_cont_list = label_cont2list(train_path)
    
    # 获取测试集的标签列表和内容列表
    test_path = 'test_final'
    test_label_list,test_cont_list = label_cont2list(test_path)
    

    4、生成词汇表

    • 收集训练集文本内容列表词作为词汇表
    # 导入词汇收集工具包
    from collections import Counter
    
    # 定义获取词汇表的函数
    def getVocabList(content_list, vocab_size):
        str_allContent = ''.join(content_list)
        counter = Counter(str_allContent)
        vocab_list =[k[0] for k in counter.most_common(vocab_size)]
        return vocab_list
    
    # 生成词汇表文件
    def generateVocabList(content_list, vocab_size):
        vocab_list = getVocabList(content_list, vocab_size)
        print(vocab_list[:10])
        with open('files/vocab_list.txt', 'w+', encoding='utf-8') as f:
            for vocab in vocab_list:
                f.write(vocab+'\n')
            print('词汇表创建完成')
    
    generateVocabList(train_cont_list, 5000)
    

    5、词汇表词向量化

    • 利用词汇表文件将数据进行词向量化
    # 读取词汇表文件数据,存入列表中
    with open('files/vocab_list.txt',encoding='utf-8') as f:
        vocab_list = [k.strip() for k in f.readlines()]
    
    # 将词汇列表中的数据转化为键为数据,值为序号的字词汇典
    word2id_dict = dict([(b,a) for a,b in enumerate(vocab_list)])
    
    # 定义词向量化函数,将数据转化为词向量
    def list2vector(word2id_dict,train_cont_list):
        # 定义一个词汇字典与文本内容的映射关系
        cont2id_list = lambda content:[
            word2id_dict[
                word] for word in content if word in word2id_dict]
        # 将训练集数据映射为词汇字典对应的词向量
        train_idlist_list = [cont2id_list(
            content) for content in train_cont_list]
        return train_idlist_list
    

    四、模型的建立

    • 建立CNN模型进行数据训练和预测

    1、导入数据包

    # 导入相关数据包
    import tensorflow as tf 
    import tensorflow.contrib.keras as kr 
    from sklearn.preprocessing import LabelEncoder as spl
    

    2、固定参数初始化

    # 固定参数初始化
    vocab_size = 5000 # 词汇表的大小
    seq_length = 600 # 序列长度
    embedding_dim = 64 # 词向量维度
    num_classes = 11 # 文章的类别
    num_filters = 256 # 卷积核数目
    kernel_size = 5 # 卷积核尺度
    hidden_dim = 128 # 全连接层神经元数量
    drop_keep_prob = 0.5 # dropout保留比例
    learning_rate = 0.001 # 学习率
    batch_size = 64 # 每批次训练样本大小
    

    3、样本集合格式化

    # 获取训练样本映射的词向量矩阵
    train_idlist_list = list2vector(word2id_dict,train_cont_list)
    
    # 将训练样本的文本矩阵转化为等长度的ndarray类型
    train_X = kr.preprocessing.sequence.pad_sequences(
        train_idlist_list, seq_length)
    
    # 将训练样本的标签矩阵进行格式化
    labelEncoder = spl()
    train_y = labelEncoder.fit_transform(train_label_list)
    # 将训练集标签矩阵转化为独热编码格式
    train_Y = kr.utils.to_categorical(train_y, num_classes)
    
    # 清除默认图形堆栈并重置全局默认图形
    tf.reset_default_graph()
    # 利用占位符创建索引概率分布矩阵
    X_holder = tf.placeholder(tf.int32, [None, seq_length])
    Y_holder = tf.placeholder(tf.float32, [None, num_classes])
    
    # 获取测试样本映射的词向量矩阵
    test_idlist_list = list2vector(
        word2id_dict,test_cont_list)
    # 将测试样本的文本矩阵转化为等长度的ndarray类型
    test_X = kr.preprocessing.sequence.pad_sequences(
        test_idlist_list,seq_length)
    # 将测试样本的标签矩阵进行格式化
    test_y = labelEncoder.fit_transform(test_label_list)
    # 将测试集标签矩阵转化为独热编码格式
    test_Y = kr.utils.to_categorical(test_y, num_classes)
    

    4、CNN模型训练流程

    # CNN前向传播流程
    # 创建词向量的变量
    embedding = tf.get_variable('embedding',[vocab_size, embedding_dim])
    # 选取词向量索引矩阵对应的元素,作为输入层数据
    embedding_inputs = tf.nn.embedding_lookup(embedding,X_holder)
    # 创建一维卷积函数
    conv = tf.layers.conv1d(embedding_inputs, num_filters, kernel_size)
    # 利用横向局部最大值进行池化
    max_pooling = tf.reduce_max(conv, reduction_indices=[1])
    # 创建全连接层
    full_connect = tf.layers.dense(max_pooling, hidden_dim)
    # 降采样,防止神经网络过拟合,保留75%神经元参与训练
    full_connect_drop = tf.contrib.layers.dropout(full_connect,keep_prob=0.75)
    # 利用relu函数进行全连接层激活处理
    full_connect_activate = tf.nn.relu(full_connect_drop)
    # 将输出层前全连接层的输出进行训练,得出预测得分
    softmax_pre = tf.layers.dense(full_connect_activate, num_classes)
    # 将预测得分进行softmax激活处理,得到各种类别的预测概率
    pred_Y = tf.nn.softmax(softmax_pre)
    
    # CNN后向传播流程
    # 计算输出标签与真实标签的交叉熵
    cross_entropy = tf.nn.softmax_cross_entropy_with_logits_v2(
        labels=Y_holder, logits=softmax_pre)
    # 计算损失(交叉熵均值)误差均值
    loss = tf.reduce_mean(cross_entropy)
    # 利用Adam算法创建自动优化器,学习率为0.001
    optimizer = tf.train.AdamOptimizer(learning_rate)
    # 对损失函数进行全局优化
    train = optimizer.minimize(loss)
    # 获取真实标签与预测标签的元素布尔型矩阵
    isCorrect = tf.equal(tf.argmax(Y_holder, 1), tf.argmax(pred_Y, 1))
    # 将布尔型矩阵转化为0-1矩阵,并浮点化,并求预测准确率
    accuracy = tf.reduce_mean(tf.cast(isCorrect, tf.float32))
    

    参考网址:https://blog.csdn.net/sadfassd/article/details/80568321
    https://blog.csdn.net/q383700092/article/details/79159776
    https://blog.csdn.net/u011439796/article/details/77692621
    https://blog.csdn.net/heyc861221/article/details/80128748

    展开全文
  • # 定义批量预测函数,将结果转化为ndarray类型 def predictAll(test_X, batch_size=100): pred_val_list = [] for i in range(0,len(test_X),batch_size): select_X = test_X[i:i+batch_size] ...
  • 官方给出的Faster R-CNN的代码是caffe框架下的,我对caffe不是很了解,一直用的是tensorflow环境,所以去网上找了一下用tensorflow实现的Faster R-CNN。找到了一篇博客https://www.cnblogs.com/toone/p/8433581.html...

    2014年是目标检测算法的里程碑,因为那一年R-CNN横空出世,将深度学习-卷积神经网络用在了目标检测领域,标志着目标检测进入了一个新的高度。目前tensorflow深度学习框架比较火且容易上手,所以想基于tensorflow来看看RCNN到底是怎么实现图片目标检测的。本人洒哥比较穷,电脑还是2013年买的,所以GPU很菜,在深度学习领域没法用GPU来train和Inference,github上的RCNN代码很多都默认是GPU运行,我这里记录一下如何在CPU下运行RCNN代码的demo。

    因为RCNN出来之后,Fast RCNN,Faster RCNN相继问世,肯定是越来越牛皮,老的方法将会被摒弃,所以我就直接拿Faster R-CNN来做演示了,但是想提醒一下:R-CNN是核心,后面的都是基于此思想来改进的。

    ------本文章只是实现了基于深度学习的图片检测的Inference过程,实现了图片中20类目标检测功能,并没有Train过程,只需要下载源码和已经训练好的模型即可,不需要数据集。后续洒哥会写如何基于Faster R-CNN训练自己的数据集。

    1.本机环境

    ubuntu16.04,CPU,tensorflow==1.15.0(不是GPU版本的TF,如下),python3,opencv-python3,cython==0.25.2,easydict

    在这里插入图片描述

    如果后面编译出现了找不到相应模块,大家pip安装一下就可以了,如:
    sudo pip3 install cython==0.25.2
    sudo pip3 install easydict

    2.下载Faster R-CNN代码

    git clone https://github.com/endernewton/tf-faster-rcnn.git

    3.修改CPU运行配置

    lib/setup.py文件中设置CPU和GPU的参数,如图所示:

    在这里插入图片描述

    因为代码默认是在GPU下运行,如果不设置成CPU模式,后面编译和运行代码时会报错。(要在GPU下运行就很简单了,只需要根据自己GPU的型号来设置-arch一个参数就可了)

    1. 修改config.py代码:将USE_GPU_NMS 由原来的True改为False就可以:

    在这里插入图片描述

    2. 修改 lib/model/nms_wrapper.py文件

    按照图中所示,将代码注释,直接禁用掉GPU模式

    在这里插入图片描述

    2. 修改 lib/setup.py文件

    一种需要修改三处地方:
    在这里插入图片描述在这里插入图片描述在这里插入图片描述

    4. 安装和链接cython 模块

    首先安装cython模块:sudo pip3 install cython==0.25.2

    然后在lib目录下打开终端,输入

    make clean

    make

    至此,代码要在CPU下运行的设置已完成。

    5.安装 Python COCO API

    代码中要用到COCO数据库,也可以手动下载,然后放在/data下即可:

    cd data

    git clone https://github.com/pdollar/coco.git

    cd coco/PythonAPI

    make

    6.下载预训练好的Model

    1. 下载已经训练好的模型

    要用到的模型 voc_0712_80k-110k.tgz ,该模型可实现20类目标检测,如dog,car,person等。下载见百度网盘: https://pan.baidu.com/share/init?surl=ClcNOWiqOm6nyAdfD3RSsQ ,提取码: 6dz8。下载之后放到 data文件夹中,使用以下命令解压:

    tar xvf voc_0712_80k-110k.tgz

    解压得到voc_2007_trainval+voc_2012_trainval文件夹,其中包含四个模型文件:

    res101_faster_rcnn_iter_110000.ckpt.data-00000-of-00001

    res101_faster_rcnn_iter_110000.ckpt.index

    res101_faster_rcnn_iter_110000.ckpt.meta

    res101_faster_rcnn_iter_110000.pkl

    2. 建立预训练模型的软连接

    在tf-faster-rcnn主目录下:

    NET=res101

    TRAIN_IMDB=voc_2007_trainval+voc_2012_trainval

    mkdir -p output/${NET}/${TRAIN_IMDB}

    cd output/${NET}/${TRAIN_IMDB}

    ln -s ../../../data/voc_2007_trainval+voc_2012_trainval ./default

    建立了模型软链接之后,双击default之后,会出现以下四个文件,说明就成功哦,后面运行demo.py时就会找到model来做推理,不然会提示你找不到:xx.cpkt的

    7. CPU下运行demo

    python3 ../tools/demo.py

    运行结果为:

    在这里插入图片描述

    这个demo里面自带5张照片:

    运行后的预测结果为12张图像:

    其实想运行demo还是很简单的:大家先去尝试运行下代码,先比较直观的看到图片检测结果,当十几张图片突然跳出来的时候,心里还是慢开心的,后面再怀着好奇心看看代码是如何实现把图片中的目标给框出来的~,这才是关键

    疑问

    1. 为啥一张图片中有多个目标时,一张图片只检测出来一种,然后同样的图片再检测出来另外一种目标?
    2. 检测出来的结果在哪,如何取出来?最终还是要把(x,y,w,h)发送给下面的决策算法的。
    3. 5张图片检测出来需要30多s,看来一张image的inference大概6s,还是很慢的,如何提高预测速度?

    后续计划:

    1. 下一步加入公开的20类目标训练集(如PASCAL VOC2007),训练模型,然后用简单训练出的模型进行检测;
    2. 制作自己的数据集,如panda,格式为VOC2007,修改源码,执行Train,Inference,Test等过程,实现自定义目标检测;
    3. 实现视频流目标检测。

    最后:问题懊恼时常六问,之一乃问博客,当问题迎刃而解之时,一念头萦绕脑海,何不记录以助后来的人呢,故写下了洒哥的第一篇CSDN技术博客,特此纪念。有一些内容也是参考和借鉴一些前人的相关技术博客,在此表示感谢。君不见黄河之水天上来,奔流到海不复回,同时也加了一丢丢自己的理解和思考,前见古人后见来者,未来还需加油!

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 11,888
精华内容 4,755
关键字:

cnn深度学习