美文网首页
第十章 卷积神经网络

第十章 卷积神经网络

作者: 晨光523152 | 来源:发表于2020-02-29 18:07 被阅读0次

    10.1 全连接层网络的问题

    所需的参数多,耗内存

    10.3 卷积层的实现

    在 TensorFlow 中,既可以通过自定义权值的底层实现方式搭建神经网络,也可以直接调用现成的卷积层类的高层方式快速搭建

    10.3.1 自定义权值

    tf.nn.conv2d 函数可以方便地实现 2D 卷积运算。
    输入X:[b,h,w,c_{in}]
    卷积核W:[k,k,c_{in},c_{out}]
    得到输出O:[b,h^{'},w^{'},c_{out}]

    x = tf.random.normal([2,5,5,3])
    # 创建3通道的 2 x 5 x 5的 张量
    w = tf.random.normal([3,3,3,4])
    # 创建 4 通道的, 3 x 3 的卷积核大小的kernel
    out = tf.nn.conv2d(x, w, strides=1, padding=[[0,0],[0,0],[0,0],[0,0]])
    

    其中 padding 参数的设置格式为:

    padding = [[0,0],[上,下],[左,右],[0,0]]
    # 上: 是指在上面填充一个单位,其余同理
    

    特别地,通过设置参数 padding = ‘SAME',strides = 1 可以直接得到输入,输出同大小的卷积层,其中 padding 的具体数量由 TensorFlow 自动计算并完成填充操作:
    (tf.nn.conv2d 函数是没有实现偏置向量计算的,添加偏置只需要手动累加偏置张量即可:)

    x = tf.random.normal([2,5,5,3])
    w = tf.random.normal([3,3,3,4])
    
    out = tf.nn.conv2d(x, w, strides=3, 
        padding='SAME')
    b = tf.zeros([4])
    out = out + b
    

    10.3.2 卷积层类

    通过卷积层类 layers.Conv2D 可以不需要手动定义卷积核 W 和 偏置 b 张量,直接调用类实例即可完成卷积层的前向计算,实现更加高层和快捷。

    在 TensorFlow 中,API 的命名有一定的规律,首字母大写的对象一般表示类,全部小写的一般表示函数。

    layer = layers.Conv2D(4, kernel_size = 3, strides = 1, padding='SAME')
    out = layer(x)
    

    10.4 LeNet-5

    对其中细节不赘述,可以参考之前的文章,
    传送门如下:
    https://www.jianshu.com/p/5c427e9fa79b

    10.9 经典卷积网络

    10.9.1 AlexNet

    AlexNet 创新点

    传送门:
    https://www.jianshu.com/p/526d3ab08098

    10.9.2 VGG 系列

    VGG 系列创新点

    10.9.3 GoogLeNet

    传送们:
    https://www.jianshu.com/p/9162369c653d

    10.10 CIFAR 10 与 VGG 13 实战

    conv_layers = Sequential([
        layers.Conv2D(64, kernel_size = [3, 3], padding = "same", activation = tf.nn.relu),
        layers.Conv2D(64, kernel_size = [3, 3], padding = "same", activation = tf.nn.relu),
        layers.MaxPool2D(pool_size = [2, 2], strides = 2, padding = 'same'),
        layers.Conv2D(128, kernel_size = [3, 3], padding = "same", activation = tf.nn.relu),
        layers.Conv2D(128, kernel_size = [3, 3], padding = "same", activation = tf.nn.relu),
        layers.MaxPool2D(pool_size = [2, 2], strides = 2, padding = "same"),
        layers.Conv2D(256, kernel_size = [3, 3], padding = "same", activation = tf.nn.relu),
        layers.Conv2D(256, kernel_size = [3, 3], padding = "same", activation = tf.nn.relu),
        layers.MaxPool2D(pool_size = [2, 2], strides = 2, padding = "same"),
        layers.Conv2D(512, kernel_size = [3, 3], padding = "same", activation = tf.nn.relu),
        layers.Conv2D(512, kernel_size = [3, 3], padding = "same", activation = tf.nn.relu),
        layers.MaxPool2D(pool_size = [2, 2], strides = 2, padding = "same"),
        layers.Conv2D(512, kernel_size = [3, 3], padding = "same", activation = tf.nn.relu),
        layers.Conv2D(512, kernel_size = [3, 3], padding = "same", activation = tf.nn.relu),
        layers.MaxPool2D(pool_size = [2, 2], strides = 2, padding = "same")
    ])
    
    fc_net = Sequential([
        layers.Dense(256, activation = tf.nn.relu),
        layers.Dense(128, activation = tf.nn.relu),
        layers.Dense(10, activation = None)
    ])
    

    10.11 卷积层变种

    10.11.3 分离卷积

    普通卷积在对多通道输入进行运算时,卷积核的每个通道与输入的每个通道分别进行卷积运算,得到多通道的特征图,再对应元素相加产生单个卷积核的最终输出。

    分离卷积的计算流程则不同,卷积核的每个通道与输入的每个通道进行卷积运算,得到多个通道的中间特征,然后这个多通道的中间特征张量接下来进行多个 1 x 1 卷积核的普通卷积运算,得到多个高度不变的输出,这些输出在通道轴上面进行拼接,产生最终的分离卷积层的输出。
    分离卷积层包含了两步卷积运算,第一步卷积运算是单个卷积核,第二个卷积运算包含了多个 1 x 1 卷积核

    普通卷积核

    上图如果采用 4 个 卷积核的话,所需的参数是 3 x 3 x 3 x 4 = 108,

    深度可分离卷积

    如果使用分类卷积的话,先用一个 3 x 3 的卷积,后面在分别用 4 个 1 x 1 的卷积,能得到和普通卷积核同样规模的输出,但是所需的参数为 3 x 3 x 3 x 1 + 1 x 1 x 3 x 4 = 39。

    可以看出分离卷积的一个明显优势在于,同样的输入和输出,采用深度可分离卷积的参数量约是普通卷积大小的\frac{1}{3}

    10.12 深度残差网络

    研究人员发现网络的层数越深,越有可能获得更好的泛化能力。但是当模型加深以后,网络变得越来越难以训练(主要是因为梯度弥散现象--传递的过程中会出现梯度接近于0的现象)。

    通过在输入和输出之间添加一条直接连接的 Skip Connection 可以让神经网络具有回退的能力,当深层神经网络可以轻松地回退到浅层神经网络时,深层神经网络可以获得与浅层神经网络相当的模型性能,而不至于更糟糕。

    10.12.1 ResNet 原理

    ResNet 通过在卷积层的输入和输出之间添加 Skip Connection 实现层数回退机制,如下图所示:


    残差模块

    听过两个卷积的特征变换后的输出\mathcal{F(x)},与输入x进行对应元素的相加运算,得到最终输出:
    \mathcal{H}(x) = x + \mathcal{F}(x)
    其中,\mathcal{H}(x)叫做残差模块。由于被 Skip Connection 包围的卷积神经网络需要学习映射 \mathcal{F}(x) = \mathcal{H}(x) - x,因此叫做残差网络。

    因为有相加运算,所以必须保证输入x的形状和\mathcal{F}(x)一致。

    当不一致时,需要在 Skip Connection 上添加额外的卷积运算环节将输入x变换到与\mathcal{F}(x)相同的形状。

    10.13 DenseNet

    由于 Skip Connection 在 ResNet 上面获得了巨大的成功,研究人员开始尝试不同的 Skip Connection 方案,其中比较流行的就是 DenseNet。

    DenseNet 将前面所有层的特征图信息通过 Skip Connection 与当前层输出进行了聚合,与 ResNet 的对应位置相加不同,DenseNet 采用在通道轴 c 维度进行拼接操作,聚合特征信息。

    DenseNet

    参考资料:https://github.com/dragen1860/Deep-Learning-with-TensorFlow-book

    相关文章

      网友评论

          本文标题:第十章 卷积神经网络

          本文链接:https://www.haomeiwen.com/subject/vopbchtx.html