在 Tensorflow 中逐行处理张量
Row by row processing on tensor in Tensorflow
我正在测试逐行处理张量的代码。
张量可能有最后 4 个元素为 0 或非零值的行。
如果该行的最后 4 个元素为 0 [1.0,2.0,2.3,3.4,0,0,0,0]
最后四个被删除,形状更改为行中的 5 个元素。
第一个元素表示行索引。它变成了 [0.0,1.0,2.0,2.3,3.4].
如果该行的所有8个元素都具有非零值,则拆分成两行并将行索引放在第一位。那么 [3.0,4.0,1.0,2.1,1.2,1.4,1.2,1.5]
就变成了 [[2.0,3.0,4.0,1.0,2.1],[2.0,1.2,1.4,1.2,1.5]]
。第一个元素 2.0 是张量中的行索引。
所以经过处理
[[1.0,2.0,2.3,3.4,0,0,0,0],[2.0,3.2,4.2,4.0,0,0,0,0],[3.0,4.0,1.0,2.1,1.2,1.4,1.2,1.5],[1.2,1.3,3.4,4.5,1,2,3,4]]
变为
[[0,1.0,2.0,2.3,3.4],[1.0,2.0,3.2,4.2,4.0],[2.0,3.0,4.0,1.0,2.1],[2.0,1.2,1.4,1.2,1.5],[3.0,1.2,1.3,3.4,4.5],[3.0,1,2,3,4]]
我做了如下操作。但是error as TypeError: TypeErro...pected',) at map_fn
.
import tensorflow as tf
boxes = tf.constant([[1.0,2.0,2.3,3.4,0,0,0,0],[2.0,3.2,4.2,4.0,0,0,0,0],[3.0,4.0,1.0,2.1,1.2,1.4,1.2,1.5],[1.2,1.3,3.4,4.5,1,2,3,4]])
rows = tf.expand_dims(tf.range(tf.shape(boxes)[0], dtype=tf.int32), 1)
def bbox_organize(box, i):
if(tf.reduce_sum(box[4:]) == 0):
box=tf.squeeze(box, [5,6,7]
box=tf.roll(box, shift=1, axis=0)
box[0]=i
else:
box=tf.reshape(box, [2, 4])
const_=tf.constant(i, shape=[2, 1])
box=tf.concat([const_, box], 0)
return box
b_boxes= tf.map_fn(lambda x: (bbox_organize(x[0], x[1]), x[1]), (boxes, rows), dtype=(tf.int32, tf.int32))
with tf.Session() as sess: print(sess.run(b_boxes))
我不擅长Tensorflow,还在学习中。
是否有更好的方法实现 Tensorflow api 来处理它?
你需要做的是变换boxes
的形状并得到非零线
import tensorflow as tf
tf.enable_eager_execution();
boxes = tf.constant([[1.0,2.0,2.3,3.4,0,0,0,0],[2.0,3.2,4.2,4.0,0,0,0,0],[3.0,4.0,1.0,2.1,1.2,1.4,1.2,1.5],[1.2,1.3,3.4,4.5,1,2,3,4]])
boxes = tf.reshape(boxes,[tf.shape(boxes)[0]*2,-1])
# [[1. 2. 2.3 3.4]
# [0. 0. 0. 0. ]
# [2. 3.2 4.2 4. ]
# [0. 0. 0. 0. ]
# [3. 4. 1. 2.1]
# [1.2 1.4 1.2 1.5]
# [1.2 1.3 3.4 4.5]
# [1. 2. 3. 4. ]]
rows = tf.floor(tf.expand_dims(tf.range(tf.shape(boxes)[0]), 1)/2)
# [[0.]
# [0.]
# [1.]
# [1.]
# [2.]
# [2.]
# [3.]
# [3.]]
add_index = tf.concat([tf.cast(rows,tf.float32),boxes],-1)
index = tf.not_equal(tf.reduce_sum(add_index[:,4:],axis=1),0)
# [ True False True False True True True True]
boxes_ = tf.gather_nd(add_index,tf.where(index))
print(boxes_)
# tf.Tensor(
# [[0. 1. 2. 2.3 3.4]
# [1. 2. 3.2 4.2 4. ]
# [2. 3. 4. 1. 2.1]
# [2. 1.2 1.4 1.2 1.5]
# [3. 1.2 1.3 3.4 4.5]
# [3. 1. 2. 3. 4. ]], shape=(6, 5), dtype=float32)
我觉得你更需要上面的代码。矢量化方法将明显快于 tf.map_fn()
.
我正在测试逐行处理张量的代码。
张量可能有最后 4 个元素为 0 或非零值的行。
如果该行的最后 4 个元素为 0 [1.0,2.0,2.3,3.4,0,0,0,0] 最后四个被删除,形状更改为行中的 5 个元素。 第一个元素表示行索引。它变成了 [0.0,1.0,2.0,2.3,3.4].
如果该行的所有8个元素都具有非零值,则拆分成两行并将行索引放在第一位。那么 [3.0,4.0,1.0,2.1,1.2,1.4,1.2,1.5]
就变成了 [[2.0,3.0,4.0,1.0,2.1],[2.0,1.2,1.4,1.2,1.5]]
。第一个元素 2.0 是张量中的行索引。
所以经过处理
[[1.0,2.0,2.3,3.4,0,0,0,0],[2.0,3.2,4.2,4.0,0,0,0,0],[3.0,4.0,1.0,2.1,1.2,1.4,1.2,1.5],[1.2,1.3,3.4,4.5,1,2,3,4]]
变为
[[0,1.0,2.0,2.3,3.4],[1.0,2.0,3.2,4.2,4.0],[2.0,3.0,4.0,1.0,2.1],[2.0,1.2,1.4,1.2,1.5],[3.0,1.2,1.3,3.4,4.5],[3.0,1,2,3,4]]
我做了如下操作。但是error as TypeError: TypeErro...pected',) at map_fn
.
import tensorflow as tf
boxes = tf.constant([[1.0,2.0,2.3,3.4,0,0,0,0],[2.0,3.2,4.2,4.0,0,0,0,0],[3.0,4.0,1.0,2.1,1.2,1.4,1.2,1.5],[1.2,1.3,3.4,4.5,1,2,3,4]])
rows = tf.expand_dims(tf.range(tf.shape(boxes)[0], dtype=tf.int32), 1)
def bbox_organize(box, i):
if(tf.reduce_sum(box[4:]) == 0):
box=tf.squeeze(box, [5,6,7]
box=tf.roll(box, shift=1, axis=0)
box[0]=i
else:
box=tf.reshape(box, [2, 4])
const_=tf.constant(i, shape=[2, 1])
box=tf.concat([const_, box], 0)
return box
b_boxes= tf.map_fn(lambda x: (bbox_organize(x[0], x[1]), x[1]), (boxes, rows), dtype=(tf.int32, tf.int32))
with tf.Session() as sess: print(sess.run(b_boxes))
我不擅长Tensorflow,还在学习中。
是否有更好的方法实现 Tensorflow api 来处理它?
你需要做的是变换boxes
的形状并得到非零线
import tensorflow as tf
tf.enable_eager_execution();
boxes = tf.constant([[1.0,2.0,2.3,3.4,0,0,0,0],[2.0,3.2,4.2,4.0,0,0,0,0],[3.0,4.0,1.0,2.1,1.2,1.4,1.2,1.5],[1.2,1.3,3.4,4.5,1,2,3,4]])
boxes = tf.reshape(boxes,[tf.shape(boxes)[0]*2,-1])
# [[1. 2. 2.3 3.4]
# [0. 0. 0. 0. ]
# [2. 3.2 4.2 4. ]
# [0. 0. 0. 0. ]
# [3. 4. 1. 2.1]
# [1.2 1.4 1.2 1.5]
# [1.2 1.3 3.4 4.5]
# [1. 2. 3. 4. ]]
rows = tf.floor(tf.expand_dims(tf.range(tf.shape(boxes)[0]), 1)/2)
# [[0.]
# [0.]
# [1.]
# [1.]
# [2.]
# [2.]
# [3.]
# [3.]]
add_index = tf.concat([tf.cast(rows,tf.float32),boxes],-1)
index = tf.not_equal(tf.reduce_sum(add_index[:,4:],axis=1),0)
# [ True False True False True True True True]
boxes_ = tf.gather_nd(add_index,tf.where(index))
print(boxes_)
# tf.Tensor(
# [[0. 1. 2. 2.3 3.4]
# [1. 2. 3.2 4.2 4. ]
# [2. 3. 4. 1. 2.1]
# [2. 1.2 1.4 1.2 1.5]
# [3. 1.2 1.3 3.4 4.5]
# [3. 1. 2. 3. 4. ]], shape=(6, 5), dtype=float32)
我觉得你更需要上面的代码。矢量化方法将明显快于 tf.map_fn()
.