edward2のinterception処理 [e334115, d07338e, 93bc07b] - pymc4のソースコード読んでみた
概要
- まずは
Model
クラスの初期化処理系のメソッドを読んでみます。_init_variables
: 今回はここのed.interception()
の処理を読みます
コミット
2018/06/09から2018/06/11の間のコミットです。
- tmp · pymc-devs/pymc4@e334115 · GitHub
- restructure + test point implementation · pymc-devs/pymc4@d07338e · GitHub
- fixes · pymc-devs/pymc4@93bc07b · GitHub
Model - pymc4/model/base.py
_init_variables
今回は _init_variables
内のtensorflow及びtensorflow_probabilityに関連する処理を見ていきます。 ed.interception
がわかればなんとなく処理がわかってくるはずです。
info_collector = interceptors.CollectVariablesInfo() # info_collector() で呼べるcallable with self.graph.as_default(), ed.interception(info_collector): self._f(self.cfg) self._variables = info_collector.result
以下の ed.interception
の使い方を見てみましょう。
see: probability/interceptor.py at master · tensorflow/probability · GitHub
def model(): return ed.Poisson(rate=1.5, name="y") def interceptor(f, *args, **kwargs): if kwargs.get("name") == "y": kwargs["value"] = 42 return interceptable(f)(*args, **kwargs) with ed.interception(interceptor): y = model() with tf.Session() as sess: assert sess.run(y.value) == 42
interceptという名前の通り、 def interceptor(f, *args, **kwargs)
のような関数を渡すと、 f
を呼んだ結果のインスタンスに値をセットすることができます。
上記の例では、 y
というModelインスタンスに y.value = 42
の値をセットしています。
他のコードを読んでみると ed.interception(interceptors.Chain(*chain))
という形で使用している箇所もあるので、名前から察するにinterceptの処理を複数重ねていくことができるみたいです。例えば、上記の例で言えば、別のintercept処理を重ねて y.result = [42]
のように y
のインスタンスに新たに result
という名前の配列を作成していくこともできるはずです。
以下の _init_variables
の処理を見ると、 self._f
を実行した戻り値がedward2の RandomVariable
クラスのインスタンスであり、そのインスタンスに info_collector
というinterceptの処理をかませていることが見て取れます。前回見た通り、 CollectVariablesInfo
内では 単に f
を実行し、info_collector
の result
プロパティに RandomVariable
の配列を格納していました。
with self.graph.as_default(), ed.interception(info_collector): self._f(self.cfg) # <= RandomVariableクラスのインスタンス
結果的に、 with文内で RandomVariable
のインスタンスの結果を受け取ることなく、 info_collector
から結果の配列を受け取ることができます。
self._variables = info_collector.result <= RandomVariableクラスのインスタンス配列
次回は、どう使われているかわからない self.graph.as_default()
部分を読み解いていく予定です。