tf.layers.separable_conv2d实现深度可分卷积

我们先回忆一下普通的卷积操纵,对于一个输入张量,[N,H,W,C]分别表示图片数目、图片高度、宽度和通道数,如果我们设定卷积核[H_kernal,W_kernal,C_in,C_out]分别表示卷积核的高度、宽度、输入通道数也就是卷积核厚度、输出通道数也就是卷积数目。通常卷积核的厚度是等于图片通道数的,也就是说一个卷积核可以是把一片区域内的所有通道都包住。所以平时卷积函数里面写kernal_size都只有[H_kernal,W_kernal]两个参数,因为厚度默认是图片的通道数了,输出通道数也就是卷积核数量会单独作为一个参数设置。例如函数:

tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, data_format=None, name=None)
其中的:filter——是输出通道数目,即卷积核的个数。kernel_size: 两个整数的元组或列表,表示卷积核在高、宽尺寸。
而卷积核的厚度是多少呢?函数已经帮你设置好了,就是按照输入张量的通道数来的。

但是,我们的可分卷积就不一样了,它比较复杂,是由一个depthwise卷积再接一个pointwise卷积完成的。

对depthwise卷积,它的卷积核厚度不是输入张量的通道数,而是1,这个也是函数帮你设置好的。通俗地理解就是卷积核厚度只有一层,然后在输入张量上一层一层地滑动,所以一个卷积核就对应了num_channel_in个输出通道,所以总的输出通道数是num_channel_in*depth_multiple。而pointwise卷积其实就是一个1*1卷积,它的卷积核厚度是num_channel_in*depth_multiple,这就很好了,最终函数的输出通道由filter决定。

所以说,饶了半天,哪怕您压根就不知道什么depthwise卷积、pointwise卷积,您就记住一条,函数输出通道就是filter数目。

tf.layers.separable_conv2d(
    inputs,
    filters,
    kernel_size,
    strides=(1, 1),
    padding='valid',
    data_format='channels_last',
    dilation_rate=(1, 1),
    depth_multiplier=1,
    activation=None,
    use_bias=True,
    depthwise_initializer=None,
    pointwise_initializer=None,
    bias_initializer=tf.zeros_initializer(),
    depthwise_regularizer=None,
    pointwise_regularizer=None,
    bias_regularizer=None,
    activity_regularizer=None,
    depthwise_constraint=None,
    pointwise_constraint=None,
    bias_constraint=None,
    trainable=True,
    name=None,
    reuse=None
)

关键参数说明:

inputs: 输入张量.
filters:输出通道数目,即卷积核的个数。
kernel_size: 两个整数的元组或列表,表示卷积核在高、宽尺寸。这个卷积核尺寸是参加depthwise卷积时采用的。用法和普通卷积核没区别。
strides: 两个整数的元组或列表,表示卷积核在高、宽上移动的步长。padding: "valid" 或"same" depth_multiplier: 通道扩大倍数.其他参数一般为默认值
 
 


函数的官方说明:tf.layers.separable_conv2d

猜你喜欢

转载自blog.csdn.net/qq_33278989/article/details/80265657
今日推荐