高校数学でわかる深層学習(Deep Learning)

高校数学でわかる深層学習(Deep Learning)

前回の記事では,現在のAIの中核を担っているのが深層学習(Deep Learning,ディープラーニング)と呼ばれる技術であることと,深層学習を用いてどのようなことが可能になるのかという点について簡単に紹介しました.

今回は深層学習とはどういったものなのかを,なるべくわかりやすく解説しようかと思います.この記事を一通り読めば,深層学習でどのようなことが行われているのかがある程度理解できると思います.

記事の信頼性

私は実際に深層学習の研究をしていて,研究歴は5年ほどです.

スポンサーリンク

深層学習とは

深層学習の基本概念は関数です.関数とは,何かしらの入力があって,それに対する出力を出すものです.

例えば,

  • 画像という入力を受け取り,画像に写っている物体の名称を出力するシステム.
  • 現在の将棋の盤面情報という入力を受け取り,次の一手を出力するシステム.

こういったシステムを深層学習で作ることができます.

深層学習の基本概念は関数.何かしらの入力に対して出力を出すシステム.

深層学習 = 多層ニューラルネットワークを用いた機械学習の方法論

深層学習とはずばり,多層ニューラルネットワークを用いた機械学習の方法論のことです.

ここで,「機械学習」,「多層ニューラルネットワーク」という見慣れない単語が出てきたかと思います.この「機械学習」と「多層ニューラルネットワーク」について理解することで,深層学習について理解することができるので,順番にわかりやすく説明したいと思います.

深層学習とは,多層ニューラルネットワークを用いた機械学習の方法論の1つ.上記の例では,多層ニューラルネットワークを用いて,入力画像の物体の名称を答えるシステム.

機械学習(Machine Learning)とは

機械学習とは,コンピュータがデータからそのデータに含まれている規則性やパターンを抽出する関数を獲得する方法のことです.

なんだかよくわからないかと思いますが,実は我々人間も日々機械学習をしています.例えば,リンゴをリンゴと認識する処理をものすごく簡略化して図で示すと,以下の様になると思います.

データというのはリンゴの画像のことを指し,機械学習によって獲得する関数というのは人間で例えると脳のことを指します.

データに含まれる規則性やパターンというのは,上に示したリンゴの場合だと,

  • 色が赤い
  • 形が丸い
  • ヘタがある

といったリンゴをリンゴと認識するのに必要な手がかりや情報のことを指します(この情報のことを特徴量と呼びます.もちろんリンゴを認識するために必要な手がかりである特徴量は人によって様々です).

我々も初めてリンゴを見たときは何であるかわからないはずです.しかし,これがリンゴという果物であるということを誰かに教えてもらうことで,赤くて丸くてヘタがあるものはリンゴであると学習すると思います.そして次にリンゴを見たときは,それらの特徴に着目することでリンゴであると認識できるはずです.

これと全く同じことをコンピュータにさせることを機械学習と呼んでいます.

そして,上の図の脳の部分にあたるところを多層ニューラルネットワークと呼ばれるモデルで置き換え,人間と同じようにリンゴを認識できるようにすることを,深層学習(Deep Learning)と呼んでいます.

そして,深層学習が現在注目を集めているのは,リンゴを認識するために必要な特徴量(色や形など)を人間が与えなくても自ら特徴量を見つけ出し,リンゴを認識することができる点にあります.従来の機械学習技術では我々人間があらかじめ特徴量を考え,コンピュータに与える必要がありました.

つまり,深層学習を使用することで,物体を認識するための特徴量を多層ニューラルネットワークが自動で見つけ出し,物体を高精度に認識することが可能になります.今回は画像を例に扱っていますが,もちろん文章や音声情報なども深層学習で扱うことが可能です(例えば,日本語と英語の翻訳などにも深層学習が応用されています).

深層学習を用いることで,認識に必要な特徴量も自動で獲得することが可能.

スポンサーリンク

多層ニューラルネットワークとは

多層ニューラルネットワークとはニューラルネットワークと呼ばれるモデルを多層にしたモデルです.

ニューラルネットワークというのは生物の神経回路網を模倣した人工モデルで,図で表すと以下のようになります.

3層のニューラルネットワークの例

ニューラルネットワークは入力層,中間層,出力層と呼ばれる層で構成されており,上の図は入力層,中間層,出力層がそれぞれ1層の合計3層からなるニューラルネットワークになります.

各◯はノードやニューロンと呼ばれ,それぞれ次の層のノードと結合しています.

上の図では中間層の数は1層ですが,この中間層の数を2層,3層...と増やして多層にした以下のようなモデルが多層ニューラルネットワークとなります(入力層と出力層の層数は基本的に1層のままです).このように多層にすることでより優れた性能を発揮することが可能になります.

多層ニューラルネットワークの例

ニューラルネットワーク

それでは例として,3層のニューラルネットワークを使ってリンゴとミカンを見分ける方法について説明します.このときのニューラルネットワークの構造は以下のようになります.

リンゴとミカンを見分けるニューラルネットワークの例

ニューラルネットワークには画像X (リンゴ or ミカン)を入力し,最終的にニューラルネットワークから出力されるものは,画像Xがリンゴである確率とミカンである確率の2つの値になります.

そのうち,確率が大きい(値が大きい)方を最終的な認識結果とします.そのため,理想的にはリンゴの画像を入力したときはリンゴである確率が高く,ミカンの画像を入力したときはミカンである確率が高くなるように,ニューラルネットワークが出力することが理想になります.

それでは各層での具体的な処理について説明していきたいと思います.

入力層

まず,入力層の説明に入る前にコンピュータが画像をどのように捉えているのかを簡単に説明します.

画像は画素(pixel, ピクセル)と呼ばれるものが並んだデータ構造で,各画素には「赤らしさ」「緑らしさ」「青らしさ」を表す3つの値が保持されています(下図).

画像は画素の集合で構成されている.各画素はRGBの3原色でその画素の色を表現する.

小さい頃に絵の具で,青色と緑色を足したら黄色になり,さらに緑を多く足したら黄緑になった,という経験はあるのではないでしょうか.これと同じで,基本的に赤緑青の3色の量の加減で色は表現することが可能です.

一般に,RGBの各値は0から255の整数値で表されることが多いです.

それでは,入力層について説明したいと思います.といっても以下の図で示すように,入力層は画像の画素値をそのままコピーするだけです.

各画素にはRGBの3つの値があるので,それぞれを入力層の1つのノード(下図の◯)に割り当てます.仮に,画像のサイズが縦横256✕256画素のカラー画像だった場合は,入力層のノード数は196,608個(= 256✕256✕3)になります.

入力層は画像のデータをそのままコピーするだけ

中間層(隠れ層)

続いて,ニューラルネットワークの根幹をなす中間層について説明したいと思います.

中間層の各ノードでは,前の層の出力値を変形し,次の層に渡す,という計算を行います.この計算を図で表すと以下のようになります.

中間層の計算方法

中間層での計算には,前層での出力値\(x_1\),\(x_2\),\(x_3\),各ノードに割り当てられた重みパラメータ\(w_1\), \(w_2\), \(w_3\),バイアス\(b\),活性化関数\(f\)を使用します.

一瞬難しそうに見えますが,計算方法はものすごくシンプルで,入力されてくる値(ここでは\(x_1\)〜\(x_3\))に対して,対応する\(w_1\)〜\(w_3\)をそれぞれ掛け算して,それらを足したものに活性化関数を適用したものが\(y\)の値になります.この\(y\)を次の層のノードに渡す形になります.

例えば,上図の青枠で囲まれた部分の計算は以下のようになります.

$$y=f(\sum_{i=1}^{3}x_iw_i+b)=f(x_1w_1+x_2w_2+x_3w_3+b)$$

この計算を入力層に近い中間層の各ノードから順番に計算していき,最終的な出力値を出力層に渡します.入力層に一番近い中間層の場合,入力情報である\(x\)は画像の画素値そのものになります.

活性化関数にはReLUと呼ばれる関数がよく使用されており,数式で表すと\(f(x)=max(0, x)\)になります.ReLUでは入力\(x\)の値が負であれば0を,そうでなければ\(x\)の値そのものを返す関数です.なぜこのReLUが活性化関数として使用されているのかはまた別の機会に説明したいと思います.

この中間層での計算に必要なものは各ノードの重みパラメータ\(w\)とバイアス\(b\)になりますが,これらの値の設定方法については,後で説明します.今は,中間層では適当な値をもつ\(w\)と\(b\)を使って,入力の値を変形する,といった点をおさえておいて下さい.

中間層の層数やノード数によって重みパラメータ\(w\)の個数も変わり,ニューラルネットワークの性能も大きく変わってきます.しかし,ある決まった数の層数やノード数を使用すれば良いといった答えはなく,これら層数やノード数を変更しながら性能を逐一確認するといった試行錯誤がよく行われています.

出力層

最後に,出力層について説明したいと思います.

上述したように,画像認識に用いるニューラルネットワークの出力は確率で表現されます.今は例としてリンゴとミカンを見分ける問題を扱っているため,出力層のノードの数は2つで,それぞれのノードはリンゴである確率とミカンである確率をもちます.

中間層からの出力値は確率になっていないので,出力層でsoftmaxと呼ばれる関数を使って,確率の表現に変換します.softmaxは以下の式で表現されます.

$$y_i=\frac{e^{x_i}}{\sum_{k=1}^{N}{e^{x_k}}}$$

例えば,出力層への入力値が\(x_1=3\),\(x_2=1\)だとしましょう.このときの最終的なニューラルネットワークの出力値は,

$$y_1=\frac{e^{x_1}}{\sum_{k=1}^{2}{e^{x_k}}}=\frac{e^{x_1}}{e^{x_1}+e^{x_2}}=\frac{e^{3}}{e^{3}+e^{1}}=0.8808 (=リンゴである確率)$$

$$y_2=\frac{e^{x_2}}{\sum_{k=1}^{2}{e^{x_k}}}=\frac{e^{x_2}}{e^{x_1}+e^{x_2}}=\frac{e^{1}}{e^{3}+e^{1}}=0.1192 (=ミカンである確率)$$

のように計算され,入力画像のリンゴである確率とミカンである確率を求めることができました.上の例では,リンゴである確率の方がミカンである確率よりも高いので,「リンゴ」がニューラルネットワークの予測結果となります.

ここで出力層の2つの出力値を合計すると,\(0.8808+0.1192=1.0\)となることがわかるかと思います.このように,softmax関数を適用することで確率表現に変換することができます.そして,出力層のそれぞれのノードが持つ数値は,入力画像がそれぞれのカテゴリに属している確率を表します.

ここまでのまとめ

さて,ここまでの内容を簡単にまとめておきたいと思います.

  • ニューラルネットワークは入力層,中間層,出力層で構成されている.
  • 入力層には画像の画素値がコピーされる
  • 中間層では入力の値を重み\(w\)とバイアス\(b\)を用いて,変換していく.
  • 出力層では中間層で変換された値を,softmax関数を用いて確率の形になおす.

さて,ここで1つの疑問として,中間層で用いる重みパラメータ\(w\)と\(b\)の値をどのように決めるのか,という点が出てくるかと思います.

一般的に\(w\)と\(b\)の値は最初はテキトーにランダムに決めることが多いです.そのため,リンゴの画像をニューラルネットワークに入力しても,出力値のリンゴである確率が高くなるかはランダムになります.

そこで次のステップとして,リンゴの画像を入力したときはリンゴの確率が,ミカンの画像を入力したときはミカンの確率が高くなるように,中間層のパラメータである\(w\)と\(b\)を調整する必要があります.この調整のことをニューラルネットワークの学習と呼び,人間が用意した大量の教師データを用いてニューラルネットワークの学習を行います.

教師データはリンゴの画像(=データ)とその画像がリンゴであるという情報(=ラベル)のペアのこと

重み\(w\)の調整 = ニューラルネットワークの学習

ニューラルネットワークの特徴は,大量の教師データから重みパラメータの値を自動で決定できる点にあります.

データから重みを調整できるというのはとても優れた特徴です.なぜなら,実際のニューラルネットワークの重みパラメータ\(w\)の数は数万〜数億になることもあるので,それらをすべて手作業で決めるとなると,それはもう相当大変な作業になるからです.

それでは,中間層の重み\(w\)とバイアス\(b\)をどのように調整するのかについて説明したいと思います.以降では簡略化のために,重み\(w\)の調整についてのみ言及します(バイアス\(b\)も同様に調整可能なため).

重み\(w\)の値の調整には,

  • ニューラルネットワークの出力と人間が与えた正解(ラベル)との誤差を損失関数で測り,
  • その誤差を最小化するように誤差逆伝播法によって各層の\(w\)を更新

といったことを行います.それぞれ詳しく見ていきましょう.

損失関数(Loss function,目的関数)

損失関数は,現在のニューラルネットワークの出力と人間が与えた正解(ラベル)との誤差を測り,どれだけ現在のニューラルネットワークの性能が悪いかを数値で示してくれるものです.

具体的な例を交えながら,説明していきましょう.

今回のようなリンゴとミカンを認識するようなタスクでは,交差エントロピー誤差(Cross entoropy error)と呼ばれる損失関数がよく用いられます.交差エントロピーは以下の数式で表されます.

$$loss=-\sum_{k=1}^{K}t_k{\rm log}y_k$$

\(y_k\)はニューラルネットワークの出力,\(t_k\)は正解ラベルを表します.リンゴの画像に対するラベル情報\(t\)は次のような2個の数値(確率)からなるデータになります.

t=[1.0, 0.0]   # 人間が与えたラベル情報. 1番目の数値がリンゴ,2番目がミカンである正しい確率を表す.

一方,ミカン画像に対するラベル情報\(t\)は次のようになります.

t=[0.0, 1.0]  # =リンゴである確率0%, ミカンである確率100%

このようにそれぞれのカテゴリに一致する部分の数値を1に,それ以外を0にすることでラベル情報は表現されます(one-hot表現と言います).

それでは実際に交差エントロピー誤差を計算してみましょう.例えば,リンゴの画像をニューラルネットワークに入力したときに,以下の出力\(y\)が得られたとしましょう.

y=[0.6, 0.4]   # 1番目の数値がリンゴである確率,2番目がミカンである確率を表す.
t=[1.0, 0.0]   # 人間が与えたラベル情報.yと同じく1番目の数値がリンゴ,2番目がミカンである正しい確率を表す.

このときの交差エントロピー誤差は,次のようになります.

$$loss=-(t_1\times{\rm log}y_1+t_2\times{\rm log}y_2)=-(1.0\times{\rm log}0.6+0.0\times{\rm log}0.4)=-{\rm log}0.6=0.51$$

 

続いて,もし,ニューラルネットワークの出力が\(y=[0.1, 0.9]\)だった場合,交差エントロピー誤差は

$$loss=-(t_1\times{\rm log}y_1+t_2\times{\rm log}y_2)=-(1.0\times{\rm log}0.1+0.0\times{\rm log}0.9)=-{\rm log}0.1=2.30$$

となります.

このように正解ラベルである\(t\)に近い出力結果\(y\)をニューラルネットワークが出力すると小さい値を示すように交差エントロピー誤差は設計されています.

つまり,損失関数の値をみることでニューラルネットワークの性能の良し悪しがわかり,損失関数の値を最小化するように(=ニューラルネットワークの出力をラベル情報に近づけるように)重み\(w\)の値を調整していけば良いことがわかります.

言い換えると,最適な\(w\)を見つけたとき,誤差関数の値は\(0\)(もしくは最小値)になるということです.交差エントロピー誤差の場合,ニューラルネットワークの出力とラベルが完全に一致したときには\(0\)となるため,交差エントロピー誤差が\(0\)となるような重み\(w\)の値を以下で説明する誤差逆伝播法によって調整します.

微分可能であれば損失関数には任意の関数を用いることができます.最近では,よく使用される代表的な損失関数にプラスして独自の損失関数を組み合わせた研究などがよく発表されています.

1つの教師データだけでは重みの調整を行うことは難しいため,N個の教師データを用いてニューラルネットワークの学習を行います.つまり,N個のデータに対する損失関数の値の総和\(L\)を最小化するように,重み\(w\)を調整します.

$$L=-\frac{1}{N}\sum^N_{n=1}t_n{\rm log}y_n$$

微分による重み\(w\)の調整

ニューラルネットワークの学習では,損失関数の値がなるべく小さくなるように,各層の重み\(w\)を調整します.ここで,損失関数の値を小さくするために,損失関数に対する重み\(w\)の偏微分を計算し,その微分の結果を手がかりに重み\(w\)の値を調整していきます.

例えば,以下のニューラルネットワークのある重み\(w_{11}\)に注目しましょう.

この重み\(w_{11}\)の損失関数に対する偏微分\(\frac{\partial L}{\partial w_{11}}\)は,「重み\(w_{11}\)の値を少しだけ変更したときに,損失関数の値\(L\)がどのように変わるか」を意味します.

つまり,偏微分\(\frac{\partial L}{\partial w_{11}}\)の値が正であれば,重み\(w_{11}\)の値を負の方向に変化させることで,損失関数の値を小さくすることができます.逆に,偏微分の値が負であれば,\(w_{11}\)を正の方向に変化させることで損失関数を小さくすることができます.

この操作を数式で書くと,以下のようになります.

$${\acute w}_{11}=w_{11} – \gamma\frac{\partial L}{\partial w_{11}}$$

\({\acute w}_{11}\)が変更後の新しい\(w_{11}\)の値になります.\(\gamma\)は更新の量を表し,ニューラルネットワークの学習率(learning rate)と呼ばれます.

この式は一回の更新を表しており,この更新を何回も何回も繰り返し行い,重み\(w_{11}\)の値を更新していき,損失関数の値を減らしていきます.

同様の更新を他のすべての重み\(w\)についても行います.これがニューラルネットワークの学習になります.

誤差逆伝播法による効率的な重み更新

上記の重み更新を効率的に行う方法が誤差逆伝播法(back-propagation)と呼ばれる手法です.具体的に例を示しながら説明していきます.

まず,以下の数式があるとしましょう.

$$L = t^{3}$$

$$t = x + y$$

このとき,\(L\)に対する\(x\)の偏微分\(\frac{\partial L}{\partial x}\)を求めたい場合,高校数学で習った合成関数の微分の公式を用いると,以下のように計算できます.

$$\frac{\partial L}{\partial x}=\frac{\partial L}{\partial t}\frac{\partial t}{\partial x}=3t^{2} \cdot 1=3t^2=3(2x+y)^2$$

では,この上記の計算を下図のようにニューラルネットワークと同じ形式で表してみましょう(下図の黒線).

\(\frac{\partial L}{\partial x}\)を図で計算すると上記のようになる.各ノードでの偏微分を乗算して伝搬していくことで,任意の場所の偏微分を求めることができる.

\(\frac{\partial L}{\partial x}\)を求めるために,出力の\(L\)から逆に計算を辿っていきます(上図の赤点線).そして,各ノードの局所的な偏微分を求めて,それを乗算して伝達していくことで任意の場所の偏微分を求めることができることがわかるかと思います.

ニューラルネットワークは上図で示したように,微分可能な演算を入力情報に対して適用していくだけですから,各ノードの偏微分を計算し乗算していくことで,上記と同様に任意の場所の重み\(w\)の偏微分を求めることができます.

上記のようなアプローチをとる利点は以下の通りです.

  • 出力からの計算結果を伝搬させて計算することで,途中の計算結果をほかの偏微分計算に利用できるため計算効率が良い.例えば,上図で\(\frac{\partial L}{\partial x}\)と\(\frac{\partial L}{\partial y}\)を計算する際に,\(\frac{\partial L}{\partial t}\)の計算結果を利用できる.
  • 全体がどんなに複雑な計算であっても,局所的な偏微分の計算だけで任意の場所の偏微分を計算可能

これらの利点のおかげで,ニューラルネットワークが大きくなっても高速に偏微分を計算し,各重みパラメータを更新することが可能です.

ここまでのまとめ

  • ニューラルネットワークの性能の良し悪しは損失関数と人間が与えたラベル情報によって,定量的に測ることができる.
  • 損失関数の値を最小化するように,各重み\(w\)を調整する.
  • 損失関数の値\(L\)に対する重み\(w\)の偏微分\(\frac{\partial L}{\partial w}\)を計算し,利用することで調整可能.
  • 上記の調整を効率良く行うための方法が誤差逆伝播法.
スポンサーリンク

さいごに

さて,一気に説明をしてきましたが,いかがだったでしょうか.この記事を通じて少しでも深層学習について理解が深まっていただけたら幸いです.

こちらの記事では,画像を深層学習で扱う際に,最もよく使用されている畳み込みニューラルネットワークについて解説していますので,よろしければ参考にしてください(適宜更新していく予定です).

また,以上で説明したアルゴリズムをPythonなどのプログラミング言語で書くことで,深層学習を実際に実現することができます.具体的なプログラム例などはこちらで紹介していますので,よろしければ参考にして下さい.

タイトルとURLをコピーしました