これが一般的な数式による表現ですが、プログラミングでは多くの場合以下の表記を使います。は行と列を入れ替える転置と呼ばれる操作を表す記号です。いうのはいつでも横ベクトルなんですと決めてしまえば、と書くことができます。実はもっと効率の良い計算方法があります。同時に計算させることが可能です。計算させる数式上の表現はとなります。これで一度の計算でたくさんのデータを処理できるようになりました。GPUは元々画像処理のために作られたもので、配列の計算に特化したアーキテクチャを持っています。ニューラルネットの処理を、(メモリを食う代わりに)大きな配列の計算として定義してしまうことでGPUによる高速化が可能になるのです(従って、データを1個ずつ与えるような実装をすればその恩恵は小さくなってしまいます)。コードで見るこれまでに考えてきた写像は以下のとおりでした。これをTensorFlowの(擬似)コードで書きましょう。bと書くことができます。数式での表現とほとんど変わりません。shapeに注意が必要です。これはQ次元の横ベクトルを幾つか並べた行列を入れますと宣言しているのです。Noneの部分は本来ならばデータの数を指定することになりますが、どれくらいのデータを一度に入れるのかは実は学習にある程度影響を及ぼします。後で色々調整して試したいということになるので、Noneでプレースホルダーが任意の数を受け入れるようになっているのです。具体的に決めておいてあげなければなりません。そこでPythonで関数を書く必要が出てくるわけです(別にシコシコ手で書いてもいいですが)。ニューラルネットのアフィン層を作るときは、具体的には以下のようにします。bweightの方は、行列の要素を特殊な正規分布から発生する値で埋めます。別に普通の正規分布を使っても勿論構いません。これはもともとtf.float32で返ってくるので、dtypeの指定を必要としなくなります。biasの方は通常0で埋めておきます。今はshapeがP,Qなどの文字で置かれていますが、このコードはPythonの世界の話であり、実際には具体的に値を与えなければいけないことは勿論注意しておいてください。TensorFlowに渡す準備ができたということです。ニューラルネットの設計2層のニューラルネットワークさて、1つのアフィン層を実装する手立てを手に入れました。実際のニューラルネットワークは多層構造になっており、これを幾つも準備してあげる必要があります。今回は簡単のため2層のニューラルネットを書いてみましょう。ここまで理解していれば何も難しいことはありません。b2たったこれだけで、2層のニューラルネットが定義できました。データの次元が減っていっています。5つ指標を元に、1つの銘柄の株価を出力したい場合などにこういう形を取ることになるでしょう。3クラス分類の問題で、5つの指標から各クラスに属する確率をそれぞれ出力した場合にも同じような設計になります。好きなように設定するしかありません。ニューラルネットワークは活性化関数なるものが層と層の受け渡しの間に入り込んでいます。活性化関数には色々な物があります。s0sem0y.hatenablog.com今回は、基礎となっているシグモイド関数を使ってみましょう。シグモイド関数はという式になります(話の一貫性を保つため、写像の形式で書きます)。これをPythonで定義してあげて、中間層の活性化として使うために以下のように書き換えましょう。sigmoid(x)」はあくまで、「TensorFlowの計算に使うための写像を作る関数」に相当します。いつでもTensorFlowに写像を乗せる準備をしているということを忘れてはなりません。写像を写像しているというわけです。すればという写像が行われるということです。実際には既に基本的な活性化関数はAPIとしてかなり準備されているので、特殊なことをしない限り、ほとんど自分で作る機会は無いでしょう(逆に自分で書けば何でも作れる!)。tf.sigmoid(f1)と書くことで同じことができます。TensorFlowで確認できます。ニューラルネットの順伝播これまでのコードに関して、写像をTensorFlowに渡し、順伝播の準備を完了するためには以下のコードを書く必要があります。tf.global_variables_initializer()sess.run(init_op)特に青い字に注意してください。tf.Sesstion()」によって今まで作ったPython上で作った写像をTensorFlowに渡すことができるというのは説明してきました。青い字の部分は、TensorFlow上に準備された写像を初期化することに相当します。これはTensorFlowに渡した写像の中にtf.Variableの型がある限り、必ず行わなければなりません。Variableの型が無ければ必要ありません。これらを踏まえて順伝播を実際に行う全体のコードは以下です。sess.run()の1つ目の引数は写像です。従って、実行したい写像を指定してあげれば、その値を好きなように取り出すことができます。TensorFlowの実際tf.InteractiveSession()これまで、TensorFlowの中に写像を作ってあげるために、Pythonでそれらを記述してきました。tf.Session()」によって写像を渡してあげていました。今まで作り上げてきた写像たちは、まるまる一気にTensorFlowで合成写像の形として認識されます。今回作った簡単なネットワークならまだしも、もっと大規模な合成写像(ディープなネットワーク)を構築したいとなった時に問題が生じてきます。写像の定義に対して人為的なミスが生じる可能性があるのです。中間層から中間層へのデータの受け渡しの際、データのサイズが異なってて上手くいかないということが起こるかもしれません。プログラム上は大丈夫でも、自分の意図していない構造になっているかもしれません。そこで「tf.InteractiveSession()」が有効に使えます。tf.Session」では写像を全て作り終えてからしか渡しませんでしたが、「tf.InteractiveSession」では、Pythonの世界で定義した写像をTensorFlowの世界に順次追加していくことができます。することができるのです。中途半端な位置にあっても構いませんが、とりあえず先にTensorFlowの世界を開いておいてもいいということです。こいつのお陰でニューラルネットを随時正しく伝搬できるか確認しながら構築していくことができます。当面はそのような大規模なものは作らないと思われますが、TensorFlowは研究ではなく実用の用途でも使えるように意識されており(Googleでは開発にも使われている)、このような便利な機能も備えているというわけです。順伝播を試してみるプレースホルダーに値を入れてみて、出力値を確認しましょう。})実は上記のコードはエラーを吐きます。赤字の入力がリストになっているためです。TensorFlowの世界にプレースホルダーを通して値を渡すときは、「np.float32」あるいは「np.float64」のいずれかに統一されていなければなりません。従って以下に変更します。})実はこれでもエラーを吐いてきます。実はplaceholderの型に注目してください。Q])行数はNone(任意のデータ数)であり、列数がQ(データの次元:今回の場合5)の2次元配列です。今numpyの配列は単なる1次元配列になっているので以下のように明示的に、2次元配列にしてあげなければなりません。})numpyの配列は通常、何も宣言しなければnp.float32になるので、実はこちらは明示しなくてもいいですが、今後、もっと複雑なデータ型を渡すようになると、必ず一度は経験するエラーになるので、予め意識しておきましょう。sess.runから出てくる返り値はnumpyの配列になっています。「sess.run」はいつでもPythonの世界とTensorFlowの世界の架け橋です。最後に今回は順伝播までを見てきました。ニューラルネットの本当の始まりは学習にあります。次回からは学習の方を取り扱いますが、TensorFlowをマスターするための肝は順伝播を正しく記述する方です。従ってここまでをキッチリ理解できているのとそうでないのとでは全く違います。学習の方は、実を言うとPythonの世界であれこれやる必要がほとんどありません。TensorFlowの学習の仕方というのはある程度決まっているため、ほとんどがモジュール化されており、私達はそれを呼び出す処理を書くだけになります(つまり、各手法に対してしっかり理解することが重要であって、Python上で何か特別に書く必要はあまりない)。従って私達がやるのは、狙い通りの写像を構築することであって、そちらが実際のコーディングでもメインになるのです。いうわけで、次回からは学習について取り扱いますが、特に学習手法に関する理解をした上で、TensorFlowを使いこなすことを狙っていきます。いう言葉は数学的にはいずれも全く同じ意味であって区別の必要はありません。定義していく」などという表現になってしまい、ややこしく感じたため避けました。同じ意味であり、作用素のことを英語で「Operator」と言います。TensorFlowのDocumentでは基本的にOperatorという言葉が利用されています。計算グラフというのは写像をグラフィカルに扱う体系であって、結局動作は一緒です。数式ベースの写像をグラフィカルに見ようとしたり、あるいはグラフ構造を数式ベースで考えたかったり、数学では色々な場面があります。一方では難しく見えることが他方では簡単に視えたりするのです。その例が誤差逆伝搬法であり、計算グラフで見たほうが容易です。一度分かったら、基本的に数式ベースの方がプログラミングとの親和性も高く、頭の省エネになります。いうわけで計算グラフを意識することは今回は避けました。以下の書籍は、ニューラルネットをnumpyで実装していく本であり、コードベースでニューラルネットの処理を理解していくことができます。現状、理解を促す上で最も良い本です。数式ベースで理解できている人は、単純にnumpyの練習になるくらいであり、実用的なネットワークはフレームワークを利用することになるので不要だと思われます。s0sem0y.hatenablog.com以下の分類を行うニューラルネットやSVMが、どのようにして分類を達成しうるのか、その共通した考えについて述べています。s0sem0y.hatenablog.com機械学習で現れる数式について最低限分かるレベルになってほしいものをまとめています。「かなり深くまで学ぶ」というよりは、本当にこれだけは知っておいて欲しいというものについてあっさり触れています。次は設計したニューラルネットワークを学習させる方法を書いていきます。これは今まで同様、学習を行う写像を定義していけばよいのですが、学習の写像はバックプロパゲーションとして知られており、非常に難易度の高い数式となっています。学習の写像に関してはニューラルネットは共通の方法を取るため、TensorFlowで与えられたAPIを用いて記述していきます。»プロフィール自分が勉強していく上で学んだことなどをまとめていきたいと思います。ML_deepスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。