クロの制作日記

クロの制作日記

田舎の大学生がUnityとか機械学習関連の制作物をひたすらアップします。ブログで紹介したコード一覧https://github.com/kuroshum/blog_code

初心者が頑張るTensorflow入門(用語解説編)

はじめに

最近、機械学習や深層学習が広く知られるようになりました。

それに加え、一部の専門的な知識を持った研究者やエンジニアだけでなく、専門外の学生や社会人の方々が「機械学習・深層学習を使ってこんな事をしてみた」といった試みをよくqitaやはてなで見かけます。


qiita.com

pyhaya.hatenablog.com

ただ、本来はそのような技術を使うためには、高度な数学や確率統計の知識が必要で、専門外の人間が手を出せるような代物ではございません。

それを可能にしたのが「Tensorflow(テンソルフロー)」です。Tensorflowが出てきたおかげで、機械学習・深層学習を実装する際に必要とされる専門的な知識がなくても実装できるようになりました。


この記事ではそのようなことを可能にしたTensorflowがどのようなものなのかを解説していきます。

また、本記事はTensorflow1.xの解説で、Tensorflow2.0以降の解説ではないことをご了承ください。

あと、今回は用語の解説だけですが、次の記事では、簡単な線形回帰モデルの実装と実装上で用いた関数などの解説を行います。

次の記事
kurora-shumpei.hatenablog.com

私がよく参考にしている本はこちらです。


TensorFlow機械学習クックブック Pythonベースの活用レシピ60+ impress top gearシリーズ


詳解 ディープラーニング ~TensorFlow・Kerasによる時系列データ処理~

Tensorflowとは

TensorflowはGoogleによって開発された高速数値解析用のライブラリです。ちなみにOSSオープンソースソフトウェア)ですので、何も登録せずにしかも無料で使うことができます。

github.com

基本的にはニューラルネットワークやディープニューラルネットワークを「簡単に」構築するために用いられます。簡単にというのが重要ですね。簡単ではなかったらここまで普及していなかったかと思います。

対応言語はPythonを筆頭に、C/C++java、goといった様々な言語に対応しています。ちなみに、Tensorflowの内部はNumpyなどのライブラリと同じようにC++で記述されているようで、pythonなどの処理速度が遅い言語で実装しても、速度面では心配することはなさそうです。

Tensorflowの仕組み

Tensorflowの特徴としては以下の二つが挙げられます。

  • データ・フロー・グラフを構築する
  • 内部の計算はTensorで行う

順に説明していきましょう。

データ・フロー・グラフ

Tensorflowはデータ・フロー・グラフと呼ばれるグラフを構築して、その後に数値を入力することで、数値計算を行います。

このデータ・フロー・グラフがどのようなものかを線形回帰の式であるwx+bを例に説明します。

wx+bのデータフローグラフは大体こんなイメージです(図1)。

f:id:kurora-shumpei:20191126004400p:plain
図1 データフローグラフの例

Tensorflowでは青丸が「オペレーション」、オレンジ四角が「入力値」、矢印が「エッジ」と呼ばれています(多分入力値もオペレーションだと思いますが分かりやすいように分けています)。

一般的なデータフローグラフだとオペレーションのことを「ノード」と呼ぶらしいですが、Tensorflowではオペレーションと呼ぶようです。

このようなグラフをまず構築し、その後に入力値を代入すれば、あとは水が流れるようにグラフを辿って計算を行ってくれるので、「Tensorflow」という名前になったのだと思います(多分)。




データフローグラフの利点

ここで、なぜ、このようなグラフを構築する必要があるのか、という疑問が湧いてくるかと思います。そこで、このグラフ構築を行う利点を3つほど紹介しておきましょう。

  1. 複数のGPUやマシンでの並列・分散処理ができる
  2. PythonC/C++間でのオーバーヘッドを減少させることができる
  3. 移植性が高い
複数のGPUやマシンでの並列・分散処理ができる

上記のwx+bだと説明が難しいのと、良い例が浮かばなかったので、w1x+w2xみたいな数式の場合を考えてみましょう(図2)。

f:id:kurora-shumpei:20191126014600p:plain
図2 データフローグラフ2

この場合だとw1xとw2xの計算は独立しているので、並列計算することができます。

PythonC/C++間でのオーバーヘッドを減少させることができる

Tensorflowはあらかじめグラフを構築します。numpyのようなライブラリだと、numpyの関数を呼ぶたびにpythonとnumpyとの変数等のやり取りを行う必要がありますが、あらかじめグラフを構築しているとそのやり取りを減らすことができます。

移植性が高い

データフローグラフは何かしらのプログラム言語で記述されたものではなく、あくまでもグラフなので、特定のプログラム言語に依存しません。pythonで実装したグラフもjavaで実装したグラフも同じグラフになります。なので、開発環境が変わったときでも簡単に移植することができます。

Tensorとは

Tensorflowの内部の計算では、Tensor(テンソル)を用います。

Tensorとは何かを数学的に説明するのは面倒なので、取り敢えずは多次元配列みたいなものと認識しておいてください。

数学的な説明はこちら
ja.wikipedia.org

Tensorは多次元行列みたいなものなのでスカラー・ベクトル・行列の対応関係は以下の図3のようになります。

f:id:kurora-shumpei:20191126021853p:plain
図3 テンソルの対応関係

ここでの「階」とは次元のことです。Tensoeでは次元のことを階と呼びます。

TensorflowでのTensorの扱い

先ほど言ったように、Tensorflowの内部の計算はすべてTensorで行われます。「へー、そうなんだー。まあいいんじゃない?」と思うかもしれませんが、これが結構厄介なのです。

何が厄介かというと、Tensorpythonやnumpyのデータ型に基本的に変換することができません。後で説明するSessionというものを使えば、グラフで行われた計算結果はpythonやnumpyのデータ型で取得することはできますが、グラフ内で行われている計算に用いている数値はTensorから変更することができません。

今はあまりピンと来ないかもしれませんが、Tensorflowで色々複雑な計算を実装し始めると理解することができるかと思います。

Tensorflowの実装の流れ

Tensorflowはデータフローグラフを構築してから計算を実行するという流れなので、一般的なプログラム言語での実装とは少し違ったものになります。実際にどう違うのかPythonのみでの実装と、Tensorflowを用いた実装を図4で比較してみましょう。

f:id:kurora-shumpei:20191126151751p:plain
図4 PythonとTensorflowの実装上の比較

Pythonの方は皆さんご存知のように、上から一行ずつ処理が読み込まれ、実行されます。

Tensorflowでも1行ずつ読み込まれていくのですが、実行のタイミングが異なります。

処理の金型の設計図を作成

上図のように一番最初には、グラフ構築と計算に用いる変数の型と形(shape)を定義するのですが、この時点では計算の処理は行われません。ただ単に、どういった計算をするか、どういった変数を用いるかの定義を読み込むだけです。まさに、これから行う計算の金型の設計図を作成しているようなものです。

金型を初期化

次に、Sessionを作成することで、グラフや変数の初期化を行います。Sessionとは何かというと、オブジェクト指向でいうクラスのインスタンス化みたいなものです。このSessionを作成することで、事前に定義したグラフや変数を使うことができるようになります。上図でいうと、設計図から金型を作成したことに相当します。

金型に入力値を代入し実行

最後に、定義しておいた変数にデータを入力し、ようやく計算を実行します。




最後に

この記事ではTensorflowで用いられる用語の解説を行いました。次の記事では、実際に、簡単な線形回帰モデルを実装して、実装上に用いた関数などの説明を行います。

次の記事
kurora-shumpei.hatenablog.com



TensorFlow機械学習クックブック Pythonベースの活用レシピ60+ impress top gearシリーズ


詳解 ディープラーニング ~TensorFlow・Kerasによる時系列データ処理~