卷積神經網絡相關內容總結

1)ResNet

(1)Deeper Bottleneck Architectures

bottleneck架構設計的目的就在於減少參數數量,進而縮短訓練時間。注意bottleneck只在resnet50、resnet101、resnet152中使用,resnet18與resnet34仍使用兩層3*3卷積堆疊的設計。

(2)對於channel不同的卷積層之間,使用步長爲2的卷積操作。反之直接使用相加操作。

以keras resnet50實現爲例:

def identity_block(input_tensor, kernel_size, filters, stage, block):
    """The identity block is the block that has no conv layer at shortcut.

    # Arguments
        input_tensor: input tensor
        kernel_size: default 3, the kernel size of
            middle conv layer at main path
        filters: list of integers, the filters of 3 conv layer at main path
        stage: integer, current stage label, used for generating layer names
        block: 'a','b'..., current block label, used for generating layer names

    # Returns
        Output tensor for the block.
    """
    filters1, filters2, filters3 = filters
    if backend.image_data_format() == 'channels_last':
        bn_axis = 3
    else:
        bn_axis = 1
    conv_name_base = 'res' + str(stage) + block + '_branch'
    bn_name_base = 'bn' + str(stage) + block + '_branch'

    x = layers.Conv2D(filters1, (1, 1),
                      name=conv_name_base + '2a')(input_tensor)
    x = layers.BatchNormalization(axis=bn_axis, name=bn_name_base + '2a')(x)
    x = layers.Activation('relu')(x)

    x = layers.Conv2D(filters2, kernel_size,
                      padding='same', name=conv_name_base + '2b')(x)
    x = layers.BatchNormalization(axis=bn_axis, name=bn_name_base + '2b')(x)
    x = layers.Activation('relu')(x)

    x = layers.Conv2D(filters3, (1, 1), name=conv_name_base + '2c')(x)
    x = layers.BatchNormalization(axis=bn_axis, name=bn_name_base + '2c')(x)

    x = layers.add([x, input_tensor])
    x = layers.Activation('relu')(x)
    return x

identity block是維度一致的res block,最後將輸出與input_tensor直接相加。

def conv_block(input_tensor,
               kernel_size,
               filters,
               stage,
               block,
               strides=(2, 2)):
    """A block that has a conv layer at shortcut.

    # Arguments
        input_tensor: input tensor
        kernel_size: default 3, the kernel size of
            middle conv layer at main path
        filters: list of integers, the filters of 3 conv layer at main path
        stage: integer, current stage label, used for generating layer names
        block: 'a','b'..., current block label, used for generating layer names
        strides: Strides for the first conv layer in the block.

    # Returns
        Output tensor for the block.

    Note that from stage 3,
    the first conv layer at main path is with strides=(2, 2)
    And the shortcut should have strides=(2, 2) as well
    """
    filters1, filters2, filters3 = filters
    if backend.image_data_format() == 'channels_last':
        bn_axis = 3
    else:
        bn_axis = 1
    conv_name_base = 'res' + str(stage) + block + '_branch'
    bn_name_base = 'bn' + str(stage) + block + '_branch'

    x = layers.Conv2D(filters1, (1, 1), strides=strides,
                      name=conv_name_base + '2a')(input_tensor)
    x = layers.BatchNormalization(axis=bn_axis, name=bn_name_base + '2a')(x)
    x = layers.Activation('relu')(x)

    x = layers.Conv2D(filters2, kernel_size, padding='same',
                      name=conv_name_base + '2b')(x)
    x = layers.BatchNormalization(axis=bn_axis, name=bn_name_base + '2b')(x)
    x = layers.Activation('relu')(x)

    x = layers.Conv2D(filters3, (1, 1), name=conv_name_base + '2c')(x)
    x = layers.BatchNormalization(axis=bn_axis, name=bn_name_base + '2c')(x)

    shortcut = layers.Conv2D(filters3, (1, 1), strides=strides,
                             name=conv_name_base + '1')(input_tensor)
    shortcut = layers.BatchNormalization(
        axis=bn_axis, name=bn_name_base + '1')(shortcut)

    x = layers.add([x, shortcut])
    x = layers.Activation('relu')(x)
    return x

可以看到convblock中shortcut使用了一個在h、w兩個方向上strides均爲2的1*1卷積。最後同樣包括相加操作。

2)mobilenet

(1)V1

將標準卷積分解爲深度卷積(depthwise convolution)和逐點卷積(pointwise convolution)

還是以keras實現的mobilenet爲例:

def _depthwise_conv_block(inputs, pointwise_conv_filters, alpha,
                          depth_multiplier=1, strides=(1, 1), block_id=1):
    channel_axis = 1 if backend.image_data_format() == 'channels_first' else -1
    pointwise_conv_filters = int(pointwise_conv_filters * alpha)

    x = layers.ZeroPadding2D((1, 1), name='conv_pad_%d' % block_id)(inputs)
    x = layers.DepthwiseConv2D((3, 3),
                               padding='valid',
                               depth_multiplier=depth_multiplier,
                               strides=strides,
                               use_bias=False,
                               name='conv_dw_%d' % block_id)(x)
    x = layers.BatchNormalization(
        axis=channel_axis, name='conv_dw_%d_bn' % block_id)(x)
    x = layers.Activation(relu6, name='conv_dw_%d_relu' % block_id)(x)

    x = layers.Conv2D(pointwise_conv_filters, (1, 1),
                      padding='same',
                      use_bias=False,
                      strides=(1, 1),
                      name='conv_pw_%d' % block_id)(x)
    x = layers.BatchNormalization(axis=channel_axis,
                                  name='conv_pw_%d_bn' % block_id)(x)
    return layers.Activation(relu6, name='conv_pw_%d_relu' % block_id)(x)

過程比較明確,depthwiseconv與1*1卷積(逐點卷積)。

(2)V2

a)引入了殘差操作。

b)在depthwiseconv之前先使用1*1卷積增加維度。使用inverted residual block模塊。

c)pointwise結束之後不在使用relu激活函數,而是使用linear激活函數,來防止relu對特徵的破壞。

3)inception

Inception V1——構建了1x1、3x3、5x5的 conv 和3x3的 pooling 的分支網絡,同時使用 MLPConv 和全局平均池化,擴寬卷積層網絡寬度,增加了網絡對尺度的適應性;

Inception V2——提出了 Batch Normalization,代替 Dropout 和 LRN,其正則化的效果讓大型卷積網絡的訓練速度加快很多倍,同時收斂後的分類準確率也可以得到大幅提高,同時學習 VGG 使用兩個3´3的卷積核代替5´5的卷積核,在降低參數量同時提高網絡學習能力;
Inception V3——引入了 Factorization,將一個較大的二維卷積拆成兩個較小的一維卷積,比如將3´3卷積拆成1´3卷積和3´1卷積,一方面節約了大量參數,加速運算並減輕了過擬合,同時增加了一層非線性擴展模型表達能力,除了在 Inception Module 中使用分支,還在分支中使用了分支(Network In Network In Network);
Inception V4——研究了 Inception Module 結合 Residual Connection,結合 ResNet 可以極大地加速訓練,同時極大提升性能,在構建 Inception-ResNet 網絡同時,還設計了一個更深更優化的 Inception v4 模型,能達到相媲美的性能。


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章