【深度学习】卷积神经网络CNN

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Hemk340200600/article/details/86141314

1.卷积神经网络

1.1Convolution 卷积

  卷积核里面的数字是被学出来的。卷积核的大小是认为规定的,以 3 × 3 3\times3 的卷积核为例,
[ 1 1 1 1 1 1 1 1 1 ] , [ 1 1 1 1 1 1 1 1 1 ] , . . . \begin{bmatrix} 1 & -1 & -1 \\ -1 & 1 & -1 \\ -1 & -1 & 1 \end{bmatrix}, \begin{bmatrix} -1 & 1 & -1 \\ -1 & 1 & -1 \\ -1 & 1 & -1 \end{bmatrix},...
  卷积步骤:对一张拥有 28 × 28 28\times28 像素的图片来说,首先将卷积核放在左上角,跟对应像素位置的值做內积得到一个值。然后向右滑动1个stride(滑动的步长称为stride),继续计算內积。当一行计算完之后,卷积核移动到下一行(移动stride步)的行首,重复以上步骤。最后可以将整张图片的像素用卷积得到的值来表示。
  当我们使用n个不同的卷积核时,我们可以得到n组新的值,这时得到的东西称之为Feature Map。我们可以把它想象为一组新的图片,只不过比原来的图片要小,并且原始图片上被卷积核卷过的区域都用n个新的特征值来表示。
  可以这样来考虑卷积后的到的特征,对于图片 [ 1 0 0 0 0 1 0 0 0 0 1 0 1 0 1 1 ] \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 1 & 0 & 1 & 1\end{bmatrix} ,我们使用卷积核 [ 1 1 1 1 1 1 1 1 1 ] \begin{bmatrix} 1 & -1 & -1 \\ -1 & 1 & -1 \\ -1 & -1 & 1 \end{bmatrix} 对其进行卷积,对于左上角 3 × 3 3\times3 的区域,其计算公式为 1 × 1 1 × 0 1 × 0 1 × 0 + 1 × 1 1 × 0 1 × 0 1 × 0 + 1 × 1 = 3 1\times1-1\times0-1\times0-1\times0+1\times1-1\times0-1\times0-1\times0+1\times1=3 。可以发现3这个输出,其实是以[1,0,0,0,1,0,0,0,1]为输入,[1,-1,-1,-1,1,-1,-1,-1,1]权重得到的输出,如果看成是神经网络的形式,其实相当于以卷积区域的值为输入,卷积核作为权重,得到一个输出3。因此卷积后得到的feature map其实是由一个全连接神经网络得到的结果。而由于卷积核是固定不变的,在卷积过程中,我们使用到的卷积也是不变的,因此对于这个全连接神经网络,得到的每个输出,它们的输入对应的权重都是不变,即 权重共享,这使得需要学习的参数量大大减少。

1.2 Max Pooling最大池化

  将卷积得到的feature矩阵,比如我们卷积后得到 [ 3 1 3 1 3 1 0 3 3 3 0 1 3 2 2 1 ] \begin{bmatrix} 3 & -1 & -3 & -1 \\ -3 & 1 & 0 & -3 \\ -3 & -3 & 0 & 1 \\ 3 & -2 & -2 & -1\end{bmatrix} ,对于Max Pooling来说,它会将这个矩阵分成四块,每一块取其中最大值作为代表值,得到 [ 3 0 3 1 ] \begin{bmatrix} 3 & 0 \\ 3 & 1 \end{bmatrix} ,与Max Pooling相对应的,还有Average Pooling平均池化。每次不取最大的,而是取其平均值作为代表。进行池化操作后,我们得到一张新的图片,可以对其重复进行卷积,池化操作,直到其变成我们想要的大小为止。

1.3 Flatten

  将上面步骤最后得到的结果拉直,用于后续的全连接层的输入,最终得到整个模型的结果,比如判断一张图片是猫还是狗,到此为止,整个CNN的部分就介绍完了。

CNN图解

2.理解深度学习

  理论上我们只需要一层hidden层就可以学到任何的非线性函数,为什么需要多层呢?并且实际上也很有用?
在这里插入图片描述

  从上面这组实验数据不难发现,当一个参数数量差不多的“高瘦”的模型和“矮胖”的模型相比,“高瘦”模型,也就是深度学习模型的效果更好,并且在只有一层hidden layer的情况下增加神经元数量到16k的数目也不能获得比深度学习更好的效果。
  在软件体系架构里面,有一个很重要的步骤就是模块化。比如,当我们需要对一组数据做一次排序,我们通常是将排序封装成一个方法,这样下次需要排序时就只要调用这个方法,而不需要再重新写一次排序。
在这里插入图片描述

  深度学习其实也是在做类似模块化的步骤。对于一张图片,我们要将其判断出是长发男生,长发女生,短发男生,短发女生四个类型,如果我们直接训练一层hidden layer,恰好其中长发男生的样本很少,那最终学出来的模型不会很好。而如果我们先判断图片中是男生还是女生,是长发还是短发,再将这两个结果组合,最终得到比较好的效果。因为长发和短发的样本是比较均匀的,男生和女生的样本也是比较均匀的,它可以学到一个比较好的基本分类器来判断这两种情况,再由后面的hidden layer进行组合。而在深度学习中,前面的hidden layer就是较为底层的模块,后面的hidden layer使用前一个hidden layer作为模块来构建分类器。


更多精彩内容