2016-10-27 19 views
7

この質問の2つの部分:テンソルフローのテンソルのサブセットに値を割り当てる方法は?

(1)テンソルフローのテンソルのサブセットを更新する最良の方法は何ですか?私はいくつかの関連の質問を見てきました:

Adjust Single Value within Tensor -- TensorFlowHow to update a subset of 2D tensor in Tensorflow?

と私は変数オブジェクトがVariable.assign()(および/またはscatter_update、など)を使用して割り当てることができることを承知しているが、それテンソルフローがTensorオブジェクトの一部を更新するより直感的な方法を持っていないということは、私にとっては非常に奇妙なことです。私はtensorflow api docsとstackoverflowをかなり長い間検索してきており、上記のリンクよりも簡単な解決策を見つけることはできないようです。 TheanoがTensor.set_subtensor()と同等のバージョンを持っていることを考えると、これは特に奇妙なようです。私は何かを見逃しているのですか?またはこの時点でテンソルフローAPIを使ってこれを行う簡単な方法はありませんか?

(2)より簡単な方法がある場合は、それは区別できますか?

ありがとうございます!

+0

numpy配列でテンソル値を初期化するだけで十分ですか?それから私は方法をお勧めします。 – Jin

+4

Tensorflowの最近のバージョンでは、次のようにnumpyのようなスライスを使用して変数を更新できます: 'v [2:4] .assign([1,2])'、 'v'は' Variable'です。それはあなたの質問に答えますか? –

+0

おかげさまで、ありがとうございました。残念ながら、私が探しているものではありません...更新変数はnumpyのようなスライシングを使用していますが、 "変数"にのみ適用できますが "テンソル"には適用されません。私はこのオペレーションの明示的な必要性を避けるためにモデルを再設計しました。実際、Tensorオブジェクトはtfで完全に不変です(Variableオブジェクトとは異なります)。しかし、考え直してくれてありがとう! – joeliven

答えて

0

計算グラフの作成にTensorsの不変性が必要であると仮定します。 Tensorに別のTensorにならずに値の一部を更新させることはできません。または、それ以前にグラフに入れることはありません。 The same issue comes up in Autograd

ブール値のマスクを使って(醜い)変数を作成してassignを使用するか、numpyで事前に定義することもできます。それは微分可能ですが、実際にはサブセンサーを更新する必要はありません。

あなたが本当にしなければならない、と私は本当にこれを行うには良い方法があると思いますが、ここではtf.dynamic_stitchtf.setdiff1d使用して1Dでそれを行うための方法である場合:高次元の場合

def set_subtensor1d(a, b, slice_a, slice_b): 
    # a[slice_a] = b[slice_b] 
    a_range = tf.range(a.shape[0]) 
    _, a_from = tf.setdiff1d(a_range, a_range[slice_a]) 
    a_to = a_from 
    b_from, b_to = tf.range(b.shape[0])[slice_b], a_range[slice_a]  
    return tf.dynamic_stitch([a_to, b_to], 
        [tf.gather(a, a_from),tf.gather(b, b_from)]) 

はこれができましたreshape悪用によって一般化(nd_slice could be implemented like thisをより良い方法はおそらくあります)すること:

def set_subtensornd(a, b, slice_tuple_a, slice_tuple_b): 
    # a[*slice_tuple_a] = b[*slice_tuple_b] 
    a_range = tf.range(tf.reduce_prod(tf.shape(a))) 
    a_idxed = tf.reshape(a_range, tf.shape(a)) 
    a_dropped = tf.reshape(nd_slice(a_idxed, slice_tuple_a), [-1]) 
    _, a_from = tf.setdiff1d(a_range, a_dropped) 
    a_to = a_from 
    b_range = tf.range(tf.reduce_prod(tf.shape(b))) 
    b_idxed = tf.reshape(b_range, tf.shape(b)) 
    b_from = tf.reshape(nd_slice(b_idxed, slice_tuple_b), [-1]) 
    b_to = a_dropped 
    a_flat, b_flat = tf.reshape(a, [-1]), tf.reshape(b, [-1]) 
    stitched = tf.dynamic_stitch([a_to, b_to], 
        [tf.gather(a_flat, a_from),tf.gather(b_flat, b_from)]) 
    return tf.reshape(stitched, tf.shape(a)) 

私はこれがものになるかどうか遅い見当がつかない。私はかなり遅いと思います。そして、私はそれを2つのテンソルで実行する以外にはそれほどテストしていません。

関連する問題