深層学習　画像認識1　理論編

[Aidemy](https://aidemy.net/)　2020/11/10
#はじめに
　こんにちは、んがょぺです！バリバリの文系ですが、AIの可能性に興味を持ったのがきっかけで、AI特化型スクール「Aidemy」に通い、勉強しています。ここで得られた知識を皆さんと共有したいと思い、Qiitaでまとめています。以前のまとめ記事も多くの方に読んでいただけてとても嬉しいです。ありがとうございます！
　今回は、深層学習・画像認識の一つ目の投稿になります。どうぞよろしくお願いします。

＊本記事は「Aidemy」での学習内容を「自分の言葉で」まとめたものになります。表現の間違いや勘違いを含む可能性があります。ご了承ください。

今回学ぶこと
・
・


#単純パーセプトロン
##単純パーセプトロンとは
・__単純パーセプトロン__とは、複数の入力を受け取り1つの値（0か1）を出力するものであり、__ニューラルネットの基本単位__である。
・単純パーセプトロンの数式は次のようになる。
$$
\begin{eqnarray}
u = \sum_{i=1}^N w_i x_i + \theta\\
y = H(u)
\end{eqnarray}
$$

・上記式について「u」はそれぞれの入力$x_i$に重み$w_i$をかけたものを合計し、バイアスθを足したものである。これに対して$H(u)$はuが正の時1、負の時0となる__ステップ関数__（活性化関数）と呼ばれるものである。
・このように単純パーセプトロンでは、複数の入力を受け取り、__閾値（今回は0）を越えると発火する__。
・ただし、XOR関数のように、__線形分離可能な場合にのみ使用できる__。これ以外の場合には、後述する__「多層パーセプトロン」__というものを使う。

・コード（実装例）![スクリーンショット 2020-11-09 9.51.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698700/c25e602f-7e6f-9289-9676-0b1fa309efe6.png)

##誤り訂正学習
・上記「w」「θ」は適切に変更していく必要があるが、手作業で変更するのは現実的ではない。このようなときに値の更新を__自動化__してくれる手法が__「誤り訂正学習」__である。
・誤り訂正学習は初めは適当な「w」を与え、入力「x」を与えることで出力「y」を得る。そのyと、正しい出力「t」との差から、以下の式で「w」を更新する。
$$
{\bf w} = {\bf w} + \eta(t_i - y_i){\bf x_i}
$$

・この時、簡単のため重みwは(w1,w2,θ)、入力xは(x1,x2,1)とし、出力uは__「（転置したw）＊x」__で求められるようにする（uの計算式上からθを省略する）。
・$\eta$は学習率である。詳しくは後述。
・式から言えることとして、wはtとyの値が異なり（差が生じ）、かつxが1の時のみ値が更新される。また、y>tの時wは負の方向に更新され、y<tの時wは正の方向に更新される。

・コード
![スクリーンショット 2020-11-09 10.23.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698700/f915c06a-51d6-c0c0-df0b-0ad21a3e4b3c.png)

・出力（＋出力のためのコード）
![スクリーンショット 2020-11-09 10.23.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698700/83eff338-2bbb-9ae4-5d33-4f0529018fbd.png)

#多層パーセプトロン
##多層パーセプトロンとは
・先述の通り、単純パーセプトロンでは__非線形分離の場合__には対応できないという問題点があったが、このようなときに使われるのが__「多層パーセプトロン」__である。多層という言葉通り、層が増えたものがこのように呼ばれる。具体的には「入力層」「出力層」の他に__「中間層（隠れ層）」__を増やす。

・具体的なコードは以下の通り。入力データxについて、単純パーセプトロンと同じ式で「u1」と「u2」を求め、一層目の出力である「z1」「z2」を求め、これらと重みw3とバイアスb3とで「u3」を算出し、「H(u3)」で最終的な出力「y」が求められる。

![スクリーンショット 2020-11-09 11.30.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698700/df45b0c8-579f-9dca-baed-90e6c34d439b.png)

##勾配降下法
・上記で学んだ「誤り訂正学習」では入力が「0or1」の場合以外には対応できない。__隠れ層が増えるとこの手法は使えなくなる__ので、このような場合には__「勾配降下法」__を使用する。
・勾配降下法は__これまでの深層学習でも使われてきた手法__であり、__「誤差関数が最も小さくなるように学習する」__手法である。
・この「最も小さくする」ために使われるのが、__勾配__である。これは__微分__によって求まる。
・ここでも__「学習率」__というパラメータが出てくるが、これは__「一回のステップでどれだけ学習するか」__を調整するパラメータである。この値が大きすぎると求めたい値に収束せず、小さすぎるとその値まで到達するのに時間がかかりすぎるという問題が生じるので、__適切な値を設定する__必要がある。
・学習率の設定は__基本的には探索的に行われる__が、ツールを使って適切な値を求めることもできる。

##活性化関数
・勾配降下法では微分が行われるが、__活性化関数__に今までのステップ関数を使用すると、0か1の出力なので__微分結果が0になってしまう__。よって、この方法を使うときは活性化関数に__別の関数を使う__必要がある。
・例えば__シグモイド関数__や__ReLU関数__などが挙げられる。
・数学的な部分にはなるが、__シグモイド関数__は以下の式で表される。その微分についても記載する。
$$
sigmoid(x) = \frac{1}{1+e^{-x}}
$$
$$
\frac{d}{dx}sigmoid(x) = (1 - sigmoid(x))sigmoid(x)
$$

・コード上でも、このように計算すればシグモイド関数の計算結果を得ることができる。

・__ReLU関数__は__x>=0の場合__は「x」のまま、__x<0の場合__は「0」とする単純な関数であり、「x」は微分すると常に値が「1」になるため、__誤差逆伝播法__で使われることが多い。

##ニューラルネットワークの重みの更新
・ニューラルネットワークでは、重みの更新は__誤差逆伝播__によって求まる誤差関数の勾配方向に更新されていく。このときの勾配の求め方によって、以下の3手法に分けられる。
・一つ目が__「最急降下法」__と呼ばれるもので、__全データを使って求めた勾配__に従って更新するものを指す。ただし、この手法は一度__局所解__に達してしまうとそこから抜け出せなくなるという問題がある。
・二つ目が__「確率的勾配降下法」__と呼ばれるもので、__i番目のデータのみを使って勾配を求め__、それに基づいて全データを更新するというものである。この手法では局所解には陥りにくいものの、一つのデータしか使わないので、そのデータが外れ値だったりすると更新が破綻する可能性がある。
・この問題を減らせるのが、三つ目の__「ミニバッチ法」__である。これは、勾配の算出に使うデータ数__（batch_size）__を自分で決め、それに基づいて更新する手法である。

#まとめ
・ニューラルネットの基本構造は複数の入力を受け取り、一つの値を出力する__「単純パーセプトロン」__である。これに__隠れ層__を追加することで__多層パーセプトロン__となり、非線形分離にも対応するようになる。
・深層学習の重みやバイアスを更新するときには__「誤り訂正学習」__というものも使われるが、中間層が増えるとこれが使えないので、代わりに__「勾配降下法」__が使われる。__誤差関数__を__微分__することで求められた勾配が最も小さくなる部分に向かって値を更新する手法である。
・勾配降下法を使う時は、__活性化関数__に__シグモイド関数__や__ReLU関数__を使う。
・勾配降下法で重みを更新するときに、__全データのうちどれぐらいを勾配の計算に使うか__で手法が異なる。最も一般的に使われるのは、自分でデータ数（batch_size）を決め流処方であり、これを__「ミニバッチ法」__という。

今回は以上です。最後まで読んでいただき、ありがとうございました。