官方服务微信:dat818 购买与出租对接

深入理解与实现卷积神经网络CNN:从理论到实践,手写体识别的卓越表现

3万

主题

2

回帖

10万

积分

管理员

积分
105383
发表于 2024-12-25 22:36:42 | 显示全部楼层 |阅读模式
    //p/.html

    前言:

    从理解卷积神经网络到实现它花了一个月的时间。还有一些事情我还没有彻底理解。 CNN还是很难。光看一些博客或者一两篇论文是无法理解的。主要还是靠自己研究,看最后推荐的参考文献。目前实现的CNN在MINIT数据集上运行良好,但仍然存在一些bug。因为最近比较忙,所以先总结一下之前做的事情,后面继续优化。

    卷积神经网络CNN是Deep的重要算法,在很多应用中都表现出了优异的效果。 [1]比较了多种算法对文档字符识别的效果,得出结论:CNN优于所有其他算法。 CNN 在手写识别方面取得了最好的成绩。 [2]将CNN应用于基于人脸的性别识别,效果也非常好。前段时间,我用BP神经网络来识别手机拍摄的照片中的数字。效果还是不错的,接近98%。但是它在汉字识别上表现不佳,所以我想尝试一下卷积神经网络。

    1.CNN整体网络结构

    卷积神经网络是BP神经网络的改进。与BP类似,它使用前向传播来计算输出值,并使用反向传播来调整权重和偏差。 CNN与标准BP最大的区别在于:CNN中相邻层之间的神经单元不是全连接的,而是部分连接的,即某个神经单元的感知区域来自于一些上层神经单元,而不是像BP一样连接到所有神经单元。 CNN 具有三个重要的意识形态结构:

    局部区域感知可以发现数据的一些局部特征,比如图片上的角点或者弧线。这些基本特征构成了动物视觉的基础[3];在BP中,所有像素都是一堆相互影响的混沌点。他们之间的关系尚未被探讨。

    CNN 中的每一层都由多个映射组成。每个映射由多个神经单元组成。同一映射中的所有神经单元共享一个卷积核(即权重)。卷积核往往代表一个特征,比如某个卷积和代表一条弧。然后将卷积核滚动到整个图片上。卷积值较大的区域很可能是圆弧。注意,卷积核实际上就是权重。我们不需要单独计算卷积,而是需要一个固定大小的权重矩阵来匹配在图像上。这个操作类似于卷积,所以我们称其为卷积神经网络。其实,上面的BP也可以看成是一种特殊的卷积神经网络,只不过卷积核是某一层的所有权值,即感知区域是整幅图像。权重共享策略减少了需要训练的参数,使得训练出来的模型更加通用中文。

    采样的目的主要是为了混淆特征的具体位置,因为找到一个特征之后,它的具体位置就不再重要了。我们只需要该特征与其他特征的相对位置,例如“8”。当我们得到上面的一个“o”时,我们不需要知道它在哪里,至于图像的具体位置,我们只需要知道它下面还有一个“o”,就可以知道它是一个‘8’,因为图片中的“8”无论在图片的左边还是右边,都不影响我们对它的识别。混淆特定位置的策略可以识别变形和扭曲的图像。

    CNN的这三个特点就是对输入数据在空间(主要针对图像数据)和时间(主要针对时间序列数据,参考TDNN)的扭曲具有高度鲁棒性。 CNN一般采用卷积层和采样层交替设置,即一个卷积层后面跟着一个采样层,一个采样层后面跟着一个卷积层……这样,卷积层提取特征,然后将它们组合起来形成更抽象的特征。最终形成图片对象的描述性特征。 CNN后面还可以接全连接层,这一点和BP一样。这是卷积神经网络的示例:

    图1

    卷积神经网络的基本思想就是这样,但是具体实现有多个版本。我提到了 Deep 工具箱。这里实现的 CNN 与其他实现的最大区别在于采样层没有权重和偏差,只有卷积层。进行抽样过程。该工具箱的测试数据集是每张图像大小为28*28。它实现了以下 CNN:

    图2

    2、网络初始化:

    CNN的初始化主要是初始化卷积核(权值)以及卷积层和输出层的偏置。卷积核和权重随机初始化,偏置初始化为全0。

    3、前向传输计算:

    前向计算中,输入层、卷积层、采样层、输出层的计算方式不同。

    3.1 输入层:

    输入层没有输入值,只有一个输出向量。这个向量的大小就是图像的大小,是一个28*28的矩阵;

    3.2 卷积层:

    卷积层的输入要么来自输入层,要么来自采样层,如上图红色部分所示。卷积层的每个图都有一个相同大小的卷积核,其中包含一个5*5的卷积核。下面是一个例子。为了简单起见,卷积核大小为2*2,上一层的特征图大小为4*4。利用这个卷积对图像进行滚动,得到一张一张的(4-2+1)*(4-2+1)=3*3的特征图,卷积核一次移动一步,所以。实现中,卷积层的一个map与上层的所有map关联起来,比如上图中的S2和C3,即C3总共有6*12个卷积核,每个特征图卷积层是不同的卷积核对上一层的所有图进行卷积,累加对应的元素,加上偏移量,然后得到。还需要注意的是,卷积层中图的数量是在网络初始化时指定的,卷积层中图的大小由卷积核和上一层输入图的大小决定。假设上一层的map大小为n*n,卷积核大小为k*k,那么本层的map大小为(n-k+1)*(n-k+1),比如24 *上图中24地图尺寸。 24=(28-5+1)。斯坦福的深度学习教程更详细地介绍了卷积特征提取的计算过程。

    图3

    3.3 采样层(,):

    采样层是对上层地图的采样过程。这里的采样方法是对上层地图的相邻小区域进行聚合统计。区域大小为scale*scale。有些实现取小区域的最大值,而里面的实现则取2*2小区域的平均值。注意,卷积的计算窗口重叠,但使用的计算窗口不重叠。计算采样也是使用卷积实现(conv2(A,K,'valid')),卷积核为 2*2 ,每个元素为 1/4 ,去除计算出的卷积结果的重叠部分,即是:

    图4

    4.倒档调节重量

    反向传输过程是CNN中最复杂的部分。虽然从宏观上看,其基本思想与BP相同,都是通过最小化残差来调整权值和偏置,但CNN的网络结构并不像BP那么简单。 的结构,尤其是采样层的残差计算,我在这里详细讲解一下。

    4.1 输出层残差

    与BP一样,CNN输出层残差的计算方式与中间层残差的计算方式不同。输出层的残差是输出值与类标准值之间的误差值,而中间层的残差是由下一层的残差推导出来的。差异的加权和。输出层的残差计算如下:

    公式来源

    这个公式没有任何解释。你可以查看斯坦福深度学习教程《反向传播算法》的公式出处和解释。

    4.2 下一层是采样层卷积层的残差()

    当卷积层L的下一层(L+1)是采样层时,假设我们已经计算了采样层的残差,现在计算卷积层的残差。从最上面的网络结构图中我们知道,采样层的map大小(L+1)是卷积层L的1/(scale*scale)。其中,scale为2,但是中的map数量两层是相同的。 ,卷积层L的某个map中的4个单元与L+1层配对 根据map的某个单元的关联,采样层的残差与一个scale*scale全1矩阵的乘积可以进行扩展,使得采样层残差的维度与上一层输出图的维度一致。 ,代码如下,其中d代表残差,a代表输出值:

    净.{l}.d{j} = 净.{l}.a{j} .* (1 - 净.{l}.a{j}) .* (净.{l + 1}.d{ j}, [net.{l + 1}.scale net.{l + 1}.scale 1])

    扩展过程:

    图5

    使用卷积计算卷积层的残差:

    图6

    4.3 下一层是卷积层采样层的残差()

    当某个采样层L的下一层是卷积层(L+1)时,假设我们已经计算了L+1层的残差,现在计算L层的残差。采样层到卷积层直接连接有权值和偏置参数,所以不像卷积层到采样层那么简单。现在假设L层的第j个图Mj与L+1层的M2j相关联。根据BP原理,L层的残差Dj是L+1层的残差D2j的加权和。但这里的困难在于,我们很难弄清楚M2j的哪些单位通过哪些权重与Mj的哪些单位相关联。卷积(稍微变形)就巧妙地解决了这个问题。代码是:

    净.{l}.d{j} = 净.{l}.a{j} .* (1 - 净.{l}.a{j}) .* (净.{l + 1}.d{ j}, [net.{l + 1}.scale net.{l + 1}.scale 1])

    表示矩阵旋转180度(可以通过行对称交换和列对称交换来完成)。这里为什么要旋转卷积核呢?答案是:通过这种旋转,正好捕获了“全”模式下的卷积。前向传输计算上层图单元和卷积和与当前层图之间的关系。需要注意的是,内置函数 convn 在计算卷积之前会旋转一次卷积核,所以我们之前所有的卷积计算都是旋转卷积核:

    一个=

    11

    11

    11

    k =

    23

    56

    89

    >> convn(a,k,'完整')

    答案=

    3653

    convn在计算前还会将要卷积的矩阵展开0。如果卷积核为k*k,要卷积的矩阵为n*n,则需要展开为(n+2(k-1))*(n+2(k-1)),计算过程上述所有 convn(a,k,'full') 如下:

    图7

    事实上,convn是否内部轮换对网络训练没有影响。只要内部结构一致(即,它们要么旋转,要么不旋转),我所有的卷积实现都不会旋转卷积核。如果在CNN计算之前将卷积核旋转180度,然后在Convn内部旋转180度,则相当于卷积核没有变化。

    为了清楚地描述卷积核旋转180和卷积层残差的卷积相关的权重和单位,也正是前向计算相关的权重和单位,我们选择稍大的卷积核,即假设卷积层使用3*3的卷积核,上采样层的输出图的大小为5*5。那么从采样层向前传输到卷积层的过程如下:

    图8

    这里我们使用自己实现的convn(即卷积核内部不会进行旋转),并假设上述矩阵A和B的下标都是从1开始的,则有:

    B11 = A11*K11 + A12*K12 + A13*K13 + A21*K21 + A22*K22 + A23*K23 + A31*K31 + A32*K32 + A33*K33

    B12 = A12*K11 + A13*K12 + A14*K13 + A22*K21 + A23*K22 + A24*K23 + A32*K31 + A33*K32 + A34*K33

    B13 = A13*K11 + A14*K12 + A15*K13 + A23*K21 + A24*K22 + A25*K23 + A33*K31 + A34*K32 + A35*K33

    B21 = A21*K11 + A22*K12 + A23*K13 + A31*K21 + A32*K22 + A33*K23 + A41*K31 + A42*K32 + A43*K33

    B22 = A22*K11 + A23*K12 + A24*K13 + A32*K21 + A33*K22 + A34*K23 + A42*K31 + A43*K32 + A44*K33

    B23 = A23*K11 + A24*K12 + A25*K13 + A33*K21 + A34*K22 + A35*K23 + A43*K31 + A44*K32 + A45*K33

    B31 = A31*K11 + A32*K12 + A33*K13 + A41*K21 + A42*K22 + A43*K23 + A51*K31 + A52*K32 + A53*K33

    B32 = A32*K11 + A33*K12 + A34*K13 + A42*K21 + A43*K22 + A44*K23 + A52*K31 + A53*K32 + A54*K33

    B33 = A33*K11 + A34*K12 + A35*K13 + A43*K21 + A44*K22 + A45*K23 + A53*K31 + A54*K32 + A55*K33

    我们可以得到B矩阵的各个单元与A矩阵的哪些卷积核单元和哪些单元之间的关系:

    A11 [K11] [B11]

    A12 [K12, K11] [B12, B11]

    A13 [K13、K12、K11] [B12、B13、B11]

    A14 [K13, K12] [B12, B13]

    A15 [K13] [B13]

    A21 [K21,K11] [B21,B11]

    A22 [K22、K21、K12、K11] [B12、B22、B21、B11]

    A23 [K23、K22、K21、K13、K12、K11] [B23、B22、B21、B12、B13、B11]

    A24 [K23、K22、K13、K12] [B23、B12、B13、B22]

    A25 [K23,K13] [B23,B13]

    A31 [K31、K21、K11] [B31、B21、B11]

    A32 [K32、K31、K22、K21、K12、K11] [B31、B32、B22、B12、B21、B11]

    A33 [K33、K32、K31、K23、K22、K21、K13、K12、K11] [B23、B22、B21、B31、B12、B13、B11、B33、B32]

    A34 [K33、K32、K23、K22、K13、K12] [B23、B22、B32、B33、B12、B13]

    A35 [K33、K23、K13] [B23、B13、B33]

    A41 [K31、K21] [B31、B21]

    A42 [K32、K31、K22、K21] [B32、B22、B21、B31]

    A43 [K33、K32、K31、K23、K22、K21] [B31、B23、B22、B32、B33、B21]

    A44 [K33、K32、K23、K22] [B23、B22、B32、B33]

    A45 [K33、K23] [B23、B33]

    A51[K31][B31]

    A52 [K32,K31] [B31,B32]

    A53 [K33、K32、K31] [B31、B32、B33]

    A54 [K33、K32] [B32、B33]

    A55 [K33] [B33]

    然后使用convn(卷积核会在内部旋转180度)执行convn(B,K,'full')。结合图7,看红色部分,去掉0,A11=B'33*K'33 =B11*K11。发现A11与K11和B11完全相关是否正确?再看一下 A24=B'34*K'21 +B'35*K'22+B'44*K'31+B'45*K'32=B12*K23+B13*K22+B22*K13+ B23*K12,找到参与计算A24的卷积核单元 B矩阵单元正是前向计算关联的单元,因此我们可以得到A24的残差采样层通过旋转卷积核然后进行卷积。

    计算残差后,唯一剩下的就是更新权重和偏差。这个和BP是一样的,就不详细说了。如果您有任何疑问,请随时沟通。

    5. 代码实现

    详细代码这里不再贴了,我还是放在这里。欢迎参考和指正。我再次重新发明轮子,没有使用任何第三方库类。这是调用代码:

    神经网络(){

    //创建卷积神经网络

    =();

    .(层.((28, 28)));

    .(层.(6,(5, 5)));

    .(层.((2, 2)));

    .(层.(12,(5, 5)));

    .(层.((2, 2)));

    .(层.(10));

    CNN CNN =(, 50);

    //导入数据集

    ="/火车。";

    = .load(,",", 784);

    cnn.train(, 3);//

    =“型号/n”;

    CNN.();

    。清除();

    =空;

    //预测

    // CNN cnn = CNN.();

    = .load("/test.",",", -1);

    cnn.(,"/测试。");

    6. 参考文献

    [1].颜乐昆. -基于.

    [2].刘山松. :A。

    [3] DH Hubel 和 TN,“,,以及在猫的,”

    [4] .

    [5] 杰克.关于 的注释。

    [6] C++实现详细介绍。

    [7]
您需要登录后才可以回帖 登录 | 立即注册

Archiver|手机版|小黑屋|关于我们

Copyright © 2001-2025, Tencent Cloud.    Powered by Discuz! X3.5    京ICP备20013102号-30

违法和不良信息举报电话:86-13718795856 举报邮箱:hwtx2020@163.com

GMT+8, 2025-5-14 15:16 , Processed in 0.065534 second(s), 17 queries .