2016-04-10 21 views
3

テンソル内の要素の数を取得したいとします。たとえば、t = [1,2,0,0,0,0](tはテンソル)、私は、Pythonでt.count(0)を呼び出すことによって '0'の量を得ることができますが、テンソルフローでは、私はこれを行うための関数を見つけることができません。どうすれば '0'のカウントを得ることができますか?誰かが私を助けてくれますか?テンソル内の要素の数を取得する方法

+0

あなたはまた、(https://stackoverflow.com/a/45207218/1090562)[各要素を数える]でき –

答えて

4

現在、テンソルフローに組み込みカウント方法はありません。しかし、次のような方法で既存のツールを使用して行うことができます。

def tf_count(t, val): 
    elements_equal_to_value = tf.equal(t, val) 
    as_ints = tf.cast(elements_equal_to_value, tf.int32) 
    count = tf.reduce_sum(as_ints) 
    return count 
+0

、リターンvalut「数」はテンソルである、私はこれを比較することはできませんたとえば、int32を使用しています。グラフのtf_count(t、val)<6: 'ならば、これはエラーになります。 'sess.run() 'を実行せずに戻り値をint32で区切る方法はありますか?ありがとう。 –

+0

いいえ、それはテンソルの流れがどのように作用するのですか、物事はsession.runを通過するまでテンソルです。グラフの中を走り続けたい場合は、tf.less(tf_count(t、val)、6)を使うことができますが、結果にテンソルがあります。 –

+0

サルター、それを使って、私はそれを断念することに決めました。あなたの親切な助けをありがとうございます:) –

1

上記のスレーターの答えに加えて。 の数をすべての要素にする場合は、one_hotreduce_sumを使用して、Python内でのループを避けることができます。たとえば、以下のコードスニペットは、word_tensor内のオカレンスによって順序付けられたボキャブを返します。

def build_vocab(word_tensor, vocab_size): 
    unique, idx = tf.unique(word_tensor) 
    counts_one_hot = tf.one_hot(
     idx, 
     tf.shape(unique)[0], 
     dtype=tf.int32 
) 
    counts = tf.reduce_sum(counts_one_hot, 0) 
    _, indices = tf.nn.top_k(counts, k=vocab_size) 
    return tf.gather(unique, indices) 

EDIT:少し実験をした後、私はそれがTFの最大テンソルのサイズを超えて爆破するone_hotテンソルのために非常に簡単です発見しました。 (少しエレガントな場合)には、このようなものでcountsコールを交換する可能性がより効率的です。

counts = tf.foldl(
    lambda counts, item: counts + tf.one_hot(
     item, tf.shape(unique)[0], dtype=tf.int32), 
    idx, 
    initializer=tf.zeros_like(unique, dtype=tf.int32), 
    back_prop=False 
) 
1

あなたはテンソルtnまでのすべての整数のカウントを取得したい場合は、あなたのようtf.unsorted_segment_sum使用することができますこれは:

count_all = tf.unsorted_segment_sum(tf.ones_like(t), t, n) 

count_allがヒストグラムになります。

count_all[0]はテンソルtであなたに番号0が表示された回数を教えてくれます:

t = tf.placeholder(tf.int32) 
count_all = tf.unsorted_segment_sum(tf.ones_like(t), t, 3) 
sess.run(count_all[0], {t: [1,2,0,0,0,0]}) 
# returns 4 
sess.run(count_all, {t: [1,2,0,0,0,0]}) 
# returns array([4, 1, 1], dtype=int32) 

残念ながら、これだけの作品は何のバッチ次元が存在しないと仮定します。また、Eli Bixbyが指摘しているように、one_hotを割り当てる方が速い方法は、あまりにも多くのメモリを占有する可能性があります。これを回避する私の個人的な好みは、を次のように使用することです。

def count_all_fnc(e): 
    return tf.unsorted_segment_sum(tf.ones_like(e), e, n) 
count_all = tf.map_fn(count_all_fnc, t) 

n = 3 
t = tf.placeholder(tf.int32) 
def count_all_fnc(e): 
    return tf.unsorted_segment_sum(tf.ones_like(e), e, n) 
count_all = tf.map_fn(count_all_fnc, t) 
sess.run(count_all, {t:[[1, 0, 0, 2], [1, 2, 0, 0], [0, 0, 0, 0], [1, 1, 1, 2]]}) 

戻り

array([[2, 1, 1], 
     [2, 1, 1], 
     [4, 0, 0], 
     [0, 3, 1]], dtype=int32) 

あなたが利用可能なメモリを持っている場合、それははるかに高速(約10倍)指数への各インデックスを表すワンホットベクトルの検索で、それらを一緒に合計し、これは高度に並列化できるためです。しかし、スペースの必要量はn*|t|として増加し、これはすぐに実行不可能になります。

one_hot_t = tf.one_hot(t, n) 
count_all = tf.reduce_sum(one_hot_t, axis=1) 
3

は、あなたがboolean型のマスクを作成することができるだけで、特定の要素を数えるintに変換し、それを合計するには、次の

import tensorflow as tf 

X = tf.constant([6, 3, 3, 3, 0, 1, 3, 6, 7]) 
res = tf.reduce_sum(tf.cast(tf.equal(X, 3), tf.int32)) 
with tf.Session() as sess: 
    print sess.run(res) 

はまた、あなたがtf.unique_with_countsを使用して、リスト/テン​​ソル内のすべての要素をカウントすることができます。ダニエル・スレーター@

import tensorflow as tf 

X = tf.constant([6, 3, 3, 3, 0, 1, 3, 6, 7]) 
y, idx, cnts = tf.unique_with_counts(X) 
with tf.Session() as sess: 
    a, _, b = sess.run([y, idx, cnts]) 
    print a 
    print b 
関連する問題