Advertisement

Understanding convolution neural networks Part I

阅读量:

作者:禅与计算机程序设计艺术

1.简介

卷积神经网络(Convolutional Neural Network, CNN)被广泛认为是当前研究的热点之一。这些模型因其具备高效的图像识别、分类与物体检测能力而自然地在图像、视频以及文本等多个领域得到广泛应用。

本系列博客文章旨在帮助你迅速掌握CNN相关基础知识,并深入学习其原理、核心要素及其分类等内容及其常见实现方式。

本文共分为两个部分。第一部分是对CNN的基础知识进行阐述,并涵盖研究背景分析与理论基础阐述。第二部分着重探讨CNN的具体实现方式与实践应用,并涵盖算法原理阐述、编程实现细节以及理论与实践结合分析。

2.基本概念术语说明

2.1 深度学习基本概念 深度学习是一种以数据驱动的机器学习方法。其本质是通过持续调整优化模型参数,在训练过程中不断提升模型对更多样化数据和复杂任务环境的适应能力。深度学习能够从海量数据中自主提取出具有价值的信息特征,并在此基础上构建高效的分析与决策体系。

深度学习的三个主要组成要素如下:

模型:深度学习体系包含三层结构:输入节点、隐含单元以及输出节点。其中的输入节点用于接收原始数据并传递给隐含单元进行信息处理;隐含单元则经过特征提取与数据加工后将结果传递至后续的输出节点完成任务;系统的最后一级模块即输出节点会对前一层的信息进行整合与转换生成最终的结果数据。

该段改写后的内容:
数据:深度学习模型所需的训练样本通常分为两组:训练集和验证集。其中,训练集主要用于模型参数的学习过程,而验证集则用于评估其预测的准确性水平。

选择合适的优化器:在训练过程中需要采用特定的优化方法来更新模型参数,并从而提升模型性能。常用的方法包括随机梯度下降方法(Stochastic Gradient Descent, SGD)、动量方法(Momentum)以及Adam最优化方法。

2.2 卷积神经网络基本概念 卷积神经网络(Convolutional Neural Network, CNN)是深度学习的一个重要分支领域,在其体系架构中主要以卷积操作作为处理输入数据的基本单元。整个网络架构设计通常包含多个卷积组件与下采样组件交替组合而成,在每一层次中均通过可学习的滤波器与偏置项实现多方位的特征提取、空间上的重叠性以及降维效果。该模型凭借其自身具备的自适应性地选择关键特征、局部区域的连接性以及参数间的共享性等优势特性,并能在引入Dropout机制后有效防止模型过度拟合问题。

卷积神经网络的结构图如下:

CNN的主要组件包括:

卷积层作为二维滤波器,在神经网络中用于提取空间信息。它接收输入特征图(通常来自上一层输出),执行特定核与输入图像在空间域上的滑动内积操作,并生成输出特征图其尺寸受滤波器尺寸、步长以及填充策略影响。

激活函数:该技术负责将输出调节至[0,1]范围内以确保其成为概率值。常见的实现方式包括sigmoid族函数及其变形如tanh和ReLU等;此外还包含基于神经统计学原理设计的activation family如softmax等

全连接层:密集连接层通过线性变换将输入特征转换为输出表示,在深度学习模型中常与 preceding 的卷积层或池化操作相结合,并被称作神经元单元以探索和建模不同特征之间的相互作用和关联。

池化层:池化层用于降低特征图的空间尺寸,并多以最大池化或平均池化的形式实现。经过最大池化或平均池化的处理过程后,能够有效提取关键特征信息并去除冗余细节。

损失函数用于评估模型在训练阶段预测结果与实际标签之间的差异,并通过优化模型参数使其达到最小值

优化器:作为更新模型参数的核心组件,在训练过程中,通过计算损失函数对各模型参数的梯度,并基于这些梯度进行更新操作。具体而言,梯度下降法以及Adam算法等被用来完成这一过程。

3.核心算法原理和具体操作步骤以及数学公式讲解

3.1 Convolution layer

卷积层的目的是对输入数据做卷积运算,得到一个新的特征图。

首先,在设定好的卷积核尺寸下对输入数据与滤波器进行截取操作(具体为F_H \times F_W尺寸),随后在截取后的区域中对每个像素点与其对应滤波器权重进行相乘运算;接着将各乘积累加,并加入偏置参数以获得该局部区域上的特征响应结果

对于不同的滤波器来说,它们能够产出各自独特的输出特征图。
比如,在边缘检测滤波器中,则仅呈现水平或垂直方向上的边缘特征;
而对于线性滤波器而言,则通过加权值的转换作用于输入数据,
从而生成相应的输出数据。

由此可见,在信号处理领域中,滤波器也可被视为一种专门的特征提取装置,在这种情况下它们通过分析图像的空间特性来执行多样化的特征提取过程。

对于边缘检测滤波器,其卷积核为:

在本系统中,符号-1表示原始图像的水平方向或垂直方向移动,在此过程中会引入一种偏移量;参数4则对应于每个中心点周围所包含的四个相邻点的数量。对于输入图像中的每一个点而言,在其周围存在四个相邻点的情况下,则可以计算出其与这些邻居之间的差异程度;如果该区域中的颜色变化显著,则可判断该区域为边缘区域。

对于线性滤波器,卷积核可以选择任意的矩阵,如平滑滤波器,可以设置为:

它可以被用于模糊图像以使图片变得更为平滑。同样也可被用于执行其他任务例如图像增强。

随后,在卷积操作中添加填充层可以显著提升输出特征图的空间尺寸。以刚才所述为例,在未施加填充操作的情况下(即直接进行卷积运算),输出特征图的大小为(H-\text{kernel\_height}+1)\times (W-\text{kernel\_width}+1)。这表明相对于输入图像而言(其尺寸为H\times W),输出图像在高度方向减少了\text{kernel\_height}-1个像素,在宽度方向减少了\text{kernel\_width}-1个像素。这样的效果可能无法捕获到边缘区域的信息(即位于输入图像边界附近的像素),因此可以通过在输入图像四周添加零值像素(zero padding)来弥补这一缺陷。从而解决这一问题的有效办法就是通过在输入图像四周添加零值像素(zero padding)。

所以,一个标准的卷积层包括三个步骤:

  1. 通过卷积运算将输入数据与滤波器结合生成局部响应图的一部分。
  2. 采用零填充策略使提取到的目标图像具有更大的空间尺寸。
  3. 在计算过程中加入偏置参数以获取最终的特征映射。

最后,激活函数通常用于缩放输出,获得概率值。

3.2 Pooling layer

池化层的目的是将特征图进行缩小,减少计算量,同时保持关键特征。

在卷积神经网络中,通常主要使用最大池化和平均池化的两种方法来进行特征提取。其中,在最大池化过程中,通过滑动一个大小固定的窗口遍历输入特征图,并将该区域的最大值作为其输出结果;而在平均池化的操作中,则是通过计算该区域所有元素的算术平均值来确定最终的输出结果。

该池化层所使用的卷积核尺寸为P_H \times P_W,其步长参数设置为S;padding策略与默认配置一致。

3.3 Fully connected layer

该段文字已经按照要求进行了改写

3.4 Softmax function and loss function

softmax函数主要负责将输入数值转换为概率分布。该函数在分类问题中生成各类别的概率值。其数学表达式如下: 其中\vec x表示输入向量,在其中的每一个元素x_i(i=1,2,…,C)代表输入向量中的第i个元素,并且共有C$个类别。

该模型的性能通过损失函数进行评估和优化,在训练过程中通过比较预测结果与真实标签之间的差异来不断改进模型参数。其中一种常用选择是采用交叉熵损失函数来度量这一差距。该方法能够计算模型预测的概率分布与真实分布之间的差异程度。

在二分类问题中,其损失函数的形式可表述为:其中符号y_i代表真实类别标签;而f(x_i)则表示模型在输入x_i下的概率输出;最后涉及的lgn则指代对数运算符。

4.具体代码实例和解释说明

4.1 代码实现

复制代码
    import numpy as np
    
    class ConvLayer:
    def __init__(self, filter_size, input_channel, output_channel):
        self.filter_size = filter_size
        self.input_channel = input_channel
        self.output_channel = output_channel
    
        # initialize weights with small random values
        std = np.sqrt(2/(self.filter_size**2 * self.input_channel))
        self.weights = np.random.normal(scale=std, size=(self.filter_size**2*self.input_channel, self.output_channel))
    
    def forward(self, inputs, padding='SAME'):
        batch_size, height, width, channel = inputs.shape
    
        if padding == 'VALID':
            pad_top, pad_bottom, pad_left, pad_right = (0, 0, 0, 0)
        elif padding == 'SAME':
            pad_top = int((self.filter_size // 2) - ((height % 2!= 0)*1 + height//2 - 1))
            pad_bottom = int((self.filter_size // 2) + height%2 + height//2 - 1)
            pad_left = int((self.filter_size // 2) - ((width % 2!= 0)*1 + width//2 - 1))
            pad_right = int((self.filter_size // 2) + width%2 + width//2 - 1)
    
            pad_width = ((pad_top, pad_bottom), (pad_left, pad_right), (0, 0))
            inputs = np.pad(inputs, pad_width, mode='constant', constant_values=0.)
    
        # flatten the input data into a row vector of pixel values
        flat_inputs = inputs.reshape((-1, self.input_channel))
    
        # reshape the weights to be able to multiply them with the flattened pixels
        reshaped_weights = self.weights.reshape((self.filter_size**2*self.input_channel, self.output_channel)).T
    
        # perform the dot product between the flattened pixels and transposed weights to get feature maps
        outputs = np.dot(flat_inputs, reshaped_weights)
    
        return outputs
    
    if __name__ == '__main__':
    import matplotlib.pyplot as plt
    
    # create an example image for testing
    image = np.zeros((7, 7, 3))
    image[2:-2, 2:-2, :] = 1
    
    conv_layer = ConvLayer(3, 3, 8)
    out = conv_layer.forward(image[...,np.newaxis])
    
    fig, axes = plt.subplots(1, 2)
    axes[0].imshow(image)
    axes[1].imshow(out.squeeze())
    plt.show()
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读

运行上面代码示例,生成的输出如下:

4.2 TensorFlow implementation

TensorFlow支持构建卷积神经网络的API,并且非常容易使用;以下提供了一个具体的实施方法。

复制代码
    import tensorflow as tf
    
    def cnn_model(inputs):
    # first convolutional layer
    conv1 = tf.layers.conv2d(inputs=inputs, filters=32, kernel_size=[5, 5], strides=(1, 1),
                             activation=tf.nn.relu)
    pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)
    
    # second convolutional layer
    conv2 = tf.layers.conv2d(inputs=pool1, filters=64, kernel_size=[5, 5], strides=(1, 1),
                             activation=tf.nn.relu)
    pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2)
    
    # fully connected layer
    fc1 = tf.contrib.layers.flatten(inputs=pool2)
    fc1 = tf.layers.dense(inputs=fc1, units=1024, activation=tf.nn.relu)
    dropout = tf.layers.dropout(inputs=fc1, rate=0.5)
    logits = tf.layers.dense(inputs=dropout, units=10)
    
    predictions = {
      "classes": tf.argmax(input=logits, axis=1),
      "probabilities": tf.nn.softmax(logits, name="softmax_tensor")
    }
    
    return predictions
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读

在本研究中构建了一个卷积神经网络模型,在其架构设计中包含了两个卷积模块和一个全连接层结构。其中都具备自定义的结构设置,并根据实验需求选择了相应的参数配置以及激活函数选择也是用户自主决定的。

模型会接受一张彩色图像作为输入,并对应十个类别概率分布作为输出。在训练过程中,该模型所使用的损失函数即为交叉熵损失函数。为了提高训练效果,在这一过程中我们采用了Adam优化器以及BatchNormalization等多种技术手段进行辅助训练。

经过充分而有效的模型训练后,
能够应用到新收集的数据样本上进行预测分析。
其中,
预测结果中的分类信息及其概率分布情况有助于深入分析图片中是否存在指定的目标物体。

全部评论 (0)

还没有任何评论哟~