我正在尝试将使用的网络从使用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)
答案 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的所有细节了-如果您询问我,这是一个很好的补充。但是,这似乎仍在积极开发中,因此在积极地将其用于(面向未来的)开发中之前,我会仔细阅读它。