Machine learning layer.get_weights()对于可分离卷积层意味着什么?

Machine learning layer.get_weights()对于可分离卷积层意味着什么?,machine-learning,keras,conv-neural-network,layer,efficientnet,Machine Learning,Keras,Conv Neural Network,Layer,Efficientnet,我了解到,我们可以使用函数layer.get_weights()来获取层的权重和偏差。这将返回长度为2的列表。层的权重存储在层。获取权重()[0],偏差存储在层。获取权重()[1](如果在定义层期间未禁用偏差)。正常卷积层也是如此 我最近在EfficientDet模型中使用了可分离卷积层作为我的层之一 layers.SeparableConv2D(num_channels, kernel_size=kernel_size, strides=strides, padding='same',

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

我最近在
EfficientDet模型中使用了可分离卷积层作为我的层之一

layers.SeparableConv2D(num_channels, kernel_size=kernel_size, strides=strides, padding='same',
                            use_bias=True, name=str(name)+"/conv")
当我尝试使用相同的
layer.get_weights()
函数时,它返回了一个
长度3
的列表,我希望它是
2
,这与上面的相同。 在这里,我对列表中的三个值有点困惑。
任何帮助和建议都将不胜感激。

SeparableConv2D
层正在计算深度可分离卷积,与正常卷积不同,它需要2个核(2个权重张量)。在没有太多细节的情况下,它使用第一个内核来计算深度卷积,应用此操作后,它使用第二个内核来计算点态卷积。这背后的主要思想是减少参数的数量,从而减少计算的数量

下面是一个简单的例子。假设我们有输入图像28x28x3(宽度、高度、#通道),并应用正常的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
Layer (type)                 Output Shape              Param #   
=================================================================
separable_conv2d_7 (Separabl (None, 24, 24, 16)        139   
如果我们提取内核参数

print(model.layers[0].get_weights()[0].shape)
这给了我们

(5, 5, 3, 16)

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

print(model.layers[0].get_weights()[0].shape)
逐点内核是一个简单的1x1卷积(它在每个输入点上运行),用于将结果的深度增加到指定的过滤器数量。在我们的例子中是-1x1x16,它提供了48个参数

print(model.layers[0].get_weights()[0].shape)
总的来说,第一个内核有75个参数,第二个内核有48个参数,这给了我们123个参数,再加上16个偏差参数。这是139个参数

print(model.layers[0].get_weights()[0].shape)
在凯拉斯

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 #   
=================================================================
conv2d_4 (Conv2D)            (None, 24, 24, 16)        1216
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)

如果您想了解有关可分离卷积如何工作的详细信息,可以阅读。

谢谢您的详细解释。我相信它对未来的用户也会非常有用。干杯:)