IT + X

ITと何かのコラボレーションは時代を変えるかも

ディープラーニングは難しくない

ディープラーニングという言葉は今では専門家だけでなく多くの人が知るようになりました。
自動運転車や顔認識などニュースや身の回りで使われるようになっているから広く知られるようになったのでしょうが、ディープラーニングがどのようにして動いているのかエンジニアでも知らない人も結構います。
今回、集中的にディープラーニングについて学んだのでそのまとめと学んでいて感じたことを書いておこうと思います。

まず、ディープラーニングを学ぼうと思った時に本屋さんで色々見てみたのですが、その多くが数学の教科書みたいなものばかりでした。
大学で発展してきた技術なので仕方ないのでしょう。
しかし、実際に学んでみて思ったのが、線形代数や確率などの数学は使う分にはそこまで数学は必要ではなく、実際のプログラムではライブラリが難しい部分をやってくれるのでがちで数学が必要なところはそんなにありません。
後、ほとんどの本が詳細なところにフォーカスしていて全体的にイメージしにくいと思いました。
著者が学者かエンジニアの人ばかりなので細かな所に気が行ってしまうのでしょうが、私のような初心者には全体をイメージできるほうが理解がしやすいなと感じました。
そんな中で比較的理解できたのが次の2冊でした。

この本はPythonを使ったディープラーニングの本ですが、極力ライブラリを使わず底辺から作っていくスタイルなのでディープラーニングのしくみを学ぶにはとてもいいと思います。
数学の記述も多少ありますが、高校レベル+線形代数の基礎くらいで読みとけるのでそんなに難しくないと思います。

PythonとKerasによるディープラーニング

PythonとKerasによるディープラーニング

この本もPythonを使っていますが、TensorFlowやKerasなどのライブラリを使っています。
前の本はゼロから作っていましたが、こちらの本ではライブラリを使うので実践で使うにはこちらのほうがいいかもしれません。

後、ネットの情報などでも色々学んでみて思ったのはディープラーニングの基本的なアイデアは単純だということでした。
ディープラーニングの元となるニューラルネットのアイデアは20年以上前からあったらしいのですが、最近ブレイクしたのはコンピュータの処理能力が上がったからでした。
なので、色々学ぶことは多いですが基本はシンプルですので理解するのはそんなに難しくないと思います。
では、ディープラーニングについて詳しく説明していきましょう。

ニューロン

ディープラーニングの元々のアイデアは生物の脳の研究が元になっています。
未だに生物の脳がどう動いているかは解明されていませんが、その基本要素である神経細胞ニューロン)はどう動いているかはわかっています。
f:id:anthony-g:20190927123555p:plain この図のようにニューロンは電気信号を伝える細胞で、複数の入力と一つの出力を持つ素子になっています。
そして、入力信号がある閾値を越えるとニューロンが発火し信号を出力します。
ディープラーニングはこのアイデアを元にコンピューター上で実現された技術です。

ニューラルネット

では、このアイデアディープラーニングではどう使われているのでしょうか?
ここでニューラルネットというものが出てきます。
ニューラルネットとは、ニューロンを複数束ねてそれぞれを信号線で接続した形のものを言います。
下図のようなものが一例です。

f:id:anthony-g:20190927124302p:plain

ニューロンを複数持つグループが層になっていてそれぞれ接続されているものをニューラルネットといいます。
図のように入力層、隠れ層、出力層と呼ばれる層で構成されていてこの順番で信号が流れます。
この隠れ層が100以上持つようなニューラルネットディープラーニングでは使われます。
当たり前ですが、この層が増えるに従ってマシンパワーが必要になります。
ディープラーニングがコンピューターの能力が上がらないと実現できなかった技術であることがこれで理解できると思います。

ディープラーニングワークフロー

ディープラーニングでは、データを読み込んで学習し、学習結果が正しいかをテストした後にAIとして使えるようになります。
ディープラーニング入門でよく使われる手書き文字認識の例で具体的に説明します。 まず、コンピューターに学習させるために教師データというものを用意します。
この例では、教師データは手書き文字画像とそれがなんの文字であるかを表すラベルがペアになっています。
その教師データをニューラルネットに大量に入力します。

f:id:anthony-g:20190927131627p:plain

この学習の処理がディープラーニングで一番負荷のかかる処理です。
学習の結果、ニューラルネットが手書き文字認識のために最適化されますので、それがちゃんと正しいかをテストします。
テストデータは学習したときと同じ形式のデータを使いますが、データ内容は別のものを用意します。
なぜなら、学習データに都合のいいニューラルネットになっていないかをチェックするためです。
ニューラルネットには過学習という問題があり、特定のデータに過度に最適化されると違うタイプのデータをうまく処理できなくなるからです。

f:id:anthony-g:20190927132458p:plain

何を処理するかにもよりますが、正解率99%以上が現実に使えるニューラルネットのようです。
そして、テストで問題なければ実際のデータで画像認識を行います。

f:id:anthony-g:20190927133107p:plain

これが一般的な機械学習処理のワークフローになります。
では、ニューラルネット上で学習処理はどう行われているのかを次に説明します。

学習とはニューラルネットの重みデータの最適化

前にニューラルネットは層で別れていてニューロン同士が接続されている構成をしていると説明しました。

f:id:anthony-g:20190927124302p:plain

この図ではニューロン同士がフルメッシュで接続されていますが、特定のニューロンの接続だけを取り出したのが次の図になります。

f:id:anthony-g:20190927133906p:plain

b, x1, x2のニューロンとyのニューロンが接続されていて、b, x1, x2から入力されたデータがyで出力されるということを表しています。
ここで大事なのがw1, w2という値で「重み」と呼ばれている値です。
これはニューロン間の接続に付随する値で、w1はx1にかけられw2はx2にかけられます。
ちなみにbはバイアスと呼ばれていてニューロンの発火のしやすさを制御します。
この例では右にある方程式の計算が行われて計算結果が0より大きければyは1、0以下ではyは0となるニューラルネットを表しています。
先程の手書き認識の例でいうとx1,x2は入力画像データです。
そして、w1, w2は学習処理のときに設定されます。
つまり、機械学習とはこの重みデータを最適な値に設定する処理のことをいいます。
これはすごくシンプルな考え方だと思いませんか?
私が最初にこのことを理解したとき、機械学習ってこういうことなのかと目からウロコでした。
つまり、重みの値を変えることによって手書き文字が読めるようになったり翻訳できるようになったりするのです。
実際は、後で説明するように特殊なニューラルネットを使ったり速度を上げるためのテクニックとかあるのですが、基本はこれです。
これを抑えておけばあとはTipsみたいなものと考えていいと思います。

あともう一つ説明しなければいけないのが活性化関数についてです。
前に、ニューロンは入力によってしきい値を越えると発火すると言いました。
したがって、どのような値で発火するか判定する関数を定義する必要があります。
それが活性化関数です。
上のニューラルネットの図のyのニューロンで重みをかけて計算した結果を活性化関数に渡しています。

f:id:anthony-g:20190927154640p:plain

上図の右の方程式は、重みによる計算結果を活性化関数に与えてニューロンが発火するかどうかを判定しています。
活性化関数としてはシグモイドとReLUが代表的ですが、グラフにあるようにある閾値を越えるとyの値が増えるのがわかると思います。
活性化関数もライブラリで用意されてますので引数を渡して呼べばいいだけです。

では、重みデータの最適化はどのように行われるのでしょうか?
最初は、重みデータは0で初期化されていたりランダムな数値が設定されていたりします。
それを、教師データを読み込んで正解と予測値を比べて差異がなくなるまで繰り返し試行錯誤を行います。

f:id:anthony-g:20190927153013p:plain

上の図で損失関数というのが正解と予測値の差を求める関数で、オプティマイザーは差の値を元にニューラルネットの重みデータを更新します。
損失関数には二乗和誤差とか交差エントロピー誤差などがあり、オプティマイザーのアルゴリズムもRMSPropやAdamといったものがありますが、扱うケースによってライブラリのパラメータで指定することができますので内部の詳細なアルゴリズムまで知らなくても使うことができます。
(もちろん、興味のある方はぜひ勉強してみてください。)

CNN(畳み込みニューラルネット

ディープラーニングが一番脚光を浴びたのは画像認識です。
動物や人の顔を見分けたり地形を検知したりいろんなところで応用されています。
画像認識でよく使わるのが畳み込みニューラルネット(Convolutional Neural Net)と呼ばれるものです。

f:id:anthony-g:20190927155613p:plain

上図に畳み込み層とプーリング層というのがあると思いますが、これは画像の特徴あるところを抽出する層です。
詳細は本を読んでいただいたほうがいいと思いますが、例えば人が猫の写真を見た場合、顔の形とか目などの特徴を抽出して判断しているらしいのですがそれと似たことをCNNでも数値処理として行っています。
後、ソフトマックスというのは複数の値を出力するための層で、例えば猫である確率と犬である確率と人である確率を出したい場合は3つの出力を持つソフトマックスということになります。
そして、いまやディープラーニングは人間の認識能力を上回るようになりました。
人間でも気づかないような特徴をコンピューターが認識できるようになったということなのでしょうね。

RNN(リカレントニューラルネット

ただ、CNNには過去のデータを覚えられないという弱点があります。
例えば、文脈で判断する必要のある文章や過去の動作情報が必要な対物検知など時系列のデータを扱うものには使えません。
そこで考えられたのがリカレントニューラルネット(Recurrent Neural Net)です。

f:id:anthony-g:20190927160611p:plain

上図左のRNNが一つのニューラルネットを表していて、自分の出力を入力に再投入します。
右図は詳細の図で、前のニューラルネットの結果を次のニューラルネットに入力することによって前のデータの反映した出力を行うことができます。

かなりざっとした説明になってしまいましたが、ディープラーニングを学ぶ上でこれだけ前知識があれば本を読む時にかなり理解しやすいと思います。
特にご紹介した2冊は私が見た中では一番わかりやすいのでぜひ読んでみてください。
また、ネタが溜まってきたらブログでまとめたいと思います。