python - 为什么`tf.tile`通过所有副本传播梯度?
问题描述
我试图具体了解 Tensorflow 如何通过函数传播梯度tf.tile
。我想做的很简单:
""" Considering batch_size = 3: """
# CASE 1:
a = tf.constant([[[1., 1.5], [2., 2.5], [3., 3.5]], [[4, 4.5], [5, 5.5], [6, 6.5]], [[7, 7.5], [8., 8.5], [9., 9.5]]]) # shape [3, 3, 2]
b = tf.constant([[[0.1], [0.2], [0.3]], [[0.4], [0.5], [0.6]], [[0.7], [0.8], [0.9]]]) # shape [3, 3, 1]
""" What I want is c = a + b, so I tile b to match last dimension of a: """
b_tile = tf.tile(b, [1, 1, tf.shape(a)[-1]]) # shape [3, 3, 2]
c = a + b_tile # shape [3, 3, 2]
现在让我们计算c
关于a
和的梯度b_tile
:
dc_da, dc_dbtile = tf.gradients(c, [a, b_tile])
# dc_da: tensor with same shape as a and all elements 1.
# dc_dbtile: tensor with same shape as b and all elements 1.
这是完全有道理的,因为我有一个线性关系:c = a + b_tile
. 但是,当我计算b_tile
wrt的梯度时b
,我希望梯度也是1.
如此,因为我没有更改 的内部值b
,只需扩展维度。但是当我这样做时,它会给出2.
结果:
dbtile_db = tf.gradients(b_tile, [b])
# dbtile_db: tensor with same shape as b and all elements equal 2.
我也尝试过b
两次连接张量而不是使用tf.tile
,它给出了相同的结果,所以很明显我遗漏了一些东西。
我试过用另一个例子来检查它的来源。现在让我们考虑另一个t
具有完全相同值的张量b
,让我们将它们连接起来以获得我需要的张量。在这种情况下:
# CASE 2:
m = tf.concat([b, t], -1) # shape [3, 3, 2]. Tensor identical to b_tile
dm_db, dm_dt = tf.gradients(m, [b, t])
# dm_db: tensor with same shape as b and all elements equal 1.
# dm_dt: tensor with same shape as t and all elements equal 1.
所以我有几个问题:
1)我不明白为什么使用tf.tile
梯度会传播到所有副本,而它们只是能够计算总和的工具。从数值上讲,这对我来说没有意义,我希望渐变像最后一种情况一样传播。
2)案例1和案例2之间有什么区别(就梯度而言)?当我尝试做的事情相同时,为什么它会产生不同的结果?
3)考虑到我想计算总和c = a + b
,正确的方法是什么?
问题是,在示例中,我的最后一个维度是2
,所以我可以手动(连接)购买我真正的问题,我的最后一个维度是256000
,所以我不能用最后一种方式来做。先感谢您
解决方案
推荐阅读
- wordpress - 在树枝模板中调用 woocommerce 函数两次
- sql-server - 我有两个表我想从 SQL 的同一列中检索不同的结果
- amazon-lightsail - aws Lightsail Connexion 被服务器拒绝
- android - minSdkVersion vs targetSdkVersion vs maxSdkVersion
- autohotkey - 创建 ahk 睡眠定时器快速编辑
- python - 我发现此错误“NoneType”对象不可迭代
- java - OpenGL非常大的网格裁剪
- javascript - 从一种方法到另一种方法使用变量
- javascript - 立即在服务中设置使用脚本 API 创建的用户的密码
- ios - 如何制作具有动态类型支持的应用程序?