为啥将张量对象更改为 tf.constant 有效
Posted
技术标签:
【中文标题】为啥将张量对象更改为 tf.constant 有效【英文标题】:why changing the tensor object to tf.constant works为什么将张量对象更改为 tf.constant 有效 【发布时间】:2019-11-01 15:31:49 【问题描述】:我有两个代码,它们做同样的事情,但输出不同。
这是第一个代码:
import tensorflow as tf
tf.reset_default_graph()
input_tf = tf.Variable([ [9.968594, 8.655439, 0., 0. ],
[0., 8.3356, 0., 8.8974 ],
[0., 0., 6.103182, 7.330564 ],
[6.609862, 0., 3.0614321, 0. ],
[9.497023, 0., 3.8914037, 0. ],
[0., 8.457685, 8.602337, 0. ],
[0., 0., 5.826657, 8.283971 ],
[0., 0., 0., 0. ]])
rows_tf = tf.constant (
[[1, 2, 5],
[1, 2, 5],
[1, 2, 5],
[1, 4, 6],
[1, 4, 6],
[2, 3, 6],
[2, 3, 6],
[2, 4, 7]])
columns_tf = tf.constant(
[[1],
[2],
[3],
[2],
[3],
[2],
[3],
[2]])
rows_tf = tf.reshape(rows_tf, shape=[-1, 1])
print(rows_tf.shape)
columns_tf = tf.reshape(
tf.tile(columns_tf, multiples=[1, 3]),
shape=[-1, 1])
print(columns_tf.shape)
sparse_indices = tf.reshape(
tf.concat([rows_tf, columns_tf], axis=-1),
shape=[-1, 2])
print(sparse_indices.shape)
v = tf.gather_nd(input_tf, sparse_indices)
v = tf.reshape(v, [-1, 3])
print(rows_tf.shape) (8,3)
print(columns_tf.shape) (8,1)
print(rows_tf.shape) (24,1)
print(columns_tf.shape) (24,1)
这给了我想要的输出:
[[8.3356 0. 8.457685 ]
[0. 6.103182 8.602337 ]
[8.8974 7.330564 0. ]
[0. 3.8914037 5.826657 ]
[8.8974 0. 8.283971 ]
[6.103182 3.0614321 5.826657 ]
[7.330564 0. 8.283971 ]
[6.103182 3.8914037 0. ]], shape=(8, 3), dtype=float32)
我有另一个代码是计算“rows_tf”和“columns_tf”的过程。
所以,rows_tf
和 columns_tf
不是常数,而是其他计算的结果(它们的形状和值相同)。
这是我的代码的第二部分,它没有给出上面的代码:
import tensorflow as tf
tf.enable_eager_execution()
n = 2
tf_a1 = tf.Variable([ [9.968594, 8.655439, 0., 0. ],
[0., 8.3356, 0., 8.8974 ],
[0., 0., 6.103182, 7.330564 ],
[6.609862, 0., 3.0614321, 0. ],
[9.497023, 0., 3.8914037, 0. ],
[0., 8.457685, 8.602337, 0. ],
[0., 0., 5.826657, 8.283971 ]])
tf_a2 = tf.constant([[2, 5, 1],
[1, 6, 4],
[0, 0, 0],
[2, 3, 6],
[4, 2, 4]])
N, M = tf_a1.shape
input_tf = tf.concat([tf_a1, tf.zeros((1, tf_a1.shape[1]), tf_a1.dtype)], axis=0)
tf_a2 = tf.sort(tf_a2, axis=1)
first_col_change = tf.zeros([tf_a2.shape[0], 1], dtype=tf.int32)
last_cols_change = tf.cast(tf.equal(tf_a2[:, 1:], tf_a2[:, :-1]), tf.int32)
change_bool = tf.concat([first_col_change, last_cols_change], axis=-1)
not_change_bool = 1 - change_bool
tf_a2_changed = tf_a2 * not_change_bool + change_bool * N
# y,x = tf.where(tf.count_nonzero(a1p[a2], axis=1) >= n)
idx = tf.where(tf.count_nonzero(tf.gather(input_tf, tf_a2_changed, axis=0), axis=1) >= n)
x, y = idx[:, 0], idx[:, 1]
rows_tf = tf.gather(tf_a2, y, axis=0)
columns_tf = tf.cast(x[:, None],tf.int32)
out = tf.Variable(tf.zeros_like(input_tf, dtype=tf.int32))
rows_tf = tf.reshape(rows_tf, shape=[-1, 1])
columns_tf = tf.reshape(
tf.tile(columns_tf, multiples=[1, 3]),
shape=[-1, 1])
sparse_indices = tf.reshape(
tf.concat([rows_tf, columns_tf], axis=-1),
shape=[-1, 2])
v = tf.gather_nd(input_tf, sparse_indices)
v = tf.reshape(v, [-1, 3])
print(v)
print(rows_tf.shape) (8,3)
print(columns_tf.shape) (8,1)
print(rows_tf.shape) (24,1)
print(columns_tf.shape) (24,1)
在这段代码中
rows_tf = tf.Tensor(
[[1 2 5]
[1 2 5]
[1 2 5]
[1 4 6]
[1 4 6]
[2 3 6]
[2 3 6]
[2 4 4]], shape=(8, 3), dtype=int32)
和
columns_tf= tf.Tensor(
[[1]
[2]
[3]
[2]
[3]
[2]
[3]
[2]], shape=(8, 1), dtype=int32)
所以,我的意思是在第一个代码中,我唯一要做的就是创建一个常量张量,而不是包含生成这些张量的代码。那为什么他们的结果不一样呢?
这是这段代码的输出:
tf.Tensor(
[[0. 9.497023 0. ]
[9.968594 9.968594 9.968594]
[0. 6.609862 0. ]
[8.655439 8.655439 8.655439]
[0. 0. 0. ]
[0. 0. 0. ]
[7.330564 0. 8.283971]
[0. 0. 0. ]], shape=(8, 3), dtype=float32)
为什么会发生这种情况?如果您将第一个代码的rows_tf
和columns_tf
更改为constant tensor
,它将给出正确的结果!(我还应该提到第二个代码中的rows_tf
和columns_tf
正是第一个代码中的代码)。在第一个代码中,为了使其可重现,我将张量定义为常量张量。
提前致谢!
【问题讨论】:
您是否打印出rows_tf
和columns_tf
以检查它们在第一个sn-p 中是否实际上相同?因为当我尝试时,它们并不相同。
@ImperishableNight 感谢您的跟进。是的,它们完全相同,我们有两个rows_tf
和columns_tf
。第一个rows_tf
是(8,3),它与常数相同,也是`columns_tf' ia (8,1)。请注意,您应该打印出第一个 rows_tf 和 columns_tf,因为它们与第一个 sn-p 上的常量相同。两个 sn-p 都有第二个。
我只能通过将x, y = idx[:, 0], idx[:, 1]
更改为y, x = idx[:, 0], idx[:, 1]
来使它们相同。有问题吗?
当我将 x, y
更改为 y, x
时,我得到了正确的输出(与第一个 sn-p 的输出相同)。
谢谢,我已经用有关第二个代码的一些信息更新了我的问题。以及 rows_tf 和 columns_tf 的形状。所以正确的sn-p在问题中,x
和y
不应该改变,问题的目的是这里的冲突是什么。
【参考方案1】:
问题中的第二个 sn-p 是错误的,它没有为 rows_tf
和 columns_tf
提供相同的值。问题是这一行:
x, y = idx[:, 0], idx[:, 1]
应该是:
y, x = idx[:, 0], idx[:, 1]
进行此更正后,sn-p 会给出rows_tf
和columns_tf
的正确值,以及正确的最终答案。
【讨论】:
以上是关于为啥将张量对象更改为 tf.constant 有效的主要内容,如果未能解决你的问题,请参考以下文章