重新创建 ResNet50

数据挖掘 深度学习 喀拉斯
2022-03-12 06:46:58

我正在尝试在 Keras 中重新创建 ResNet50。我不了解在块之间创建残差步骤的过程,甚至不了解创建块本身的过程。是不是很简单:

创建 CNN

cnnModel = 模型()

区块 1

cnnModel.add(Conv2D( kernel_size= (7,7), input_shape=(256,256,3), filters = 64, strides=2))

第 2 座

cnnModel.add(MaxPool2D(pool_size=(3,3), strides=2))

区块 3

cnnModel.add(Conv2D( kernel_size= (3,3), input_shape=(256,256,3), filters = 64,)) cnnModel.add(Conv2D( kernel_size= (3,3), input_shape=(256,256,3), filters = 64,)) cnnModel.add(Conv2D( kernel_size= (3,3), input_shape=(256,256,3), filters = 64,)) cnnModel.add(Conv2D( kernel_size= (3,3), input_shape= (256,256,3), 过滤器 = 64,))

第 4 座

cnnModel.add(Conv2D( kernel_size= (3,3), input_shape=(256,256,3), filters = 64,)) cnnModel.add(Conv2D( kernel_size= (3,3), input_shape=(256,256,3), filters = 64,)) cnnModel.add(Conv2D( kernel_size= (3,3), input_shape=(256,256,3), filters = 64,)) cnnModel.add(Conv2D( kernel_size= (3,3), input_shape= (256,256,3), 过滤器 = 64,))

……

还是我必须以某种方式创建“块”?

我还看到了这些被称为“层堆叠”的“块”

在此处输入图像描述

1个回答

恐怕没那么简单 - 看看这个相当不错的演练

您发布的表格是一种概述,不包含“块”如何链接的所有详细信息。其他细节,例如卷积层后的最大池化。

因此,您的模型还不包含主要思想,即残差映射,如本文图表片段中跳过几个卷积层的黑色箭头所示:

resnet 的片段

这是其中一个块的代码(取自我上面链接的博客):

def residual_block(y, nb_channels, _strides=(1, 1), _project_shortcut=False):
    shortcut = y

    # down-sampling is performed with a stride of 2
    y = layers.Conv2D(nb_channels, kernel_size=(3, 3), strides=_strides, padding='same')(y)
    y = layers.BatchNormalization()(y)
    y = layers.LeakyReLU()(y)

    y = layers.Conv2D(nb_channels, kernel_size=(3, 3), strides=(1, 1), padding='same')(y)
    y = layers.BatchNormalization()(y)

    # identity shortcuts used directly when the input and output are of the same dimensions
    if _project_shortcut or _strides != (1, 1):
        # when the dimensions increase projection shortcut is used to match dimensions (done by 1×1 convolutions)
        # when the shortcuts go across feature maps of two sizes, they are performed with a stride of 2
        shortcut = layers.Conv2D(nb_channels, kernel_size=(1, 1), strides=_strides, padding='same')(shortcut)
        shortcut = layers.BatchNormalization()(shortcut)

    y = layers.add([shortcut, y])
    y = layers.LeakyReLU()(y)

    return y

您可以看到他们使用功能 API(这意味着他们使用Model而不是Sequential, from keras.models)。还要注意shortcut变量如何存储在块的开头作为块输入的副本(残差映射),然后用于引入实际的魔法,在块的末尾将这些残差重新提供给网络.

从论文中:

操作 F + x 由快捷连接和元素加法执行

这基本上是if行中的块之后发生的事情:

y = layers.add([shortcut, y])

链接博客末尾的完整代码示例应该有助于提供更多上下文。