KZKY memo

自分用メモ.

Computational Graphの実装概要

TF, CNTK, Theano, Caffe, Chainer等,巷にDNNライブラリはあふれている.DNNライブラリとはいかないまでも,自分でComputational Graphを実装してみたいと前から思っていたので,書いてみた.インターフェイスとしてすら,まだ全部出来ているわけではない.

概要

3つのクラス

  • ComputationalGraph
  • Vertex
  • Edge

がある.

設計思想

こんな感じに積み木を積み上げるように使いたい.

v_in = Vertex("x")
v1 = Edge(name="e0")(v_in)
v2 = Edge(name="e1")(v1)
v3 = Edge(name="e2")(v2, v1)  # fork and concate
v4 = Edge(name="e3")(v3)
v5 = Edge(name="e4")(v4)
...
v_in.forward()
v_out.backward()

学習パラメータとグラフは分離させたいので,EdgeについてるパララメータもVertexとして扱いたい.すなわち,Edgeにパラメータを持たせないことで,グラフとパラメータの分離ができて,グラフを動的に構築しながら,foward/backwardができる.

DAGのSourcesでfowardってやって,DAGのDistinationsでbackwardてやると,それぞれ,inference, backpropをしてくれるようにしたい.

すなわち,v.foward() -> e.foward() -> v.forward() -> e.foward() ... な感じで連鎖的に,自分のfowardを呼んで,子供のfowardを呼んで,その子供のfowardを呼んで,というようにしたい.backwardはその逆で,自分のbackwardを呼んで,親のbackwordを呼んでといった感じ.

ComputationalGraph

Directed Acyclic Graphそののもで, G=(V, E), VertexとEdgeを持つ

Vertex

Edgeを通る前,および,通った後の入れ物として機能するコンテナ

Edge

任意のVertciesを受け取って,何かしらの操作をして,Vertexを返す

制約

  • DAGである
  • Edgeの入力/出力はVertex, Vetexの入力/出力はEdge
  • Multi Graphでない, 複数Edgeが同じVertex間に存在してはならない
  • Edgeは,複数のvertexを入力として良いが,出力vertexは1つ. すなわち,Edgeにおける,入力Vertex:出力Vertex=1-n:1
  • Vertexは,複数のEdgeに入ってい良いし,全く入らなくても良い (=Distination). すなわち,Vertexにおける,入力Edge:出力Edge=1:0-n
  • forward時,Edgeに複数入力がある場合は,全部の入力が揃うまで,子供Veretexのfowardは呼べない.
  • backward時,Vertexに複数入力がある場合は,全部の入力が揃うまで,親Edgeののbackwardは呼べない.

残件 (順不同)

これ以上やらないと思うが,

  • Activationの実装
  • Convolutionの実装
  • Computational Graph上にヘルパー関数forward/backwardの実装
  • Optimizerの実装
  • ComputatinalGraph上のグラフ操作系のヘルパー関数いろいろ

コード

Computational Graphにある.
サンプルは,ここにある.

所感

思ったより,Fork/Concateがややこしく,Edge.foward, Vertex.backwardがややこしくなっている.この実装がベストプラクティスなのか不明.現状,1 processで1graphが制約になっているのも不満.