首页 > 其他分享 >part3_CNN

part3_CNN

时间:2023-01-03 19:45:06浏览次数:39  
标签:提取 特征 像素 卷积 part3 CNN model

1 CNN概述

前面搭建的全连接神经网络是最初始的神经网络模型,非常自然的想法。但是并非所有数据都适合用全连接神经网络实现,同时使用全连接的深度模型,其连接数量太大,随着层数的加深,复杂度将呈现指数级的增长趋势。对于图像数据,可以发现使用全连接神经网络训练,将会发现消耗巨大,因为根本没有考虑到图片数据的空间结构,单纯的视为数值数据进行盲目地处理,此时如果将图片上的物体进行旋转、平移和缩放等操作,就会认为这些经过处理之后的图片属于不同的类别。

在全连接神经网络中,每个维度的数据被认为是一个特征,所以当一个图片中的事物经过平移、缩放等处理之后,其维度上的序列发生改变,原有维度上的特征也发生变化,所以就被认为是一个新的数据;而人在识别事物时,提取的特征的粒度会大一些,不会是像素级的 ,很多自然特征是层级组成的属性,在其属性中高级特征通过组合低级特征得以呈现。在图片数据中,从低级的像素到高级的轮廓;在语音数据中,从音素到音节再到词汇,组后到语义,无不显现着这种层级属性。

CNN也存在大粒度或者称为高层级的特征提取方法,此外,这些方法相较于全连接神经网络效率更高。

主要内容有:

  • 局部感受场,又称为感受野(Local Receptive Fields)
  • 权重共享(Shared Weight)
  • 池化层(Pooling Layres)
  • 卷积层(Convolutional Layers)

CNN由一个或者多个卷积层和顶端的全连接层组成,同时包括权重共享和池化层。这一结构特性使CNN可以利用输入数据的二维结构。CNN一开始是为了解决图像识别问题发明的,但是其现在的应用不仅限于图像和视频,同时可以用于时间序列数据,如音频数据、文本数据等。图像数据不像其他类型的数据可以通过人工理解提取特征,CNN提取的特征可以达到更高的效果,同时其提取特征和分类训练两个过程不需要分开进行,在训练时就自动提取了最有效的特征。CNN利用空间结构关系减少需要学习的参数量,提高了反向传播算法的训练效率。

相比于传统的机器学习算法,CNN无需提前提取特征,可以在训练过程中自动完成特征的提取和抽象,并进行模型分类,大大降低了图像识别的难度;相比一般的神经网络,CNN在结构上和图片的空间结构更为贴近,都是二维的有联系的结构,并且卷积层的连接方式和人的视觉神经处理光信号的方式类似。

1.1 局部感受场

全连接层的网络结构在配置输入层设置的数据结构时被设置为784(28*28),即在全连接的场景中,输入数据首先被转化为一维数据,然后再用于训练。

但是,在CNN中,输入数据可以不用变换到一维,可以保留原来的数据结构。例如,MNIST数据是黑白的,是一个二维数据,大小为$$m\times n$$(m为长,n为宽),每个像素值的范围是0~255,代表灰度;而彩色图片数据是三维的数据,大小为$$r\times m\times n$$(m为长,n为宽;r为颜色,通常为3,代表的是红、黄、蓝三原色)。

提取特征的方式是利用一个子矩阵(Sub_Matrix),其长和宽远小于输入矩阵的大小,这个子矩阵与下一层感知器的神经元(通常是卷积层,如果在更深的层里可能是池化层)相连接。这里子矩阵所提取的特征就是局部感受场。

局部感受场通过平移的方式将输入中的所有元素都覆盖,通过卷积或者池化的方式,下一层的神经元可以呈现出本层的单个局部感受场,所以下一层神经元组成的层能够呈现出上一层的特征。CNN是逐层提取特征,从较低的层提取的粒度较小,通常以线条和点状形作为特征;中间层的特征慢慢开始具体起来,包括一些局部特征;最高层提取的特征更加具体,已经包括完整的特征信息。整体上,特征的提取从最初的像素到边缘,再到对象局部,最终到对象整体

局部感受场是为了提取局部的显著特征,那么通过平移的方式,则是为了将本层的所有元素全部覆盖到,便于提取全部特征,此外,通过平移的方式可以维持特征之间的相邻关系

子矩阵的长和宽分别记为h和w,N代表原始数据的大小,n代表窗口的大小,s代表平移的步长,L代表特征矩阵的的大小,有如下的关系式:
$$
L=floor(\frac{N-n}{s})+1
$$
由此可以看出两点:一是经过特征采集之后,下一层得到的数据大小实际上被压缩了(只要窗口大小不为1×1,平移量不为1),通过过滤掉一部分特征从而得到关键特征,对原有的数据空间进行了"裁剪"。这样的好处是,能够提取高层级的特征,还可以降低模型在训练过程中的性能损耗。

CNN01

左图为2×2过滤器对3×3数据的提取计数;右图为添加填充后2×2过滤器对3×3数据的提取计数

二,因为矩阵的边缘被提取的次数较少,而矩阵的中心被提取的次数较多。这种压缩方式是以牺牲边缘数据特征为代价的,如果用这种方式在网络模型中逐层叠加,最终得到的训练效果并不会很好,即得到一个尺寸非常小的数据。对于这样的问题,可以将边缘的”像素“变成相对接近中心的,即在数据的边缘之外,填充(Padding)一圈新的”像素“,因为这些被填充的”像素“即使被边缘化也无所谓,这样的处理方式可以使得原来的边缘化的像素变得相对中心化。在填充时,通常将0作为填充数,这样可以不改变提取的特征。同时,原本处在边缘的像素被采集的次数和中心的像素被采集的次数是一样的。

1.2 共享权重和偏差

原本局部感受场的大小为3×3,而投射到特征提取图(Faeture Map)上之后,其大小为1×1,中间通过过滤器(Filter)或者称为核(Kernel)的处理,将感受场中的数值分别乘以过滤器中对应位置的数值并求和,得到的数值成为特征提取图上的一个"像素"。

Filter

在全连接神经网络中,每一层神经元到下一层神经元的权重各异,假设有两层,每层有100个神经元,那么权重及偏差数量达到(100×100+100)个,全连接层的性能损耗也表现在大量的权重及偏差带来的巨大的计算量。

CNN则不存在上述的问题,过滤器的值可以视为神经元之间的权重,在特征提取图上的每一个”像素“都与局部感受场相连接,如果是在全连接场景下,则意味着每一个”像素“与每一个输入数据的”像素“都有连接,而在CNN中,过滤器的数值即权重,这样大大减少了所需要的权重及偏差。

假设输入数据的大小为$$H\times W$$,特征提取图的大小为$$h\times w$$,过滤器的大小为$$s\times s$$,则全连接神经网络需要的权重及偏差数量为$$H×W×h×w$$;CNN所需要的权重及偏差数量为$$H×W×s×s$$。过滤器的大小要远小于特征图的大小,通常过滤器大小为3×3、5×5、7×7,但是特征图小则几百像素,大则几十万像素、几百万像素。因此,CNN较之于全连接神经网络可以减少几个数量级的权重和偏差数量。

1.3 卷积层

通过过滤器或者被称为核的处理,将感受场的数值分别乘以过滤器中对应位置的数值并求和,可以提取较高级的特征,这个过程被称为卷积,卷积核有不同的过滤方式,通过这些过滤所起到的效果也有所不同。

  • 轮廓核(Outline Kernel)——用于突出显示像素值中的巨大差异

    在新图像中,与相邻像素相邻且强度相近的像素显示为黑色,而与相邻像素强烈不同的相邻像素旁边的像素将显示为白色。

  • 锐化核(Sharpen Kernel)——强调相邻像素值的差异,使图像看起来更生动。

轮廓核锐化核
  • Sobel核——用于强调某一方向上的差异,下面是底部Sobel核及左Sobel核,在不同的方向上两者有不同的呈现,前者在水平方向上特征较为显著;而后者则在垂直方向上的特征较为显著。
Sobel核

如果将局部感受场上的”像素“簇通过卷积核(Convolutional Kernel)提取到特征提取层上成为一个像素点上的数值,那么可以增加这个”像素“的深度或者维度,也可以使用多个不同的卷积核叠加提取不同类型的特征,而这些通过卷积计算出的数字可以列入”像素“点上的不同维度。

卷积层的结构

1.4 池化层

在图像数据进行分类时,当分类标识物在图像上发生平移、缩放、旋转等方式时,如果是全连接模型对其进行识别,则认为是不同的数据分类。虽然分类标识物没有发生变化,但是其相应的”像素“值在原有的位置上发生改变,在没有局部感受场的情况下,无法提取更高级的特征,从而出现图像数据无法识别或者识别错误的问题。

这种标识物经过平移、缩放、旋转等方式处理后仍然可以识别的性质被称为不变性。而池化层使模型具有不变性这种特殊的性质。池化层的输入一般来源于上一个卷积层,主要作用是提供较强的健壮性,减少参数数量,防止过拟合。池化层一般没有参数,所以反向传播时,只需要对输入参数求导,而不需要进行权值更新。池化层同样存在”窗口“,也存在平移,唯一不同的是,不需要过滤器,或者成为狭义的过滤器。

对池化层提供了两种实现方法:最大值池化(Max-Pooling)和平均值池化(Average-Pooling)。

最大值池化

在局部感受场区间采集最大值,得到的最大值将在对应的”像素“中,在绝大多数的场景中使用的都是最大值池化。

一个窗口大小为2×2、平移量为(2,2)的最大值池化层对一个4×4的原始数据进行池化,最后输出的大小为2×2。

前向池化层

在反向传播时,只有最大值对下一层有贡献,所以将残差值传递到该最大值的位置,区域内其他位置设为0,其中4×4矩阵非零的位置就是前向传播时计算出的每个小区域的最大值的位置。

反向传播池化层

平均值池化

求取局部感受场区间所有数的平均值,然后将得到的平均值放在对应的"像素"中,这样也可以维持模型的不变性。

平均值池化

池化处理的优点:

  • 降维
  • 实现非线性
  • 扩大感受场
  • 实现不变性:平移不变性、旋转不变性、尺度不变性

特征提取的误差主要来自两个方面:①邻域大小受限造成的估计值方差增大②卷积层参数误差造成估计均值的偏移

一般来说,平均值池化可以减小第一种误差,更多地保留图像的背景信息;最大值池化可以减小第二种误差,更多地保留纹理信息。

1.5 CNN的代码实现

在CNN模型的构建中,卷积层和池化层是连续排列的,因为卷积层的作用是提取上一层较高级的特征,而池化层则是将相似的特征整合起来,即较高级的特征不可以与特征的不变性割裂。此外,为了使模型可以提取多方面的特征,在卷积层中可以设置多个过滤器。

除了卷积层和池化层之外,全连接层也必不可少,因为最后是一个分类问题,而卷积层和池化层本身并不能很好地解决分类问题,而是需要在高级特征的基础上解决分类问题。

当然,还有一些其他的组件,激活函数(层)用于增加模型的非线性,扁平层将池化层的输出进行转换以适用于全连接层的输入,代码如下:

from keras.layers.convolutional import Conv2D, MaxPooling2D
from keras.layers.core import Dense, Activation, Flatten
from keras.datasets import mnist, cifar10
from keras.utils import np_utils
import keras
from tensorflow.keras.optimizers import SGD, RMSprop, Adam
import numpy as np
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.utils.vis_utils import plot_model

# 初始化模型参数
np.random.seed(17)
NB_EPOCH = 10
BATCH_SIZE = 256
N_ADDITION = 1024
VERBOSE = 1
NB_CLASSES = 10
N_HIDDEN = 128
VALIDATION_SPLIT = 0.2

# 配置模型
# (X_train, y_train), (X_test, y_test) = mnist.load_data()
(X_train, y_train), (X_test, y_test) = cifar10.load_data()
X_train = X_train.astype('float32')
X_test = X_test.astype('float32')
# X_train = X_train[:, :, :, np.newaxis]
# X_test = X_test[:, :, :, np.newaxis]
X_train = X_train[:, :, :]
X_test = X_test[:, :, :]
# input_shape = (28, 28, 1)
input_shape = (32, 32, 3)
print(X_train.shape)
X_train /= 255
X_test /= 255
y_train = np_utils.to_categorical(y_train, NB_CLASSES)
y_test = np_utils.to_categorical(y_test, NB_CLASSES)

# 构建卷积模型
model = Sequential()

model.add(Conv2D(20, kernel_size=3, padding='same', input_shape=input_shape))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2), padding='valid'))

model.add(Conv2D(20, kernel_size=3, padding='same', input_shape=input_shape))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2), padding='valid'))

# model.add(Conv2D(20, kernel_size=3, padding='same', input_shape=input_shape))
# model.add(Activation('relu'))
# model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2), padding='valid'))

model.add(Flatten())
model.add(Dense(50))
model.add(Activation('relu'))
model.add(Dense(10))
model.add(Activation('softmax'))

model.summary()

# 初始化一个回调函数
CSV_log = keras.callbacks.CSVLogger('./csv/cnn两层.log')
# 模型编译及训练
model.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
model.fit(X_train, y_train, batch_size=BATCH_SIZE, epochs=NB_EPOCH, verbose=VERBOSE,validation_split=VALIDATION_SPLIT, callbacks=[CSV_log])

1.6 CNN调优

神经网络中基础的调优方案有:增加神经网络模型的深度、宽度以及训练的轮数;有时候还存在一定的过拟合情况,可以采用增加Dropout层及配置正则化器的方法。

模型名称 采用的技术 达到的效果
AlexNet 激活函数ReLU 解决了Sigmoid函数在网络较深时出现的梯度消散问题
局部归一 对局部神经元的活动创建竞争机制,使其中响应较大的值变得相对更大,并抑制其他反馈较小的神经元,增强了模型的泛化能力
VGG系列 小卷积核叠加 更多的激活函数,更丰富的特征,更强的辨别能力,并且只需要更少的参数
小池化核 更容易捕捉图像上的变化、梯度的变化,带来更大的局部信息差异性,更好地描述边缘、纹理等构成语义的细节信息
ResNet系列 恒等映射/捷径连接 使网络能够从整体上达到更深,使堆积层在输入特征基础上学习到新的特征,从而拥有更好的性能
Inception网络模型 Inception模块 利用网络内部的计算资源,涉及允许增加网络的深度和宽度,同时保持计算预算不变,不同的卷积运算与池化操作可以获得输入图像的不同信息,并行处理这些运算并结合所有结果将获得更好的图像表征

标签:提取,特征,像素,卷积,part3,CNN,model
From: https://www.cnblogs.com/olin25/p/17023203.html

相关文章