机器学习:卷积神经网络

和全连接神经网络的主要差别

全连接神经网络:
  每个神经元的输入数据,都使用了上一层的所有神经元的输出数据,每个神经元的输出数据,都被作为下一层的所有神经元的输入数据,这容易导致参数数量膨胀、过拟合、容易陷入局部最优,尤其用于图像识别时,因为如果把每个像素当成一个特征,则会有大量的特征值,比如一副 32 x 32 x 3(3位 RGB)的图片,输入层就有 3072 个点,假设第一个变换层有 100 个点,则这一层就需要 3072 x 100 + 100 = 307300 个参数,如果是精度更高的图片,加上网络还有多层,参数太多了
  
卷积神经网络:
  主要用于图像识别,其效果非常好,同时黑箱程度也非常著名(既数学上还无法解释证明)
  在全连接神经网络的基础上增加了卷积层(注意这里说的卷积和数学上的卷积不是一个意思),卷积层之间采用局部连接,既每个输出数据只被下一层的部分数据使用,每个数据只使用上一层的部分输出数据,卷积层直接使用三维数据(图片的长、宽、颜色),而全连接网络需要将其转为一维数据,所以全连接层一般用一排圆圈表示,而卷积层一般用一个长方体表示,卷积层通过卷积核(也叫 filter、滤波器)对数据进行转换,产生二维数据,多个卷积核产生多个二维数据输出,最终输出的还是三维数据
  卷积层相当于特征提取的作用,最后还是要通过全连接网络进行分类,实际上后面接其他分类算法也可以,只不过一般都是用全连接神经网络
  卷积神经网络的训练过程与全连接神经网络基本一致

局部连接(Sparse Connectivity)& 权值共享(Shared Weights)

卷积的两个基本概念
  
看到一个有趣的比喻:就像我们看风景,由于视野有限,实际上我们一次只能看到一部分风景,为了看到完整的风景我们必须四处张望,然后得到对全景的感受。实际上完整地看一次可能还不够,可能还会看多次,这次关注点是人,下次关注点是树林,等等,但每次四处张望我们都用相同的思想分析看到的每一部分
  
在这里,视野有限就是局部连接,四处张望并得到对全景的感受就是卷积,使用的思想就是卷积核,同一次张望使用相同的思想观察全景就是权值共享,用不同的思想多次观察全景就是使用多个卷积核
  
更具体的说,卷积核是一个函数,一个卷积层有多个卷积核函数,不同卷积核的函数参数不一样,每次卷积核取上一层的一小部分三维数据作为输入,计算得出一个输出值,从左到右再从上到下扫一遍得到一个二维数据结果,多个卷积核的结果组成三维数据,每个卷积核的大小一样,卷积核的大小决定了输出的长度和宽度,卷积核的数量决定了输出的深度
  
局部连接和权值共享大大减少了参数的数量

经典数据集

MNIST
  0~9 的手写体数据集,60000 张 28 x 28 的图片
  
CIFAR-10
  60000 张 10 个不同种类的图片,像素为 32 x 32
  
CIFAR-100
  60000 张 100 个不同种类的图片,像素为 32 x 32
  100 个类被分成 20 个超类,每张图片即属于一个类又属于一个超类,比如鱼、鲨鱼
  
ImageNet
  约 1500 万张图片,超过 20000 个分类,可以选择 32 x 32 或 64 x 64 的尺寸

卷积神经网络结构


  
卷积神经网络一般包括了输入层、卷积层、池化层、全连接层、输出层

输入层

将原始数据以三维的形式输入

卷积层

结构上,和全连接网络的两点不同
  1. 输入的形式不同(一维和三维)
  2. 层与层之间的连接方式不同(全连接和局部连接)

每次计算一小块数据相当于获取抽象程度更高的特征
  
假设一副 (small 3 imes 3 imes 3) 的图像,其内容为
  
  (small R = egin{bmatrix} 11 & 12 &13 \ 14 & 15 & 16 \ 17 & 18 & 19 end{bmatrix})  (small G = egin{bmatrix} 21 & 22 &23 \ 24 & 25 & 26 \ 27 & 28 & 29 end{bmatrix})  (small B = egin{bmatrix} 31 & 32 &33 \ 34 & 35 & 36 \ 37 & 38 & 39 end{bmatrix})
  
卷积网络直接接受这个三维数组作为输入
  
假设使用 2 个卷积核,每个卷积核的长宽深是 (small 2 imes 2 imes 3) (深度必须和上一层的相同)
每个卷积核的假设参数如下

卷积核 1 

  (small W_{1R}= egin{bmatrix} 0.1 & 0 \ 0.1 & 0.1end{bmatrix})  (small W_{1G}= egin{bmatrix} 0.2 & 0.2 \ 0 & 0.2 end{bmatrix})  (small W_{1B} = egin{bmatrix} 0 & 0.3 \ 0.3 & 0 end{bmatrix})  (small b_{1} =4)

卷积核 2

  (small W_{2R}= egin{bmatrix} 0 & 0.4 \ 0.4 & 0.4 end{bmatrix})  (small W_{2G}= egin{bmatrix} 0.5 & 0.5 \ 0.5 & 0 end{bmatrix})  (small W_{2B} = egin{bmatrix} 0.6 & 0 \ 0 & 0.6 end{bmatrix})  (small b_{2}=7)

卷积核从第 0 行第 0 列开始,从左到右,从上到下,取 (small 2 imes 2 imes 3) 的数据计算
当处于第 i 行第 j 列时,将取得的数据转换为激活函数的输入

  (large z = sum_{k=R}^{B}sum_{m=0}^{1}sum_{n=0}^{1}W_{k}(m,n) imes X_{k}(i+m, j+n) + b)

假设卷积核的激活函数为恒同函数

  (small f(z) = z)

则上面例子的输出为
  (small f(0.1 imes 11 + 0 imes 12 + 0.1 imes 14 + 0.1 imes 15 +)
   (small 0.2 imes 21 + 0.2 imes 22 + 0 imes 24 + 0.2 imes 25 +)
   (small 0 imes 31 + 0.3 imes 32 + 0.3 imes 34 + 0 imes 35 + 4) = 41.4)
  
  (small f(0.1 imes 12 + 0 imes 13 + 0.1 imes 15 + 0.1 imes 16 +)
   (small 0.2 imes 22 + 0.2 imes 23 + 0 imes 25 + 0.2 imes 26 +)
   (small 0 imes 32 + 0.3 imes 33 + 0.3 imes 35 + 0 imes 36 + 4) = 42.9)

  (small f(0.1 imes 14 + 0 imes 15 + 0.1 imes 17 + 0.1 imes 18 +)
   (small 0.2 imes 24 + 0.2 imes 25 + 0 imes 27 + 0.2 imes 28 +)
   (small 0 imes 34 + 0.3 imes 35 + 0.3 imes 37 + 0 imes 38 + 4) = 45.9)

  (small f(0.1 imes 15 + 0 imes 16 + 0.1 imes 18 + 0.1 imes 19 +)
   (small 0.2 imes 25 + 0.2 imes 26 + 0 imes 28 + 0.2 imes 29 +)
   (small 0 imes 35 + 0.3 imes 36 + 0.3 imes 38 + 0 imes 39 + 4) = 47.4)
  
  
  (small f(0 imes 11 + 0.4 imes 12 + 0.4 imes 14 + 0.4 imes 15 +)
   (small 0.5 imes 21 + 0.5 imes 22 + 0.5 imes 24 + 0 imes 25 +)
   (small 0.6 imes 31 + 0 imes 32 + 0 imes 34 + 0.6 imes 35 + 7) = 96.5)
  
  (small f(0 imes 12 + 0.4 imes 13 + 0.4 imes 15 + 0.4 imes 16 +)
   (small 0.5 imes 22 + 0.5 imes 23 + 0.5 imes 25 + 0 imes 26 +)
   (small 0.6 imes 32 + 0 imes 33 + 0 imes 35 + 0.6 imes 36 + 7) = 100.4)
  
  (small f(0 imes 14 + 0.4 imes 15 + 0.4 imes 17 + 0.4 imes 18 +)
   (small 0.5 imes 24 + 0.5 imes 25 + 0.5 imes 27 + 0 imes 28 +)
   (small 0.6 imes 34 + 0 imes 35 + 0 imes 37 + 0.6 imes 38 + 7) = 108.2)
  
  (small f(0 imes 15 + 0.4 imes 16 + 0.4 imes 18 + 0.4 imes 19 +)
   (small 0.5 imes 25 + 0.5 imes 26 + 0.5 imes 28 + 0 imes 29 +)
   (small 0.6 imes 35 + 0 imes 36 + 0 imes 38 + 0.6 imes 39 + 7) = 112.1)
  
最终是一个 (small 2 imes 2 imes 2) 的输出(计算公式在后面的 VALID 和 SAME)
  
  (small egin{bmatrix} 41.4 & 42.9 \ 45.9 & 47.4end{bmatrix})  (small egin{bmatrix} 96.5 & 100.4 \ 108.2 & 112.1end{bmatrix})
  
可以看到,参数个数由核数、核的长宽、输入数据频道大小(或深度)决定,和输入数据的长宽没有关系,这就大大减少了需要的参数个数,卷积核大小可以远小于输入数据的大小,这就是局部视野,在由左到右,由上到下移动的过程中,使用的系数是一样的,这就是权值共享
  
参数个数 = (核长 x 核宽 x 输入数据频道+1) x 核数
上面的例子共需要 (small (2 imes 2 imes 3+1) imes2 = 26)
  
卷积核的大小一般选择 (small 3 imes 3)(small 5 imes 5) 居多
一般卷积层的输出数据的频道数会变得更多
  
Padding
  卷积会导致输出数据的长宽变小,如果需要避免这个问题,可以采用填充(Padding)
  即在外围再增加一层数据,比如用 0 填充,比如前面的数据中的 R 频道变为
  
  (small R = egin{bmatrix} 0 & 0 & 0 & 0 & 0\ 0 & 11 & 12 & 13 & 0\0 & 14 & 15 & 16 & 0\ 0 & 17 & 18 & 19 & 0\ 0 & 0 & 0 & 0 & 0end{bmatrix})
  
  此时用 2 x 2 卷积核,输出是 4 x 4,用 3 x 3 卷积核,输出是 3 x 3,避免了输出维度变小
  
Stride
  此外还可以通过调整步长,改变输出数据的维度
  步长既每次向左、向下移动的步数,前面使用的步长都是 1
  假设卷积核使用步长 2,长宽为 3 x 3,系数 w 全是 1,偏移 b 是 0
  不考虑 GB 频道,只对用 0 填充后的 R 使用,则输出为
  
  (small f(1 imes 0 + 1 imes 0 + 1 imes 0 + 1 imes 0 + 1 imes 11 + 1 imes 12 + 1 imes 0 + 1 imes 14 + 1 imes 15) = 52)
  (small f(1 imes 0 + 1 imes 0 + 1 imes 0 + 1 imes 12 + 1 imes 13 + 1 imes 0 + 1 imes 15 + 1 imes 16 + 1 imes 0) = 56)
  
  (small f(1 imes 0 + 1 imes 14 + 1 imes 15 + 1 imes 0 + 1 imes 17 + 1 imes 18 + 1 imes 0 + 1 imes 0 + 1 imes 0) = 64)
  (small f(1 imes 15 + 1 imes 16 + 1 imes 0 + 1 imes 18 + 1 imes 19 + 1 imes 0 + 1 imes 0 + 1 imes 0 + 1 imes 0) = 68)
  
  既输出 2 x 2 的数据
  
    (small egin{bmatrix} 52 & 56 \ 64 & 68end{bmatrix})
  
TensorFlow 的 padding 有两种方式

  VALID:
    不会添加新元素
  
    out_height = ceil((in_height - filter_height + 1) / stride)  # ceil 为向上取整
    out_width = ceil((in_width - filter_width + 1) / stride)
  
  SAME:
    TensorFlow 自动计算需要在四周添加的元素维度
    (不一定需要四周都添加,优先添加上方和左方,添加元素为 0)
    使得输出数据的长和宽为
      out_height = ceil(in_height / stride)
      out_width = ceil(in_width / stride)
    
    需要添加的元素数量
      pad_needed_height = (out_height – 1) * stride + filter_height - in_height
      pad_top = pad_needed_height / 2
      pad_down = pad_needed_height - pad_top
    
      pad_needed_width = (out_width – 1) * stride + filter_width - in_width
      pad_left = pad_needed_width / 2
      pad_right = pad_needed_width – pad_left

池化层(Pooling)

两个卷积层之间往往会有一个池化层,目的是缩小矩阵尺寸,以加快计算速度、防止过拟合
  
池化层和卷积类似,也有长、宽、Padding、Stride
区别在于,池化层不是加权求和激化,而是简单的取最大值或平均值,以及池化层不会横跨多个频道
  
取最大值的称为极大池化(Max Pooling),取平均值的称为平均池化(Average Pooling)
为什么取平均或最大:CNN 一般处理的是图像,像素级的差异很小,这为上述两种池化提供了一定的合理性
  
实际中池化层的长宽用的最多的是 2 x 2 或 3 x 3
  
假设某个卷积层的输出如下
  
  (small egin{bmatrix} 11 & 12 &13 \ 14 & 15 & 16 \ 17 & 18 & 19 end{bmatrix})  (smallegin{bmatrix} 21 & 22 &23 \ 24 & 25 & 26 \ 27 & 28 & 29 end{bmatrix})  (small egin{bmatrix} 31 & 32 &33 \ 34 & 35 & 36 \ 37 & 38 & 39 end{bmatrix})
  
池化层为 2 x 2 采用平均池化,各输出为
  
  avg(11,12,14,15) = 13  avg(12,13,15,16) = 14  avg(14,15,17,18) = 16  avg(15,16,18,19) = 17
  avg(21,22,24,25) = 23  avg(22,23,25,26) = 24  avg(24,25,27,28) = 26  avg(25,26,28,29) = 27
  avg(31,32,34,35) = 33  avg(32,33,35,36) = 34  avg(34,35,37,38) = 36  avg(35,36,38,39) = 37
  
最终输出 3 x 2 x 2 的数据
  
  (small egin{bmatrix} 13 &14 \ 16 & 17end{bmatrix}) (small egin{bmatrix} 23 & 24 \ 26 & 27end{bmatrix}) (small egin{bmatrix} 33 &34 \ 36 &37end{bmatrix})
  
可以看到池化层起压缩的作用

全连接层

就是上篇讲的全连接神经网络,将池化层或卷积层的输出铺平,然后用全连接神经网络进行非线性变换
  
可以将输入层和卷积层当作是特征提取,将全连接层和输出层当作分类器
  
全连接层一般不会有太多层
  
理论上讲后面的分类可以用其他算法比如 SVM 等,但一般都是用的全连接神经网络

反向传播算法

原理和全连接神经网络是一样的,也是从输出层开始,计算误差,求梯度,通过梯度更新参数
公式推导可能复杂了点,就不列出来了

卷积计算的解决方案

1 变换成比较大规模的矩阵相乘
2 利用快速傅里叶变换(Fast Fourier Transform,FFT)
  
TensorFlow 提供了各种函数用于卷积网络的实现

经典模型

LeNet-5
  1998 年提出,在 MNIST 数据集上达到 99.2% 的正确率
  
  第一层 卷积层
    接受 32 x 32 x 1 输入(既 MNIST 图片的大小),过滤器 5 x 5,卷积核 6 个,不用填充,步长为 1
    共 (5 x 5 x 1+1) x 6 = 156 个参数
    输出矩阵为 28 x 28 x 6
  
  第二层 池化层
    输入为 28 x 28 x 6,过滤器 2 x 2,步长 2,输出 14 x 14 x 6
  
  第三层 卷积层
    接受 14 x 14 x 6 输入,过滤器 5 x 5,卷积核 16 个,不用填充,步长为 1
    共 (5 x 5 x 6+1) x 16 = 2416 个参数
    输出矩阵为 10 x 10 x 16
  
  第四层 池化层
    输入为 10 x 10 x 16,过滤器 2 x 2,步长 2,输出 5 x 5 x 16
  
  第五层 全连接层
    将输入铺平,得到 5 x 5 x 16 = 400 个输入,输出个数 120,共 (5 x 5 x 16+1) x 120 = 48120 个参数
  
  第六层 全连接层
    输入节点 120 个,输出节点 84 个,共 (120+1) x 84 = 10164 个参数
  
  第七层 全连接层
    输入节点 84 个,输出节点 10 个 (图片是 0~9 的数字),共 (84+1) x 10 = 850 个参数
  
Inception-v3
  正常情况下卷积层只能选取某个长宽和核数
  而 Inception-v3 并联使用多个卷积层,每个卷积层使用不同的长宽和核数
  
  每个卷积层使用不同的过滤器尺寸,使用 SAME 模式,使用相同的步长
  这样输出数据的频道数可能不同但长宽相同,可以拼接成更大的频道作为输出
  
  TensorFlow-Slim 可以更方便的实现 Inception-v3
  Inception-v3 同样会有池化层、全连接层

卷积神经网络的迁移学习

训练一个卷积网络,需要大量的标注图片(可能达到百万级别),实际上很难收集到如此大的数据量,即使能,也要花费大量的人力物力,而且训练过程可能需要几天甚至几周的时间
  
迁移学习就是将一个训练好的模型,通过简单的调整使其适用于一个新的问题
  
可以保留训练好的 Inception-v3 模型中所有卷积层的参数,只是替换全连接层
  
卷积层起特征提取的作用,如果一个训练好的系统可以区分很多种图片(比如1000种)的话,有理由认为这个系统的特征提取能力很强,可以直接用于新的分类问题,只需要训练分类即可
  
迁移学习的效果虽然没有重新学习的好,但所需要的训练样本和训练时间能大大减少



原文地址:https://www.cnblogs.com/moonlight-lin/p/12570878.html