我不确定下面4种变体之间的实际差异(它们都评估为相同的值)。我的理解是,如果我致电select
a.id, a.total_price, a.order_id, c.id
from (select *, row_number over (partition by order_id order by id) as rn from a) a
join b on a.order_id = b.id
join (select id, order_id, row_number over (partition by order_id order by id) as rn from c) on b.id = c.order_id
where a.rn = c.rn
,将在图表上创建操作,否则可能。如果我不在开头创建tf
,我相信在添加时会隐式创建常量;但对于tf.constant()
vs tf.add(a,b)
,其中a + b
和a
都是张量(#1和#3),除了默认命名之外我没有看到任何区别(前者是{{ 1}}而后者是b
)。任何人都可以了解它们之间的差异,何时应该使用它们?
Add
答案 0 :(得分:17)
您给出的四个示例都会给出相同的结果,并生成相同的图形(如果忽略图形中的某些操作名称不同)。 TensorFlow将许多不同的Python对象转换为tf.Tensor
对象,当它们作为参数传递给TensorFlow运算符时,例如tf.add()
。 +
运算符只是tf.add()
上的一个简单包装器,当左侧或右侧参数为tf.Tensor
(或tf.Variable
)时使用重载
鉴于您可以将许多Python对象传递给TensorFlow运算符,为什么要使用tf.constant()
?有几个原因:
如果您使用相同的Python对象作为多个不同操作的参数,TensorFlow会将其多次转换为张量,并代表图中的每个张量。因此,如果您的Python对象是一个大型NumPy数组,如果您为该数组的数据制作了太多副本,则可能会耗尽内存。在这种情况下,您可能希望将数组转换为tf.Tensor
一次
显式创建tf.constant()
允许您设置其name
属性,这对TensorBoard调试和图形可视化非常有用。 (注意,默认的TensorFlow操作将尝试根据op参数的名称为每个自动转换的张量提供有意义的名称。)
明确地创建tf.constant()
可以设置张量的确切元素类型。 TensorFlow会将Python int
对象转换为tf.int32
,将float
对象转换为tf.float32
。如果您需要tf.int64
或tf.float64
,可以通过将相同的值传递给tf.constant()
并传递明确的dtype
参数来获得此结果。
在创建具有重复值的大张量时,tf.constant()
函数还提供了一个有用的功能:
c = tf.constant(17.0, shape=[1024, 1024], dtype=tf.float32)
上面的张量c
表示4 * 1024 * 1024字节的数据,但TensorFlow将在图中紧凑地表示为单个浮点17.0
以及指示应如何解释它的形状信息。如果图表中有许多大的填充常量,那么以这种方式创建它们会更有效。
答案 1 :(得分:2)
他们都是一样的。
python - a + b中的'+'由tensorflow捕获,实际上生成与tf.add(a,b)相同的操作。
tf.conctant允许您更具体,例如定义创建的张量的形状,类型和名称。但是,tensorflow再次拥有你的例子中的“a”a = 1,它等同于tf.constant(1)(在这种情况下将常量视为int值)
答案 2 :(得分:2)
结果是相同的,因为add
的重载__add__
或+
在其操作数上调用tf.convert_to_tensor
。
tf.add(a + b)
和a + b
之间的区别在于前者使您能够使用name
参数为操作命名。相反,后者并没有给你这种能力,也使得在Tensorflow环境中计算由Python解释器而不是在它之外完成。
如果(且仅当)a
和b
都不是Tensor
个对象,则会发生这种情况,因此Tensorflow将不参与计算。