在张量流中,tf.add 和运算符 (+) 有什么区别?
In tensorflow what is the difference between tf.add and operator (+)?
在 tensorflow 教程中,我看到了 tf.add(tf.matmul(X, W), b)
和 tf.matmul(X, W) + b
等代码,使用数学函数 tf.add()
、tf.assign()
等有什么区别以及运算符 +
和 =
等,在精度或其他方面?
a+b
和 tf.add(a, b)
在精度上没有区别。前者转换为 a.__add__(b)
,后者通过 math_ops.py
中的 following line 映射到 tf.add
_OverrideBinaryOperatorHelper(gen_math_ops.add, "add")
唯一的区别是底层 Graph 中的节点名称是 add
而不是 Add
。您通常可以通过查看底层图形表示来比较事物,如下所示
tf.reset_default_graph()
dtype = tf.int32
a = tf.placeholder(dtype)
b = tf.placeholder(dtype)
c = a+b
print(tf.get_default_graph().as_graph_def())
您也可以通过检查 __add__
方法直接看到这一点。多了一层间接,因为是闭包,但是可以通过如下方式获取底层函数
real_function = tf.Tensor.__add__.im_func.func_closure[0].cell_contents
print(real_function.__module__ + "." + real_function.__name__)
print(tf.add.__module__ + "." + tf.add.__name__)
你会看到下面的输出,这意味着它们调用了相同的底层函数
tensorflow.python.ops.gen_math_ops.add
tensorflow.python.ops.gen_math_ops.add
您可以从 tf.Tensor.OVERLOADABLE_OPERATORS
中看出,以下 Python 特殊方法可能会被适当的 TensorFlow 版本重载
{'__abs__',
'__add__',
'__and__',
'__div__',
'__floordiv__',
'__ge__',
'__getitem__',
'__gt__',
'__invert__',
'__le__',
'__lt__',
'__mod__',
'__mul__',
'__neg__',
'__or__',
'__pow__',
'__radd__',
'__rand__',
'__rdiv__',
'__rfloordiv__',
'__rmod__',
'__rmul__',
'__ror__',
'__rpow__',
'__rsub__',
'__rtruediv__',
'__rxor__',
'__sub__',
'__truediv__',
'__xor__'}
这些方法在Python reference 3.3.7:模拟数值类型中进行了描述。请注意,Python 数据模型不提供重载赋值运算符 =
的方法,因此赋值始终使用本机 Python 实现。
Yaroslav 很好地解释说没有真正的区别。我只会在使用 tf.add
有益时添加。
tf.add有一个重要的参数是name
。它允许您在张量板中可见的图表中命名操作。所以我的经验法则是,如果在 tensorboard 中命名一个操作是有益的,我会使用 tf.
等价物,否则我会为了简洁而使用重载版本。
a = [1,1,1,1]
b = [1,1,1,1]
w = tf.add(a, b)
with tf.Session() as sess:
p = sess.run(w)
print(p)
a+b
现在,打印的 p
的值将是 [2,2,2,2]
,打印的简单 a+b
的值将是 [1,1,1,1,1,1,1,1]
.
在 tensorflow 教程中,我看到了 tf.add(tf.matmul(X, W), b)
和 tf.matmul(X, W) + b
等代码,使用数学函数 tf.add()
、tf.assign()
等有什么区别以及运算符 +
和 =
等,在精度或其他方面?
a+b
和 tf.add(a, b)
在精度上没有区别。前者转换为 a.__add__(b)
,后者通过 math_ops.py
tf.add
_OverrideBinaryOperatorHelper(gen_math_ops.add, "add")
唯一的区别是底层 Graph 中的节点名称是 add
而不是 Add
。您通常可以通过查看底层图形表示来比较事物,如下所示
tf.reset_default_graph()
dtype = tf.int32
a = tf.placeholder(dtype)
b = tf.placeholder(dtype)
c = a+b
print(tf.get_default_graph().as_graph_def())
您也可以通过检查 __add__
方法直接看到这一点。多了一层间接,因为是闭包,但是可以通过如下方式获取底层函数
real_function = tf.Tensor.__add__.im_func.func_closure[0].cell_contents
print(real_function.__module__ + "." + real_function.__name__)
print(tf.add.__module__ + "." + tf.add.__name__)
你会看到下面的输出,这意味着它们调用了相同的底层函数
tensorflow.python.ops.gen_math_ops.add
tensorflow.python.ops.gen_math_ops.add
您可以从 tf.Tensor.OVERLOADABLE_OPERATORS
中看出,以下 Python 特殊方法可能会被适当的 TensorFlow 版本重载
{'__abs__',
'__add__',
'__and__',
'__div__',
'__floordiv__',
'__ge__',
'__getitem__',
'__gt__',
'__invert__',
'__le__',
'__lt__',
'__mod__',
'__mul__',
'__neg__',
'__or__',
'__pow__',
'__radd__',
'__rand__',
'__rdiv__',
'__rfloordiv__',
'__rmod__',
'__rmul__',
'__ror__',
'__rpow__',
'__rsub__',
'__rtruediv__',
'__rxor__',
'__sub__',
'__truediv__',
'__xor__'}
这些方法在Python reference 3.3.7:模拟数值类型中进行了描述。请注意,Python 数据模型不提供重载赋值运算符 =
的方法,因此赋值始终使用本机 Python 实现。
Yaroslav 很好地解释说没有真正的区别。我只会在使用 tf.add
有益时添加。
tf.add有一个重要的参数是name
。它允许您在张量板中可见的图表中命名操作。所以我的经验法则是,如果在 tensorboard 中命名一个操作是有益的,我会使用 tf.
等价物,否则我会为了简洁而使用重载版本。
a = [1,1,1,1]
b = [1,1,1,1]
w = tf.add(a, b)
with tf.Session() as sess:
p = sess.run(w)
print(p)
a+b
现在,打印的 p
的值将是 [2,2,2,2]
,打印的简单 a+b
的值将是 [1,1,1,1,1,1,1,1]
.