2017-06-28 5 views
1

Tensorflow計算グラフがどのように動作するかを深く理解しようとします。Tensorflow:値割り当て操作の優先度

A = tf.truncated_normal(shape=(1,), stddev=0.1) 
B = tf.Variable([0.3], dtype=tf.float32) 
C = A * B 
grads = tf.gradients(C, [A, B]) 
init = tf.global_variables_initializer() 
sess = tf.Session() 
sess.run(init) 

for i in range(1000): 
    results = sess.run([C, grads], {A: [2], B:[5]}) 

予想通り、Aが10、勾配が5、Bが2の結果が得られます。私が確信したいのは、AとBのようにテンソルに値を渡すと、計算グラフに定義されたデフォルト値生成メカニズムが上書きされるということです。

たとえば、ここでは、forループでsess.run行を実行するたびに、Aに対して通常のランダム値は生成されず、2で上書きされ、Bに対しては0.3が15で置き換えられます。このような場合、計算グラフはどのように正しく動作しますか? sess.runを呼び出すたびに、フェッチリストの値を計算するために必要なノードがトポロジカルな順序で決定され、すべてのテンソルがfeed_dictパラメータで指定された値で上書きされます。それらの依存関係を計算グラフの残りの部分に分割する。 (たとえば、テンソルAがBの値を評価するのを待っていて、feed_dictにAに値を注入すると、AのBへの依存が壊れてしまい、何とか計算グラフに反映されると思います。次に、計算グラフの最終形態に従って、前進および後退計算が実行される。

答えて

2

私は必要なだけの二つの小さな修正があると信じて:

  1. が代わりに2つのパスをしているの - 最初に実行するための最小のグラフを決定し、それが単一のパスで行うことができます「それを破る」 - 1 sess.runを実行するために必要な最小のグラフを探します。は何ですか?言い換えれば、新しいノードを発見するたびに(あなたの操作の依存関係を逆戻りするとき)、それがfeed_dictで提供されているかどうかをチェックし、それが真であれば、これが指定の葉ノードであると仮定します。

  2. TFに「後方計算」というものはありません。すべてが前方計算です。 tf.gradients(またはminimize)コールは単にという前方グラフを構成します。これは後方パス中に他の多くのライブラリで起こるものと機能的に同等です。しかし、TFでの厳密なフォワード/バックワード分離はありません。そして、あなたはグラフで必要なものを自由にハックし、混ぜ合わせることができます。最後は一方向のデータフローです。