天天看点

tensorflow 中的深度可分离卷积接口 slim.separable_conv2d()

    我在前面的一篇博客 深入浅出谈谈深度可分离卷积 中介绍了深度可分离卷积的原理,然后用 tensorflow 实现了下。

    在 tensorflow 中的接口是 slim.separable_conv2d(),接口说明:

def separable_convolution2d(
    inputs,
    num_outputs,
    kernel_size,
    depth_multiplier=1,
    stride=1,
    padding='SAME',
    data_format=DATA_FORMAT_NHWC,
    rate=1,
    activation_fn=nn.relu,
    normalizer_fn=None,
    normalizer_params=None,
    weights_initializer=initializers.xavier_initializer(),
    pointwise_initializer=None,
    weights_regularizer=None,
    biases_initializer=init_ops.zeros_initializer(),
    biases_regularizer=None,
    reuse=None,
    variables_collections=None,
    outputs_collections=None,
    trainable=True,
    scope=None):
  """一个2维的可分离卷积,可以选择是否增加BN层。
  这个操作首先执行逐通道的卷积(每个通道分别执行卷积),创建一个称为depthwise_weights的变量。如果num_outputs
不为空,它将增加一个pointwise的卷积(混合通道间的信息),创建一个称为pointwise_weights的变量。如果
normalizer_fn为空,它将给结果加上一个偏置,并且创建一个为biases的变量,如果不为空,那么归一化函数将被调用。
最后再调用一个激活函数然后得到最终的结果。
  Args:
    inputs: 一个形状为[batch_size, height, width, channels]的tensor
    num_outputs: pointwise 卷积的卷积核个数,如果为空,将跳过pointwise卷积的步骤.
    kernel_size: 卷积核的尺寸:[kernel_height, kernel_width],如果两个的值相同,则可以为一个整数。
    depth_multiplier: 卷积乘子,即每个输入通道经过卷积后的输出通道数。总共的输出通道数将为:
num_filters_in * depth_multiplier。
    stride:卷积步长,[stride_height, stride_width],如果两个值相同的话,为一个整数值。
    padding:  填充方式,'VALID' 或者 'SAME'.
    data_format:数据格式, `NHWC` (默认) 和 `NCHW` 
    rate: 空洞卷积的膨胀率:[rate_height, rate_width],如果两个值相同的话,可以为整数值。如果这两个值
任意一个大于1,那么stride的值必须为1.     
    activation_fn: 激活函数,默认为ReLU。如果设置为None,将跳过。
    normalizer_fn: 归一化函数,用来替代biase。如果归一化函数不为空,那么biases_initializer
和biases_regularizer将被忽略。 biases将不会被创建。如果设为None,将不会有归一化。
    normalizer_params: 归一化函数的参数。
    weights_initializer: depthwise卷积的权重初始化器
    pointwise_initializer: pointwise卷积的权重初始化器。如果设为None,将使用weights_initializer。
    weights_regularizer: (可选)权重正则化器。
    biases_initializer: 偏置初始化器,如果为None,将跳过偏置。
    biases_regularizer: (可选)偏置正则化器。
    reuse: 网络层和它的变量是否可以被重用,为了重用,网络层的scope必须被提供。
    variables_collections: (可选)所有变量的collection列表,或者是一个关键字为变量值为collection的字典。
    outputs_collections: 输出被添加的collection.
    trainable: 变量是否可以被训练
    scope: (可选)变量的命名空间。
  Returns:
    代表这个操作的输出的一个tensor
           

    但是这个接口根据原理来看,我觉得有个缺点,如果设置 depth_multiplier 为1,则变成了单通道的点乘,那这样是否缺乏了通道间的信息融合?

    这样显然能极大程度减少参数,但是网络性能也会受到影响,至少对于low-levle 的 cv 任务来说,性能下降很大。

    如有不对请指正。

继续阅读