2017-08-24 28 views
0

我想根據特定的軸提取tensorflow張量中'真'的索引。如何在基於軸的Tensorflow中獲得「真」值的指示?

期望值

[[真,假,TRUE,FALSE],

[FALSE,FALSE,TRUE,FALSE]]

[[0,2],

[2]]

我發現

'tf.where' 

類似於我所期待的,但

當我使用這個函式,結果是

[0,0] , [0,2], [1,2]],

有什麼辦法根據特定軸獲得'真'值的索引?

回答

1

這應該給你,你找什麼 -

import tensorflow as tf 

b = tf.constant([[True, False, True, False],[ False, False, True, False]]) 
x=tf.unstack(b) 
c = [tf.squeeze(tf.where(e)) for e in x] 

init_op = tf.global_variables_initializer() 

with tf.Session() as sess: 
    sess.run(init_op) 
    print(sess.run([c])) 

這個編輯是在以前的版本我的回答chrert的評論啓發。該解決方案實際上並不需要一個人來指定軸,我已經修改它以反映這一點(然而,它的軸= 0,這可能被認爲是限制性的)。他是正確的,tf.while_loop和TensorArrays一起可以讓你循環任何給定形狀的張量,而不必事先知道它的形狀;而且它也很好地知道如何使用動態形狀張量來處理!但是,對於bj1123的特定用例,嘗試堆疊結果時可能會失敗。這是因爲每個行或切片都可以(並且很可能會!!)具有不同的True和False值。這將引發錯誤「InvalidArgumentError(請參閱上面的回溯):TensorArray具有不一致的形狀。」爲了量化什麼,我想說 -

import tensorflow as tf 
import numpy as np 



inputs = tf.placeholder(dtype=tf.bool, shape=(2,4)) 
time_steps = tf.shape(inputs)[0] 
initial_outputs = tf.TensorArray(dtype=tf.int32, size=time_steps) 
initial_t = tf.placeholder(dtype='int32') 

def cond(t, *args): 
    return t < time_steps 

def body(t, outputs_): 
    sub = tf.gather(inputs, t) 
    cur = tf.squeeze(tf.cast(tf.where(sub), tf.int32)) 
    outputs_ = outputs_.write(t, cur) 
    return t + 1, outputs_ 

t, outputs = tf.while_loop(cond, body,[initial_t, initial_outputs]) 

outputs = outputs.stack() 
with tf.Session() as sess: 
    init = tf.global_variables_initializer() 
    sess.run([init]) 
    print(outputs) 
    print(sess.run([outputs], feed_dict={inputs: np.asarray([[True,False,True,False],[True, True, False, False]]), initial_t:0})) 

上面的代碼將會運行得很好,現在嘗試用

np.asarray([[True,True,True,False],[True, True, False, False]]) 

來替代佔位符,現在你可以看到錯誤。似乎沒有任何將不規則形狀張量堆疊成單張量的直接方式。唯一的辦法是有張量表,如我的第一個版本所示。 我也編輯了

+0

也許你應該提到,如果軸的尺寸在圖構造中是已知的,那麼這隻會起作用。也許有可能用tf.TensorArray和tf.while_loop實現類似的動態尺寸張量。 – chrert