卷积神经网络要义

什么是卷积(convolutional)?

如果脱离出卷积神经网络这个应用背景,单纯从数学层面上看,卷积其实就是一个函数和另一个函数在某个维度上的加权“叠加”。

图像识别领域是卷积神经网络大显神威的“圣地”,我们把卷积看成一种有效提取图片特征的方法,一般用一个正方形的卷积核,遍历图片上的每一个像素点,图片与卷积核重合区域内对应的每一个像素值乘卷积核内相对应点的权重,然后求和,再加上偏置项后,最后得到输出图片的像素值。

例如:

上面表示5*5*1的灰度图片,1表示单通道,5*5表示分辨率,共有5行5列个灰度值,用一个3*3*1的卷积核对此5*5*1的灰度图片进行卷积.

则卷积的计算为:

(-1)*1+0*0+1*2+(-1)*5+0*4+1*2+(-1)*3+0*4+1*5=0

这里的偏置项b为0,如果偏置项不为0,要记得末尾加上偏置项。

输出图片的边长为:(5-3+1)/3=3,即(输入图片边长-卷积核长+1)/步长。

经过该卷积核输出的图片为3*3*1,3*3的分辨率,用了一个卷积核,输出深度为1。

这里就不得不提一下卷积核了,利用卷积核对输入的图片进行处理,提取到的特征具有更高的鲁棒性。所谓卷积核,实质上就是一个权值矩阵,有很多人们长期摸索而成的有意思的卷积核,如同一化核,边缘检测核,图像锐化核,浮雕核等等,经过边缘检测核的图片会很暗,只有边缘位置是亮的;经过浮雕核的图片,可以给图片营造出一种艺术化的3D阴影效果等等。

再聊一下卷积神经网络的结构:

不考虑输入层的情况下,一个典型的卷积神经网络通常包含若干个卷积层(Convolutional Layer)、激活层(Activation Layer)、池化层(Pooling Layer)以及全连接层(Fully Connection Layer)组成。

配合Tensorflow给出计算卷积的函数,我们来分别看看这些层:

卷积层(Convolutional Layer):卷积神经网络的核心所在,可达到两个重要目的,降维处理和提取特征。

tf.nn.conv2d(
    input,    # 对图片的输入描述[batch,in_height,in_width,in_channels]
    filter=None,  # 对卷积核的描述[filter_height,filter_width,in_channels,out_channels]
    strides=None,  # 对卷积核滑动步长的描述
    padding=None,   #是否使用padding(填充)
    use_cudnn_on_gpu=True,
    data_format='NHWC',
    dilations=[1, 1, 1, 1],
    name=None,
    filters=None
)

函数要求必须给出前四个信息,函数功能就是在给定的4维输入张量中计算2维卷积。(1)输入图片的描述,eg:[batch,分辨率,分辨率,通道数],如果是灰度图,则为单通道,参数写1,如果是彩色图则为红绿蓝三通道,参数写3;(2)对卷积核的描述,filter的第三个参数in_channels就是参数input的第四个维度,eg:[卷积核高度,卷积核宽度,通道数,核个数];(3)对卷积核滑动步长的描述,表示卷积时在图像每一维的步长;(4)是否使用padding,只有两个类型“SAME(一致性填充)”和“VALID(有效填充)”,前者能确保输入图像和输出图像保持大小一致,后者事实上不填充,可能会裁剪图片。

激活层(Activation Layer):作用在于将前一层的线性输出,通过非线性的激活函数进行处理,用以模拟任意函数,从而增强网络的表征能力。

在深度学习领域,用的较多的是ReLU(Rectified-Linear Unit)非线性激活函数,主要原因是它收敛更快,次要原因是它部分解决了梯度消失问题。tensorflow中提供了多种激活函数、如tf.sigmoid、tf.tanh、tf.nn.relu及tf.nn.dropout等。

tf.nn.relu(
    features,  # 输入值
    name=None  #(可选)对该操作命名
)
tf.nn.dropout(
    x,    # 输入张量
    keep_prob=None,   # 每个元素被保留下来的概率,float型
    noise_shape=None,  # 默认每个元素的去留是随机的,加入它,某些元素去留就不那么随机了
    seed=None,   #随机数种子
    name=None,
)

池化层(Pooling Layer):也可以称为采样层,可以降低数据规模,增加强卷积神经网络的泛化处理能力。在网络训练时,数据多了并不见得是好事,它容易产生过拟合,计算量也会增大,池化层就可以在合理减少输入数据的同时,保留每个矩阵中最显著的特征,并提升模型的泛化能力。

tensorflow中给出了两种常见计算池化的函数,tf.nn.max_pool()最大池化函数以及tf.nn.avg_pool()平均池化函数。

tf.nn.max_pool(
    value,    # 对输入的描述[batch,height,width,channels]
    ksize,    # 对池化核的描述[batch,height,width,channels]
    strides,  # 对池化核滑动步长的描述[batch,stride,stride,channels]
    padding,  # 是否使用padding
    data_format='NHWC',
    name=None,
    input=None
)

函数要求给出四个信息,(1)对输入的描述,eg:[batch,行分辨率,行分辨率,通道数],池化层一般连接在卷积层后面,所以它的输入通常是特征图谱;(2)对池化核的描述,这里可以只描述行分辨率核列分辨率,第一个和最后一个参数固定为1,eg:[1,行分辨率,列分辨率,1];(3)对池化核滑动步长的描述,同样,通常设置不在batch和channels维度上做池化,只描述纵向滑动步长核横向滑动步长,第一个和最后一个参数固定为1,eg:[1,行步长,列步长,1];(4)是否使用padding,与卷积类似,可取“VALID(有效填充,图大小被裁剪)”和“SAME(一致填充,图大小被保持)”。

tf.nn.avg_pool(
    value, # 对输入的描述[batch,height,width,channels]
    ksize,    # 对池化核的描述[batch,height,width,channels]
    strides,  # 对池化核滑动步长的描述[batch,stride,stride,channels]
    padding,  # 是否使用padding
    data_format='NHWC',
    name=None,
    input=None
)

均值池化tf.nn.avg_pool()的用法和tf.nn.max_pool()函数用法完全一样。

全连接层(Fully Connection Layer):在整个卷积神经网络中起到分类器的作用,通过前面多个“卷积-激活-池化”层的层层堆叠,将输入层导入的原始图片逐层抽象,形成高语义信息,送到全连接层做分类,便完成了神经网络的前向传播计算。

全连接层的表示就是一个矩阵乘法tf.matmul(),在计算完矩阵之后,相当于计算出每个神经元的加权和,然后它还要加上自己的偏置。

全连接层将其目标任务(分类、回归)形式化为损失函数,再计算预期值与真实值之间的差值,就可计算loss,再通过BP反向传播算法,将loss向后反向传播,更新网络的权值,多循环几次,前向传播->后向反馈->权值更新,模型渐渐收敛,这样一个卷积神经网络模型就训练好了。

卷积神经网络从诞生到现在,每一种网络结构都是以卷积、激活、池化、全连接着四种操作作为基础进行扩展的,包括后面将一一接触到的经典网络结构Lennet-5、Alexnet、VGGNet、GoogleNet和ResNet都是。

猜你喜欢

转载自blog.csdn.net/qq_41127332/article/details/101062382
今日推荐