【问题标题】:What does layer.get_weights() of a Separable convolutional layer means?可分离卷积层的 layer.get_weights() 是什么意思?
【发布时间】:2020-10-14 10:53:55
【问题描述】:

我了解到我们可以使用函数layer.get_weights() 来获取层的权重和偏差。这将返回一个长度为 2 的列表。层的权重存储在layer.get_weights()[0],偏差存储在layer.get_weights()[1](如果在定义层期间没有禁用偏差)。对于普通的卷积层也是如此。

我最近在EfficientDet model 中使用可分离卷积层作为我的层之一。

layers.SeparableConv2D(num_channels, kernel_size=kernel_size, strides=strides, padding='same',
                            use_bias=True, name=str(name)+"/conv")

当我尝试使用相同的layer.get_weights() 函数时,它返回给我一个length 3 列表,我期望它是2,与上面的相同。 在此,我对列表中的三个值是什么感到有些困惑。 任何帮助和建议将不胜感激。

【问题讨论】:

    标签: machine-learning keras conv-neural-network layer efficientnet


    【解决方案1】:

    SeparableConv2D 层正在计算深度可分离卷积,与普通卷积不同,它需要 2 个内核(2 个权重张量)。无需过多介绍,它使用第一个内核来计算深度卷积,应用此操作后,它使用第二个内核来计算逐点卷积。这背后的主要思想是减少参数的数量,从而减少计算的数量。

    这是一个简单的例子。假设我们有输入图像 28x28x3(宽度、高度、#channels)并且我们应用正常的 2D 卷积(比如说 16 个过滤器和 5x5 内核,没有步幅/填充)。

    如果我们进行计算,那么我们最终得到 5x5x3x16(5x5 过滤器大小,3 个输入通道和 16 个过滤器)= 1200 个内核参数 + 16 个偏置参数(每个过滤器一个)= 1216。我们可以验证这一点

    model = tf.keras.models.Sequential([
        tf.keras.layers.Input(shape=(28, 28, 3)),
        tf.keras.layers.Conv2D(16, (5, 5)),
    ])
    model.summary()
    

    给我们

    Layer (type)                 Output Shape              Param #   
    =================================================================
    conv2d_4 (Conv2D)            (None, 24, 24, 16)        1216
    

    如果我们提取内核参数。

    print(model.layers[0].get_weights()[0].shape)
    

    这给了我们

    (5, 5, 3, 16)
    

    现在,让我们考虑具有 2 个内核的可分离 2D 卷积,深度内核由每个输入通道的单独 5x5x1 权重矩阵组成,在我们的例子中 - 5x5x3(5x5x3x1 - 与 4D keras 张量一致)。这给了我们 75 个参数。

    逐点内核是一个简单的 1x1 卷积(它对每个输入点进行操作),它用于将结果的深度增加到指定过滤器的数量。在我们的例子中 - 1x1x3x16,它为我们提供了 48 个参数。

    总共有 75 个参数用于第一个内核,48 个参数用于第二个内核,这为我们提供了 123 个参数以及 16 个偏置参数。也就是 139 个参数。

    在 keras 中,

    model = tf.keras.models.Sequential([
        tf.keras.layers.Input(shape=(28, 28, 3)),
        tf.keras.layers.SeparableConv2D(16, (5, 5)),
    ])
    model.summary()
    

    给我们

    Layer (type)                 Output Shape              Param #   
    =================================================================
    separable_conv2d_7 (Separabl (None, 24, 24, 16)        139   
    

    正如我们所见,这些层的输出形状与普通卷积层完全相同,但现在我们有 2 个参数少得多的内核。再一次,我们可以提取这两个内核的参数,

    print(model.layers[0].get_weights()[0].shape)
    print(model.layers[0].get_weights()[1].shape)
    

    这给了我们

    (5, 5, 3, 1)
    (1, 1, 3, 16)
    

    如果您想了解有关可分离卷积工作原理的更多详细信息,可以阅读this article

    【讨论】:

    • 感谢您的详细解释。我相信它对未来的用户也会非常有用。干杯:)
    猜你喜欢
    • 2016-11-11
    • 2018-04-28
    • 2012-04-02
    • 1970-01-01
    • 1970-01-01
    • 2016-10-24
    • 1970-01-01
    • 1970-01-01
    • 2013-03-14
    相关资源
    最近更新 更多