こんにちは!かわしま@食を楽しむエンジニアです。
突然ですが、皆さん有給休暇は活用されていますか?私は先日、残り2日しかない有給を使って気になっていたラーメン店をハシゴしてしまいました。(ノ_-。) 次の有給付与日まで2ヶ月ありますから、とても貴重。だからこそしっかり消化します。
1店目は、今一番注目が集まっているJapanese Soba Noodles 蔦(ジャパニーズソバヌードル ツタ)を選択。ミシュランの一つ星を獲得したラーメン店と言えばご存じの方も多いのでは。ラーメン店が星を獲得したのは史上初。凄いですよね。
平日といえどもさすがの混み具合。始発で向かって夜も明けぬうちから整理券をもらい、再度お昼にうかがいました。お店の扉を開けた瞬間、料亭に来たかと錯覚させるダシの良い香りが漂います。大盛り、肉飯付きで、醤油ラーメンを注文。
緊張感が漂う店内。みなさん、もくもくと食べています。私も心躍らせながら待つ事10分。やって来ました。
ラーメンにのっている黒トリュフはインパクトありますね。ご飯にはトリュフオイルがかかっているのか、良い香りがします。スープをひとさじ口に運ぶと、あっさり醤油ベースのなかにダシの奥深さが隠れていて複雑な印象を受けます。麺はコシと旨味があります。味がおいしいだけではなく、食材から器、サービスにわたり、ラーメンという商品のプロモーションが非常に長けている感があります。驚愕です。
もう一店は亀有のつけ麺 道。こちらも有名店ですね。トッピングがネギと薬味だけの「素つけ麺」のメニューには驚きましたが、この潔さも自信の証でしょうか。実際にスープ、麺には非常にこだわりを感じます。スープの器が温められているのもまた嬉しいですね。しかし、平日の14時半に行って2時間待ちとは。。
次の有給付与日のために、そろそろお店選びをはじめたいところ。
さて、前回はTensorFlowを使った深層学習で何ができるのかを見ていきました。画像認識や機械翻訳のほかにも、医薬品開発や金融サービス、さらには囲碁AIのAlphaGoなど色々な分野で利用が広がるDeep Learning。このブログでは当面、TensorFlowのチュートリアルやサンプルコードを題材にしていく予定です。チュートリアルをうまく活用し、Deep Learningを気軽に利用できるレベルになれれば楽しそうですよね。
今回はTensorFlowの仕組みやPythonのエコシステムを少し追ってみましょう。
深層学習をより深く理解する書籍・講座
本題に入る前に、深層学習の理解を深める書籍・講座を紹介させてください。
書籍
初めてのディープラーニング --オープンソース"Caffe"による演習付き
- Deep Learning関連の知識がやさしくまとめられています
- 数式がほとんど出てこないので気楽に読めます
- ディープラーニングの全体像を俯瞰したい方におすすめです
- タイトルから受ける印象と違い、数式がたくさん出る濃い内容になっています。これから理論をしっかり学んでいきたい方を対象にしています
- 少しですがChainerやTensorFlowなどのサンプルコードも記載されています
いずれも2016年2月末に刊行されています。
Udacityでの無料講座
Deep Learningの基本が無料で学べる講座。講義の中ではTensorFlowも利用されています。
- Lesson 1: From Machine Learning to Deep Learning
- Lesson 2: Deep Neural Networks
- Lesson 3: Convolutional Neural Networks
- Lesson 4: Deep Models for Text and Sequences
TensorFlowを理解する5つの要素
それでは本題に入ります。TensorFlowの仕組みを理解するうえで、以下5つの要素をおさえておきましょう。
1. dataflow graph(データフロー・グラフ)
- tensorflowの計算処理は、ノードの集合からなる有効グラフによって表現します
- ある種のnodeが、状態の維持、更新を出来るように拡張されています
- 分岐やループが出来るようにも拡張されています
2. tensor(テンソル)
- Tensorflowはテンソルというデータ構造でデータを表現します
- データフローグラフを流れるのがテンソルになります
- 任意の次元を持つ配列、若しくは、リストと考えて問題ありません
- 文字列、整数、浮動小数点等、色々な型の値を格納できます
3. node ( operation = op )(ノード)
- 定数や演算処理を割り当てられます
- Tensorflowではoperation、もしくは略してopとも言う
4. edge(エッジ)
- データの入力と出力の流れを表します
- 具体的には、ノード間を通るテンソルの流れを表します
5. session(セッション)
- データフローグラフで計算を実行するために、まず、セッションクラスをインスタンス化して利用することで、tensorflowのシステムと情報をやり取りできるようになります
- そして、runメソッドを実行します。runされるまで、データフローグラフの演算処理は実行されません
サンプルコードからデータフロー・グラフの作成、演算の実装方法を読み解く
要素を理解したところで、TensorFlowの構造をさぐっていきます。以下はGitHubにあるサンプルコード、Try your first TensorFlow programからの引用です。Try your first TensorFlow program:Tensorの構造を理解する
$ python >>> import tensorflow as tf >>> hello = tf.constant('Hello, TensorFlow!') >>> sess = tf.Session() >>> sess.run(hello) Hello, TensorFlow! >>> a = tf.constant(10) >>> b = tf.constant(32) >>> sess.run(a+b) 42 >>
このサンプルコードはTensorFlowのライブラリーを利用して、次の2点を行っています。
- 「Hello, TensorFlow!」文字列定数を変数に代入して実行
- 「10 + 32 = 42」の計算を実行
上記2点を少し深堀りして、理解を深めてみましょう。
まず1.では constantで文字列定数のopを作成しています。opは、テンソルとしてのデータを保持し、デフォルトのグラフへnodeとして加えられます。ここで、helloの中を見てみるとopに紐付いたTensorオブジェクトなのが分かりますね。
>>> hello <tensorflow.python.framework.ops.Tensor object at 0x7f51a8b800d0>
下のように書き換えると、string型の変数に代入したことになります。
hello = 'Hello, TensorFlow!'
グラフ演算をする必要がなければこのようにプログラミングします。
データフローグラフの作成はできたのでグラフ演算を実行します。グラフ演算を実行するにはSessionクラスをインスタンス化し、オブジェクトのrunメソットを実行する必要があります。
このとき、求めたいテンソルを引数に渡していますね。
そして2.ですが、
>>> sess.run(a+b)
これは
>>> y = tf.add(a, b) >>> sess.run(y)
と同じことですね。
データフローグラフを描くと下記のとおりになると思います。
これと、先ほどのyの中を見て、比べてみましょう。
>>> print y Tensor("Add:0", shape=TensorShape([]), dtype=int32)
テンソルが次元の単位(rank)、形状(shape)、静的な型(type)で構成されているのが見えてきますね。
それでは次にIntroductionを見てみましょう。
TensorFlow Introduction :グラフ演算実装の流れを知る
import tensorflow as tf import numpy as np # Create 100 phony x, y data points in NumPy, y = x * 0.1 + 0.3 x_data = np.random.rand(100).astype(np.float32) y_data = x_data * 0.1 + 0.3 # Try to find values for W and b that compute y_data = W * x_data + b # (We know that W should be 0.1 and b 0.3, but Tensorflow will # figure that out for us.) W = tf.Variable(tf.random_uniform([1], -1.0, 1.0)) b = tf.Variable(tf.zeros([1])) y = W * x_data + b # Minimize the mean squared errors. loss = tf.reduce_mean(tf.square(y - y_data)) optimizer = tf.train.GradientDescentOptimizer(0.5) train = optimizer.minimize(loss) # Before starting, initialize the variables. We will 'run' this first. init = tf.initialize_all_variables() # Launch the graph. sess = tf.Session() sess.run(init) # Fit the line. for step in xrange(201): sess.run(train) if step % 20 == 0: print(step, sess.run(W), sess.run(b)) # Learns best fit is W: [0.1], b: [0.3]
最急降下法というアルゴリズムを利用した、最適化問題の1つです。このサンプルコードでは、yとy_dataの平均二乗誤差lossを最小にするよう学習しています。その際、1回学習する(sess.run(train))ごとに、その時の求めたい値( sess.run(W), sess.run(b))を表示しているのですね。このようにTensorFlowでは、最適化問題を扱うためのクラスが色々揃っています。
上記コードに対応するデータフローグラフは
この処理の流れを単純化してみると
- (何かしらの学習アルゴリズム)
- init = tf.initialize_all_variables()
- sess = tf.Session()
- sess.run(init)
- sess.run(train) ※この学習を繰り返す
深層学習に必須なモジュールNumPy
先ほどのサンプルコードで出てきたNumPyの特徴とメリットを見てみましょう。NumPyとは
- Pythonの拡張モジュール
- SciPy(Pythonの数学・科学・工学モジュール類をまとめたパッケージ)のうちの1つ
- ベクトルや行列、画像などを表現するための配列オブジェクトや線形代数の関数など備わっている
NumPyを使うメリット
- C言語で実装されており高速数値演算に向く
- データが主記憶上で連続した領域に格納されるためCPUサイクルとキャッシュを効率良く使える
深層学習はひたすら行列の計算を繰り返します。ですから行列計算を高速処理できることはきわめて重要です。深層学習ではNumPyライブラリーを大いに使っていきましょう。
煩雑なPythonエコシステムを整理する
さきほど紹介したNumPyなど科学計算のモジュールが豊富にそろうPython。数が多い反面、どのモジュールを使えばいいのか混乱しがちです。科学計算ツールとしてのPythonベースのエコシステムをSciPy(Scientific Pythonの略)と言います。ここではSciPyコアパッケージを整理してみます。[Numpy] 多次元配列のパッケージ | |
[SciPy library] 科学計算用の基本的なライブラリ | |
[Matplotlib] 2次元描画 | |
[IPython] 高機能な対話式のコンソール | |
[Sympy] 記号数学 | |
[pandas] データ構造と分析 |
科学計算環境としてのPythonの歴史を見てみましょう。
1990年代後半からPythonで数値データを扱うためのツールが構築されはじめました。当時開発されたNumericが発展したものがNumPy。このNumPyの上に構築されたのが数値計算アルゴリズムを実装したSciPyです。
2000年代初頭には科学技術用のグラフ描画ライブラリとしてMatplotib、対話型シェルIPythonが続けて開発されました。さらに2000年代後半になるとデータ解析ライブラリのpandas、記号処理用ライブラリのSympyが開発されています。
機械学習の1つである深層学習は主にNumPyを利用します。しかし、機械学習全般となるとエコシステムの多くのモジュールを使うことになります。もし、混乱するようなことがあれば、この概要を思い出して整理すると良いかもしれません。慣れない方には煩雑ではありますが、充実したエコシステムがあるのはPythonの強みです。
おわりに
サンプルコードを使ってTensorFlowの仕組みを見ていきました。データフロー・グラフに関して何か気づきがあった方がお一人でもいましたら嬉しい限りです。
参考書籍
[1] IPythonデータサイエンスクックブック (オライリージャパン)
TensorFlow, the TensorFlow logo and any related marks are trademarks of Google Inc.
お知らせ
ぐるなびでは一緒に働く仲間を募集しています。