2017-04-04 7 views
4

私はTensorFlowのtf.unsorted_segment_sumメソッドを使用していますが、テンソルがデータとして1行しか持たないときにはうまく動作します。たとえば:Tensorflow unsorted_segment_sum dimension

tf.unsorted_segment_sum(tf.constant([0.2, 0.1, 0.5, 0.7, 0.8]), 
         tf.constant([0, 0, 1, 2, 2]), 3) 

は、正しい結果を与える:私はいくつかの線でテンソルを使用する場合

array([ 0.3, 0.5 , 1.5 ], dtype=float32) 

質問は、私は行ごとに結果を得ることができる方法、ありますか?たとえば、私は2本の線でテンソルをしようとした場合、:

array([ [ 0.3, 0.5 , 1.5 ], [ 0.4, 0.5, 1.5 ] ], dtype=float32) 

しかし、私が得ることである:

tf.unsorted_segment_sum(tf.constant([[0.2, 0.1, 0.5, 0.7, 0.8], 
            [0.2, 0.2, 0.5, 0.7, 0.8]]), 
         tf.constant([[0, 0, 1, 2, 2], 
            [0, 0, 1, 2, 2]]), 3) 

私が期待する結果は、私が知りたい

array([ 0.7, 1. , 3. ], dtype=float32) 

誰かがforループを使わずに各行の結果を得る方法を知っていたら?事前に

おかげ

答えて

3

tf.unsorted_segment_sumは、単一の軸上で作業をサポートしていません。最も簡単な解決策は、各行に操作を適用し、それらをバック連結するようになります:

data = tf.constant([[0.2, 0.1, 0.5, 0.7, 0.8], 
        [0.2, 0.2, 0.5, 0.7, 0.8]]) 
segment_ids = tf.constant([[0, 0, 1, 2, 2], 
          [0, 0, 1, 2, 2]]) 
num_segments = 3 
rows = [] 
for data_i, ids_i in zip(data, segment_ids): 
    rows.append(tf.unsorted_segment_sum(data_i, ids_i)) 
result = tf.stack(rows, axis=0) 

はしかし、これには欠点があります:1)それは唯一のものである(静的型テンソルのために働く、あなたが持っている必要があります2)効率的ではない可能性があります。最初のものはtf.while_loopを使用して回避することができますが、それは複雑で、行を1つずつ連結する必要があり、非常に非効率です。また、すでにループを避けたいと述べています。

より良いオプションは、各行に異なるIDを使用することです。あなたは、各行は、IDSの独自のセットを持っていることを保証してたとえば、あなたは、num_segments * row_indexようsegment_idなもので、それぞれの値に追加することができます。

num_rows = tf.shape(segment_ids)[0] 
rows_idx = tf.range(num_rows) 
segment_ids_per_row = segment_ids + num_segments * tf.expand_dims(rows_idx, axis=1) 

を次にあなたがそのテンソルを取得する操作とリシェイプを適用することができますあなたが欲しい:

seg_sums = tf.unsorted_segment_sum(data, segment_ids_per_row, 
            num_segments * num_rows) 
result = tf.reshape(seg_sums, [-1, num_segments]) 

出力:

array([[ 0.3, 0.5, 1.5 ], 
     [ 0.4, 0.5, 1.5 ]], dtype=float32) 
+0

はあなたの助けをありがとう! – user3575801

関連する問題