2017-07-06 1 views
0

バッチの偶数要素と奇数要素をチェックし、必要に応じてスワップします。 Tensorflow:偶数と奇数のインデックスに従って2つの2Dテンソルを結合する

def tf_oplu(x, name=None): 


    even = x[:,::2] #slicing into odd and even parts on the batch 
    odd = x[:,1::2] 

    even_flatten = tf.reshape(even, [-1]) # flatten tensors 
    #in row-major order to apply function across them 

    odd_flatten = tf.reshape(odd, [-1]) 

    compare = tf.to_float(even_flatten<odd_flatten) 
    compare_not = tf.to_float(even_flatten>=odd_flatten) 

    #def oplu(x,y): # trivial function 
    # if x<y : # (x<y)==1 
    #  return y, x 
    # else: 
    #  return x, y # (x<y)==0 

    even_flatten_new = odd_flatten * compare + even_flatten * compare_not 
    odd_flatten_new = odd_flatten * compare_not + even_flatten * compare 

    # convolute back 

    even_new = tf.reshape(even_flatten_new,[100,128]) 
    odd_new = tf.reshape(odd_flatten_new,[100,128]) 

は、今私は満たさ偶数と奇数の場所に戻って$ [100256] $テンソルを取得したい:私は織りたい2つのテンソルとなることができました。 numpyでは、私はもちろんそうです:

y = np.empty((even_new.size + odd_newsize,), dtype=even_new.dtype) 
y[:,0::2] = even_new 
y[:,1::2] = odd_new 

return y 

テンソルは変更できませんが、そういうことはテンソーフローではできません。 sparse tensorまたはtf.gather_ndのどちらでも可能ですが、どちらもインデックスの配列を生成する必要があります。これは、私にとっては自明ではありません。 もう1つの注意:私はtf.py_func経由でPython関数を使用したくないです。私はそれらがCPU上でのみ動作することを確認しました。たぶんラムダとtf.map_fn何とか助けてくれる?ありがとう!

答えて

1

2つの行列を垂直方向にインターリーブするには、gatherまたはmap_fnなどの大きな銃を使用しないでください。次のようにあなたは、単にそれらをインターリーブすることができます

tf.reshape(
    tf.stack([even_new, odd_new], axis=1), 
    [-1, tf.shape(even_new)[1]]) 

EDIT

が水平にそれらをインターリーブするには:

tf.reshape(
    tf.concat([even_new[...,tf.newaxis], odd_new[...,tf.newaxis]], axis=-1), 
    [tf.shape(even_new)[0],-1]) 

アイデアは、メモリ内にそれらをインターリーブするスタックを使用することです。スタックが発生する次元は、インターリーブの細分性を与える。 axis=0にスタックすると、各要素で混合列がインターリーブされます。 axis=1にスタックすると、入力行全体が連続したままになり、行間にインターリーブが発生します。

+0

ありがとうございました!しかし、このコードは[100,256]の代わりにテンソル[200,128]を生成します。私は 'y = tf.reshape(tf.stack([even_new、odd_new]、axis = 0)、[tf.shape(even_new)[0]、 - 1])'に変更しました。期待される。なぜあなたは本当に奇数と奇数の要素が必要な場所に置かれているのか、少し説明してください。 – Slowpoke

+0

私が理解するように、それはそれらを垂直に積み重ねてから、互いの下に横に並んでいる要素を配置するはずの形を変えます。 – Slowpoke

+0

はい、あなたのnumpyの例に続き、テンソルも垂直方向(最初の次元に沿って)積み重ねています。それらを横に積み重ねるように修正しました。 – user1735003

1

assignを使用してスライスに割り当てることができます。

odd_new = tf.constant([1,3,5]) 
even_new = tf.constant([2,4,6]) 
y=tf.Variable(tf.zeros(6, dtype=tf.int32)) 

sess = tf.InteractiveSession() 
sess.run(tf.global_variables_initializer()) 
y[0::2].assign(odd_new).eval() 
y[1::2].assign(even_new).eval() 
+0

ありがとう!私は当初、代入演算子を使ってネットワークを構築しようとしましたが(しかし、いくつかの問題に直面し、それをやめてしまった)(https://stackoverflow.com/questions/44737322/)(ただし、コードは正しいと思います)私は埋め込まれたテンソルフロー関数を使うことを好むので、最初の答えは私に合っています。それでも、ありがとう! – Slowpoke

関連する問題