为什么将张量对象更改为tf.constant有效

时间:2019-06-18 23:51:27

标签: python tensorflow slice

我有两个代码,它们在做同样的事情,但是输出却不同。

这是第一个代码:

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_tfcolumns_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_tfcolumns_tf更改为constant tensor,它将给出正确的结果!(我还要在其中提到rows_tfcolumns_tf第二个代码正是第一个代码中的代码)。在第一个代码中,为了使其具有可重现性,我将张量定义为恒定张量。

提前谢谢!

1 个答案:

答案 0 :(得分:1)

问题中的第二个片段是错误的,它没有为rows_tfcolumns_tf提供相同的值。问题是这一行:

x, y = idx[:, 0], idx[:, 1]

应该是:

y, x = idx[:, 0], idx[:, 1]

进行此更正后,代码段将为rows_tfcolumns_tf给出正确的值,并给出正确的最终答案。