TensorFlow的卷积层:区分不同conv2d APIs

最近本菜折腾起了TensorFlow,在折腾到卷积层这个环节的时候有许多的疑惑。

不同的API,傻傻分不清楚

TensorFlow的卷积层API有很多个,tf.nn.conv2d(), tf.layers.conv2d(), tf.contrib.layers.conv2d(), tf.contrib.slim.conv2d(), tf.keras.layers.Conv2D()等。还有很多我没有列举出来的。

首先tf.contrib模块是TensorFlow 1.x才有的,TensorFlow 2.x已经弃用了这个模块,因为“contrib模块的成长,超出了TensorFlow团队 (在一个repo里) 能维护的范围。”量子位:TensorFlow2.0要来了,tf.contrib要砍了

但是TensorFlow 1的其他内容可以在tensorflow.compat.v1里面找到,并且在2.x的生命周期里,会得到持续的维护。因此,结论是如果安装的是TensorFlow 2.x,而教学书上的、网上的代码是按TensorFlow 1.x写的话,运行的时候大概率会报各种没有这个模块、没有这个方法之类的错误,这个时候换成tensorflow.compat.v1即可。具体import方法可以是:

但是如果代码里面有tf.contrib的话,这个方法就行不通了。我就是在寻找替代方案的过程中发现了有那么多conv2d相关的方法。因此需要记录一下它们的区别。

(1) tf.contrib.layers.conv2d() & tf.contrib.slim.conv2d()

刚刚提到,这个方法只有在1.x里面有。方法的参数定义可以参见 TensorFlow: tf.contrib.layers.conv2d

inputs:该卷积层的输入。A Tensor of rank N+2 of shape [batch_size] + input_spatial_shape + [in_channels]
num_outputs:等于卷积核/滤波器的个数,跟其他方法的filters是一样的。
kernel_size:卷积核大小。
stride:步长。
padding:One of VALID or SAME. 默认VALID
activation_fn:激活函数。默认tf.nn.relu
weights_initializer:权重初始化器。默认initializers.xavier_initializer()
biases_initializer:偏差初始化器。

具体的使用例子:

tf.contrib.slim.conv2d()tf.contrib.layers.conv2d()是一模一样的。另外,tf.contrib.layers.conv2d()tf.contrib.layers.Conv2D()tf.contrib.layers.convolution2d()都是一样的,详见上面的官方API说明。

(2) tf.layers.conv2d()

这个方法可以作为tf.contrib.layers.conv2d()tf.contrib.slim.conv2d()在TensorFlow 2.x下的替代(2.x在tensorflow.compat.v1中)。但是需要小心的是对应参数的Keyword有了变化。 TensorFlow: tf.compat.v1.layers.conv2d

inputs:一致。
filters:即num_outputs
kernel_size:一致。
strides:即stride
padding:One of VALID or SAME. 默认SAME
activation:即activation_fn默认None
kernel_initializer:即weights_initializer默认None
biases_initializer:即biases_initializer

因此除了需要注意参数的Keyword发生了变化,更需要注意的是参数默认值的变化。不注意这个的话会付出惨痛的代价,本人已经亲身经历了。把tf.contrib.layers.convolution2d()换成tf.layers.conv2d()之后死活不收敛,最后发现这俩货的激活函数和初始化器的默认值是不一样的,如果没有特别指定,这两个方法得到的效果就会完全不一样。

(3) tf.nn.conv2d()

这是一个底层方法,需要指定卷积核且只完成把图像与卷积核卷积的操作。上面的方法都是tf.nn.conv2d()的高级封装。

(4) tf.keras.layers.Conv2D()

同样是tf.nn.conv2d()的高级封装。与(1)(2)方法不同的地方是使用方法不同。但是参数的Keyword和默认值与tf.layers.conv2d()是类似的(略有不同,具体看文档)。TensorFlow: tf.keras.layers.Conv2D

使用方法上有较大不同。上一层的输出放的位置不同。

债见

Leave a Comment