tf.layers.conv2d和tf.contrib.slim.conv2d之间的区别

时间:2018-09-11 00:57:17

标签: python tensorflow neural-network deep-learning conv-neural-network

我正在尝试将使用的网络从使用tf-slim的conv2d转换为使用tf.layers.conv2d,因为看起来tf.layers是更受支持且面向未来的选项。函数签名非常相似,但是两者在算法上有什么不同?我得到的输出张量尺寸与预期不同。

x = tf.layers.conv2d(inputs=x,
                     filters=256,
                     kernel_size=[3,3],
                     trainable=True)

与此相反:

x = slim.conv2d(x, 256, 3)

2 个答案:

答案 0 :(得分:6)

  

我得到的输出张量尺寸与预期的不同。

这是由于以下事实:默认情况下,slim.conv2d使用相同的填充,而tf.layers.conv2d使用有效的填充。

如果您想重现完全相同的行为,这是正确的实现:

g(n) = O(f(n))

答案 1 :(得分:3)

description of the tf.slim package为区别提供了更多信息: 具体来说,如果您在“层”下查看,则会发现以下内容:

  

     

虽然TensorFlow操作集非常广泛,但开发人员   的神经网络通常以更高的层次来考虑模型   诸如“层”,“损耗”,“度量”和“网络”之类的概念。一层,   例如卷积层,完全连接层或BatchNorm   层比单个TensorFlow操作更抽象,并且   通常涉及多个操作。此外,通常一层   (但并非总是)具有与以下内容相关联的变量(可调参数)   它,而不是更原始的操作。例如卷积   神经网络中的层由几个底层操作组成:

     
      
  • 创建权重和偏差变量
  •   
  • 将权重与上一层的输入进行卷积
  •   
  • 在卷积结果中添加偏差。
  •   
  • 应用激活功能。
  •   
     

仅使用普通的TensorFlow代码,这可能会很费力:

input = ...
with tf.name_scope('conv1_1') as scope:
  kernel = tf.Variable(tf.truncated_normal([3, 3, 64, 128], dtype=tf.float32,
                                           stddev=1e-1), name='weights')
  conv = tf.nn.conv2d(input, kernel, [1, 1, 1, 1], padding='SAME')
  biases = tf.Variable(tf.constant(0.0, shape=[128], dtype=tf.float32),
                       trainable=True, name='biases')
  bias = tf.nn.bias_add(conv, biases)
  conv1 = tf.nn.relu(bias, name=scope)
     

为减轻重复重复此代码的需要,TF-Slim   提供了更多定义的便捷操作   神经网络层的抽象级别。例如,比较代码   以上是对相应TF-Slim代码的调用:

input = ...
net = slim.conv2d(input, 128, [3, 3], scope='conv1_1')

简而言之,slim运算符可以为您做一些简洁的抽象,这样您就不必担心TensorFlow的所有细节了-如果您询问我,这是一个很好的补充。但是,这似乎仍在积极开发中,因此在积极地将其用于(面向未来的)开发中之前,我会仔细阅读它。