从DeepLearnToolbox-master看CNN

卷积神经网络

揭开卷积神经网络神秘的面纱,发现CNN也不过如此,就像对普通NN一样,第一步了解网络结构,第二步了解节点计算方法,第三步反向调节误差。就可以完全认识这个模型了。从网上看的大部分资料感觉很少有能够说清楚的,CNN确实原本也是一个比较难说明白的模型,所以从大牛的代码来看CNN会更清晰。

一、 CNN结构

                          图一

这个网络结构举了这样一个列子,输入的map是一个28*28的矩阵,输入层有1map,到了第一层的时候可以设定有多少个map,图中第一层有6map。从输入层到第一层的每一个map是通过一种类似卷积的运算求出来的(这种运算在下面小节卷积神经网络节点的计算方法会介绍),因而第一层一般就叫做C1。在第一层到第二层的时候是通过一种可以称为采样的运算得来的(这种运算方式也在后面讲述),故第二层一般称为s2。如上面图所示C1层有6map,而后面的s2层也会有6map,并且C1层和s1层的map是一一对应的关系,也就是s1的每个map只与C1层的一个map有关。然后从s2层到第三层又是通过类似卷积的运算得出来的,所以第三层就可以称为C3层。就这样网络一遍一遍的重复卷积运算和采样运算前向的发展。在上面的例子中看到最后一层变成了124*4map。在最后一层这124*4map到输出层还有一个权值。因为做的是模式识别,输出层每个节点输出的结果就是一个数值了而不是矩阵。

二、CNN每层计算方式

1、卷积运算

前面说到输入层到C1层和S2层到C3层都用到了类似于卷积的运算。这种运算方式如下


                                                                               图二

这个地方的卷积核就类似于普通NN中的权值,而上一层的一个输出map Mj就是普通NN中的第j个节点的输出。看图一中举的例子,因为输入层只有一个map,而C1层有6map,所以就要有1*6个卷积核了,而在s2层到C3层,s26mapC312map,所以这两层中间就要有6*12个卷积核。而C3层中第jmap到底应该怎么算的,就是s2中的每一个map与对应的卷积核做卷积运算,然后累加求和,再加上偏置,在带入激励函数sigmord函数得出来的。下面看一下工具箱的代码是不是这样子


                                                                                              图三

因为卷积运算和采样运算方式不同,所以第一行首先判断l层是卷积层还是采样层,如果是卷积层的话就计算lnet.layer{l}.outputmapsmap的值,所以就有了第二行代码(不算注释)的for循环,在第四行到第六行就是通过for循环计算前一层(即l-1层)inputmaps个输入map——net.Layers{l-1}.a{i}与对应的卷积核net.Layers{l}.k{i}{j}做卷积运算,然后累加求和。在第七行的部分,将累加求和所得的z与对应的偏置net.Layers{l}.b{j}相加然后带入sigmord函数,结果付给l层的map——net.Layers{l}.a{i}有点说一下,在第五行中出现的convn函数就是卷积函数,做的运算就是图二中所示的运算。

2、重采样层的采样

重采样层的计算方式非常简单,通过看图三中倒数第四行、倒数第三行的代码可以看到,如果要求采样曾第jmap,只需要拿着前一层的map——net.Layers{l-1}.a{i}与一个卷积核做卷积运算,这个卷积核是ones(net.layers{l}.scale)/( net.layers{l}.scale),在图一举的例子中采样层scale都为2,那么这个矩阵就是一个[1,1;1,1]/4=[1/4,1/4;1/4,1/4]这样的一个矩阵了。net.Layers{l-1}.a{i}ones(net.layers{l}.scale)/( net.layers{l}.scale)做完卷积运算后赋给z,再把z中的一部分提取出来,通过z(1 : net.layers{l}.scale : end, 1 :net.layers{l}.scale : end, :)可以看出把1 : net.layers{l}.scale: end的行和列提取了出来。这样整个一个过程可以通过图四来表示:


                               图四

在这里就知道了网络每层中的map到底应该怎样计算了。但是在第一部分CNN结构中说到,最后一层是有124*4map,而我们最后的输出是一个行向量,比如要识别0-9十个手写字符,输出的结果应该是一个10维的向量,从124*4map怎么到一个10维的向量呢?看下面的代码:


在最后一层有12map,所以numel(net.layers{n}.a)12net.fv = [net.fv; X];

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值