Lambdaカクテル

京都在住Webエンジニアの日記です

Invite link for Scalaわいわいランド

Tensorflow Scalaで遊んだ記録その4(グラフを定義する)

年収100兆円を目指して機械学習を学ぶシリーズです。

blog.3qe.us

blog.3qe.us

blog.3qe.us

そういえばTensorflowは正しくはTensorFlowだということに気付いたけど、もうタイトル変更するのが面倒なのでTensorflowで押し切ることにします。

グラフ定義 -- 計算の定義と実行の分離というパラダイム

さて、Tensorflowでは Tensor を扱うわけだけど、最近のプログラミング言語のパラダイムとして受け入れられつつある、計算の定義と実行の分離が採用されている。どういうことかというと、まず Tensor 計算グッズを グラフ として組み合わせたものを定義しておいて、最終的にそれに入力となる Tensor を突っ込んで実行すると Tensor が得られる、という仕組みになっている。つまり、都度計算するのではなく、手順だけ先に教えて最後にガッと計算してもらおう、という考え方。

グラフを組み立てるのに用いる「Tensorを計算した結果が入るはずのもの(まだ未計算)」を表現するモデルとして、 Output というクラスが用意されていて、ユーザはこの Output を組み立てることでより大きな Output を形作り、最終的に Tensor を入力して計算を行う、という手筈になっている。Scala標準の Future にちょっと似てますな。

そして Output もまた Tensor 同様に Shape といった属性を持っているので、実質 Tensor として扱うことができる。唯一の違いはまだ計算されていないことだけ。(計算の種類によっては、実行時に初めてShapeが判明するケースもあるとのこと。)

余談だが、計算の定義と実行の分離を採用しているライブラリやフレームワークとしては、Cats Effect (IOモナドを導入している) やAkka Streams (Graphを構築してからデータを投入する) などが挙げられる。このモデルを採用する利点は、組み立ててから実行するので計算順序がこんがらがったりしないし、ランタイムがある程度実行順序に介入できるため最適化の余地が生まれること。

チュートリアル

余談はさておき、チュートリアルをやっていきましょう。

platanios.org

って思ったけど、チュートリアルがスカスカで何も分からないぜ!

オレオレチュートリアル

しょうがないのでテストとか本家Tensorflowのドキュメントを見て勘で使い方を勉強するコーナーが始まるぜ。

ネットに良さげなチュートリアルが転がってたからこれを見るぜ。

novakov-alexey.github.io

Session

グラフを定義する前に、まず Session という概念について知っておく必要があるみたいだ。

Session とはグラフの実行環境のハンドラである。 Cats Effect とか Akka とかをやっていると、あ〜 ExecutionContext みたいなもんですねと納得いくと思うのだが、一応説明しておく。

先程説明した通り Tensorflow では計算の定義と実行が分離されているので、計算の定義とは別に、実行側のメカニズムを明示的に用意してやる必要がある。それが Session である。言い換えると Output 実際に実行する君みたいな感じだ。Tensorflow でグラフを実行するときは、この Session を作成して実行してもらうことになるというわけ。

Sessionorg.platanios.tensorflow.tensorflow.api.core.client.Sessionに定義されている。

import org.platanios.tensorflow
/* ... */
println("session")
import tensorflow.api.core.client.Session
val sess = Session()
val o1 = Tensor[Int](Seq(Seq(1, 2), Seq(3, 4))).toOutput
val o2 = Tensor[Int](Seq(Seq(1, 2), Seq(3, 4))).toOutput
val o1o2 = o1 * o2
val t1t2 = sess.run(fetches = Seq(o1o2))
println(t1t2.summarize())
sess.close()
session
2022-12-31 19:39:54.156088: I tensorflow/compiler/jit/xla_gpu_device.cc:99] Not creating XLA devices, tf_xla_enable_xla_devices not set
2022-12-31 19:39:54.274911: I tensorflow/core/platform/profile_utils/cpu_utils.cc:112] CPU Frequency: 2699905000 Hz
Tensor[Int, [1, 1, 2, 2]]
[[[[1, 4],
   [9, 16]]]]

なんか勘で書いたら動いた。天才かな?

これも勘だけど、定義とcloseがあるってことはスコープを切った賢い振舞いができるのでは?と思ったけど難しかったので諦めた。

基本的に、即値である Tensor の類は Output に変換することができるので、入力するテンソルを変換してからSession.runに渡してやると良さそう。

さて、機械学習をやるからには単にテンソルを計算するだけではなくて、学習、すなわちモデル中の変数を最適化したり、プレースホルダ機能を使ってエンドユーザからの入力を受け付けていくことになるのだけれど、これはまた次回。

参考文献

atmarkit.itmedia.co.jp

★記事をRTしてもらえると喜びます
Webアプリケーション開発関連の記事を投稿しています.読者になってみませんか?