CCS機械学習講座 Part1
目次
- この講座について
- 機械学習とは
- 機械学習の種類
- これから話す事の概略
- 単純パーセプトロン
- 多層パーセプトロン
- 教師ベクトルと誤差関数
- 最急降下法
- 誤差逆伝播法
この講座について
機械学習(というよりはほぼニューラルネットワーク、DeepLearning関係)に興味がある人向けの講座になります。
最近DeepLearningが流行ってる(?)おかげでライブラリの類が充実してて、比較的簡単に試せたりします。
数式に関してはベクトルや行列、偏微分あたりを用います。
プログラムに関してはPythonと機械学習関係のライブラリを用います。
いずれもそこまで細かい話はしないと思います。
必要なら講座中に補足はします、もしくは質問を投げて下さい。(答えられるとは言ってない)
機械学習とは
機械学習とは、雑に説明(?)するなら「データからルールを自動で見つけさせる」技術です。
なぜこのような事をするのかと言うと、手動でルールを決めるのが難しい場合があるからです。
例えば、数字が1つ書かれた画像に対して、0から9のどれが書かれているかを判別するプログラムを作るとします。
この時、判別のルールをどうやって決めるかという問題が発生します。
私たちは画像を見れば(読めないものを除き)何の数字か一瞬で分かりますが、プログラムがそれを行うのは難しいです。
なぜなら、どういう条件を満たす時に「これは1です」や「これは2です」と言えるのかがよく分からないからです。
(if文で分けるとすると、条件式が書けない…)
一応抜け道として、全ての画素値の組み合わせに対して1や2を割り当て、入力画像の画素値に対応する数字を返す関数を作るという方法があります。
しかし、この関数を作るのはとてつもなく面倒です。画像のサイズが10*10で画素値が0,1(白黒)の場合でも、2の100乗=1.267...*10^30のパターンがあります。
これだけのパターンに対して割り当てを行うのは非現実的です。(しかも実際は画像サイズはもっと大きく、画素値も0から255です)
この例のように、手動でルールを決めるのが困難な場合、別の方法を考える必要があります。
その方法として挙げられるのが機械学習と呼ばれる技術です。
この例の場合では、数字の書かれた画像とそれが何の数字であるかのデータをたくさん与える事で、判別のルールをプログラムに自動で決定させます。
この「自動で決定させる」部分の事を学習と言います。また、与えたデータの事を学習データや訓練データと言います。
応用例は多く、画像や音声、文章などを対象に様々な事ができると考えられています。
アニメオタクとかその辺(雑)がテンション上がりそうな話題としてはキャラクターの識別、キャラクターの顔画像の生成、ラフ画から線画の生成、線画の自動着色といったものが挙げられます。
調べてみると面白いと思います。また、講座の後半ではDeepLearningを利用した画風(スタイル)変換などで遊んでみようかなと考えています。
機械学習の種類
機械学習と一口に言っても様々な種類があります。
教師あり学習
プログラムに学習させるために「入力データ」と「正解ラベル」のセットを訓練データとして与えます。
先ほどの例だと数字の書かれた画像が入力データ、それが何の数字であるかが「正解ラベル」に対応します。
(正解ラベルは教師ベクトルと言ったりします)
最終的には訓練データ以外の未知のデータに対して正しく答えるのが目標になります。
未知のデータに対して正しく答える能力の事を汎化性能と言ったりします。
逆に、訓練データには上手く答えられるけど未知のデータには上手く答えられないような状態の事を過学習と言います。
教師あり学習では過学習を避け汎化性能を高める事が目標になります。
教師あり学習では主に「回帰」と「分類」を行います。
- 回帰:入力から出力を直接予測する (例)今日の気温から明日の気温を予測
- 分類:入力がどのグループ(クラス)に属するか判定する (例)受け取ったメールが迷惑メールかどうか
回帰も分類も、与えられたデータから条件を満たす関数を見つける、近似するというのがやる事になります。
回帰の場合はデータの点を通る関数を、分類の場合は各クラスに属する点の境界面になる関数を見つけます。
教師なし学習
教師なし学習では「入力データ」のみが与えられます。(正解ラベルがない)
入力データに対し何かしらの構造や規則を見出す分析を行うのが教師なし学習の目的になります。
「教師あり学習」は未知データを正しく分けるのが目標なのに対し、「教師なし学習」は与えらえれたデータを対象に分析を行います。
教師なし学習では主に「クラスタリング」と「次元削減」を行います。
- クラスタリング:入力データをいくつかのグループ(クラスタ)に分ける (例)顧客の情報から似た傾向の顧客をまとめる
- 次元削減:高次元な入力データを低次元に変換する(少ない情報で表現する)
教師あり学習の「分類」と教師なし学習の「クラスタリング」はグループ分けという意味では似ていますが、異なるものです。
「分類」におけるグループである「クラス」は人間が事前に決めておくもので、最初から意味付けされています。(数字など)
一方、「クラスタリング」におけるグループである「クラスタ」は似たデータを集めた結果できるもので、最初から意味付けされている訳ではありません。
(できたクラスタに対して解釈が必要)
次元削減は単純にデータの圧縮の他、機械学習において扱いにくい高次元データを低次元に変換し扱いやすくするというような目的で行われます。
他にも「半教師あり学習」や「強化学習」といった種類のものもあります。
この講座では教師あり学習を中心に扱うつもりです。
また、学習にはいろいろな手法があるのですが、ここではDeepLearning関係のものについて扱います。
これから話す事の概略
学習する時
- 訓練データ(入力データと対応する教師ベクトル)を用意
- 入力データに計算処理を行う
- 得られた出力と教師ベクトルを比較
- 比較して得られた誤差から重みを更新
- 上記の処理を繰り返し、重みの更新が十分進んだら学習を終了
実際に使う時
- 入力データに計算処理を行う
- 回帰なら得られた結果を出力、分類ならどのクラスに属するか判定
これからDeepLearning関系の話をする事になりますが、中身の細かい部分は変われど基本的には上記の流れで処理が行われます。
(長々と話す事になると思います、分かりにくかったらすいません…)
単純パーセプトロン
入力の各要素に対し重みをかけてそれらを足した結果が閾値以上なら1、そうでないなら0を出力するものを単純パーセプトロンと言います。
閾値
入力が2次元(バイアス項を加えると3次元)の場合を考えると、出力
となります。
入力と重みの積と和の部分は
(何次元でもこの書き方でいける)
2次元の入力の場合、平面上の点を直線の上下で分ける事になります。
入力が3次元の場合、ある平面の上下で分けることになります。入力が
(超平面は直線や平面を一般化したもので、1次元超平面は直線、2次元超平面は平面です)
例えば2次元の入力(ここでは各要素は0か1のみとします)に対し、重みとバイアスを以下のように設定します。
すると、入力と出力は次のような関係になります。
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
論理回路をやった事がある人ならわかるかもしれませんが、AND回路に相当します。
重みやバイアスを変えるとOR回路なども表現できたりします。
しかし、XOR回路と呼ばれるものは表現できません。なぜかと言うと、XORは直線1本で分離できないからです。
AND,OR,XORをそれぞれ図示すると以下のようになります。どう頑張ってもXORの直線は引けないと思います。
出典:http://tawara.hatenablog.com/entry/2016/10/22/DeepLearningFromZero-01
単純パーセプトロンでは直線などの超平面で分離できるデータ(線形分離可能なデータ)しか正確に分類する事ができません。
多少のミスを許容するなら別ですが、このように単純パーセプトロンには限界があります。
単純パーセプトロンの学習についても触れたかったんですが、資料作成の時間が足りないので省きます。すいません。
パーセプトロンの学習には誤識別の時のみ重みを更新する誤り訂正法(パーセプトロンの学習規則)と呼ばれるものや、誤差関数を設定し最小化するデルタルール(Widrow-Hoffの学習規則)と呼ばれるものが存在します。
多層パーセプトロン
先ほど述べたように単純パーセプトロンで表現できるものには限界があります。
そこで、複数の単純パーセプトロンを組み合わせる事を考えます。例えば次の図のように組み合わせ、重みを設定します。
すると、2次元の入力(ここでは各要素は0か1のみとします)に対し、以下の出力が得られます。
0 | 0 | 0 | 1 | 0 |
0 | 1 | 1 | 1 | 1 |
1 | 0 | 1 | 1 | 1 |
1 | 1 | 1 | 0 | 0 |
単純パーセプトロンでは表せなかったXOR回路を表現する事ができました。
このように、複数の単純パーセプトロンを層状に組み合わせたものを多層パーセプトロンと言います。
入力部分を入力層、出力部分を出力層、それ以外の中間部分を中間層や隠れ層と言います。
また、各単純パーセプトロンをユニットと言います。(ニューロンとかノードとか、言い方はいろいろある気がする)
例えば以下の図のような多層パーセプトロンを考えると、入力
この辺から数式にした時の地獄感が増していくので注意してください。
(もっといい書き方あったら教えてください…)
-
シグモイド関数:
$sigmoid(x) = \cfrac{1}{1+e^{-x}}$ -
Hyperbolic Tangent:
$tanh(x) = \cfrac{1 - e^{-2x}}{1 + e^{-2x}}$ -
ReLU:
$ReLU(x) = \max(0, x)$ -
ステップ関数:
$H(x) = \begin{cases} 1 & (x \geq 0) \\ 0 & (x < 0) \end{cases}$
単純パーセプトロンは活性化関数にステップ関数を選んだものとみなす事ができます。
活性化関数として非線形関数を利用するというのが重要で、これが無いと多層にする意味がなくなってしまいます。
なぜかというと、簡単のため次のような多層パーセプトロンを考えます。(各層ユニットが1つ)
中間層で用いる活性化関数に線形関数
これは重みを
このような理由から、多層パーセプトロンでは入力と重みの積和に対し非線形な関数を通す必要があります。
また、多層パーセプトロンでは後述する重みの更新(学習)の計算に微分値を用いるので、微分可能な非線形関数が好まれます。
昔はシグモイド関数がよく用いられ、最近はReLUがよく用いられるらしいです。
ReLUは
$x=0$ で微分不可ですが、劣微分という考え方を用いる事で微分可能なものとして扱うらしいです。
後述する誤差関数も合わせて、解きたい問題に適切なものを選ぶ必要があります。
-
恒等関数:
$identity(x) = x$ -
ソフトマックス関数:
$softmax(\boldsymbol{x}) = \cfrac{1}{\displaystyle\sum^k_{i=1} e^{x_i}} (e^{x_1}, ... , e^{x_k})^\top$ ($k$ はベクトルの次元、$x_i$ はベクトルの各要素)
恒等関数は回帰でよく用いられるもので、何もしない関数です。(実装とかする時は省かれると思います)
分類では2クラス分類の場合シグモイド関数(これは中間層でも用いられる)、多クラス分類の場合ソフトマックス関数と呼ばれるものがよく用いられます。
多クラス分類は数字の識別(0から9の10種類なので10クラス分類)などが例として挙げられます。
2クラス分類の場合は出力は1次元で、シグモイド関数を通す事で[0,1]になります。
これは確率として解釈ができ、0.5より小さいならクラス1、そうでないならクラス2に属するとみなせます。
多クラス分類の場合は、分類したいクラスの数だけ出力を用意します。例えば数字の識別の場合は10次元のベクトルを出力するようにします。
ソフトマックス関数ではベクトルを入力しベクトルを出力することになります。
ソフトマックス関数を通すと、ベクトルの要素の和が1になります。このような性質から、出力の
例えば出力ベクトルが(0.01, 0.04, 0.95)となっていたら、入力データは3つ目のクラスに95%の確率で属すると解釈します。
教師ベクトルと誤差関数
ここまで、重みの値はあらかじめ適切なものを設定していました。(AND回路やXOR回路に相当するもの)
ここからは学習によって適切な重みを自動で得る事を考えます。
教師あり学習では入力に対する出力値と教師データの誤差をとり、その誤差を小さくするように重みを更新する事で適切な重みを得るという手続きをとります。
(誤差が小さい方が入力に対する出力値と教師データの値が近く、訓練データを正しく表現できている)
実際は訓練データ以外に対しても正しい出力値を得る事ができているか(汎化性能)にも注意する必要があります。
教師あり学習の学習を考えるため、まず教師データについて扱います。教師データ(1次元の場合や多次元の場合がある)とは各入力に対する望ましい出力の事です。
回帰の場合は入力データに対応するデータの値をそのまま教師データとして利用します。
例えば
2クラス分類の場合、教師データは入力データがどちらのクラスに属するかで1か0を設定します。
先ほど2クラス分類ではシグモイド関数を通した値(0から1)を出力するので確率とみなせると言いましたが、1か0の出力は理想的な出力(100%どちらかのクラスである)とみなせるためです。
多クラス分類の場合はクラス
例えば、10クラス分類の場合、クラス3に属する入力データに対する教師データは以下のようになります。
これは2クラス分類の時と同様に、特定のクラスに100%属しているとみなせます。(one hot表現と言います)
多層パーセプトロンや今後扱う予定の畳み込みニューラルネットワークなどでは学習(適切な出力を得るための重みの調節)をするために誤差関数と呼ばれるものを考えます。
誤差関数は出力がどれだけ正解ラベル(教師データ、教師ベクトル)に近いかを測るためのもので、小さいほど教師データに近い値が出力されている事になります。
誤差関数はいろいろなものを考える事ができますが、基本的に常に正の値を取り、出力が教師データに近いほど値が小さくなる(理想は0)ような関数が用いられます。
活性化関数のように誤差関数にもよく用いられるものにいくつか種類があるので、紹介します。
以下、
(交差エントロピー誤差のみベクトルではなく1次元の値
-
二乗誤差:
$\displaystyle\cfrac{1}{2} \sum_{i=1}^n ||\boldsymbol{y}_i - \boldsymbol{t}_i||^2 = \displaystyle\cfrac{1}{2} \sum_{i=1}^n \sum_{j=1}^k(y_{ij} - t_{ij})^2$ -
交差エントロピー誤差:
$-\displaystyle\sum_{i=1}^n (t_i \log y_i + (1 - t_i) \log (1 - y_i))$ -
多クラス交差エントロピー誤差:
$-\displaystyle\sum_{i=1}^n \sum_{j=1}^k t_{ij} \log y_{ij}$
これらの誤差は出力層の活性化関数
回帰
- 出力値:恒等関数(活性化関数なし)を通したもの(次元はデータによる)
- 教師データ:入力に対応するデータをそのまま
- 誤差:二乗誤差
2クラス分類
- 出力値:シグモイド関数を通した1次元の値
- 教師データ:入力データの属するクラスによって0か1
- 誤差:交差エントロピー誤差
多クラス分類
- 出力値:ソフトマックス関数を通した
$k$ 次元(クラス数)のベクトル - 教師データ:クラス
$i$ のデータに対し、$i$ 番目の値のみ1、それ以外が0のベクトル - 誤差:多クラス交差エントロピー誤差
交差エントロピー誤差は見慣れないと思いますが、シグモイド関数あるいはソフトマックス関数を通した後に利用するので、
それにマイナスが付いているので、交差エントロピーは常に正の値になります。(
また、
以上のような性質から、(多クラス)交差エントロピーは誤差関数として用いられます。
これらの活性化関数と誤差関数の組を用いた場合、後述する誤差逆伝播法の計算時に、出力部分の重みの更新式がいずれも出力と教師の差を取る形に帰着するようです。
(これに関係する概念として正準連結関数というものがあるそうな…?)
最急降下法
教師ベクトルと誤差関数を定義したので、これで現在の重みが良いかどうかが分かるようになりました。(誤差が小さい方が良い)
後は誤差関数が最小になるような重みを計算します。
基本的には最急降下法(勾配降下法)と呼ばれる方法(もしくはその改良版)で重みを少しずつ更新し誤差関数を小さくしていきます。
多層パーセプトロンなどで扱う誤差関数はたくさんの重みからなる関数であり、非常に複雑な形をしていると考えられます。
そのため、ちょっと式変形をして一発で解を見つけるという事はできません。
(シンプルなものだとできて、例えば線形回帰の解は$\boldsymbol{w} = (X^\top X)^{-1} X^\top \boldsymbol{t}$ と書けます)
なので、反復法と呼ばれる繰り返し計算を行う手法で解を見つけます。
一般に、最急降下法は最小化したい関数
- 適当に初期値
$\boldsymbol{w}$ を決める -
現在のパラメータ
$\boldsymbol{w}$ に対する勾配$\nabla E(\boldsymbol{w})$ を求める$$ \nabla E(\boldsymbol{w}) = \left(\cfrac{\partial E(\boldsymbol{w})}{\partial w_0}, ... , \cfrac{\partial E(\boldsymbol{w})}{\partial w_k} \right)^\top $$ -
$\boldsymbol{w} \leftarrow \boldsymbol{w} - \varepsilon \nabla E(\boldsymbol{w}^{(i)})$ によりパラメータを更新($\varepsilon$ は正の定数) - パラメータの更新を一定回数繰り返すか、更新する量が小さくなったら終了
それぞれのパラメータについて、偏微分して得られる方向とは逆方向に値を変化させると関数
なので、それを繰り返す事で目的の関数
出典:http://www.gifu-nct.ac.jp/elec/deguchi/sotsuron/oguri/node15.html
シンプルで分かりやすいですが、もし関数
この値は自分で決める必要があります。
ただし、大きすぎると解の近くで振動してしまい、小さすぎると解へ辿り着くのに時間がかかるので注意が必要です。
最急降下法にはいろいろ問題がありますが、その辺はしょうがないという事で割り切って使っていきます。
多層パーセプトロンの場合は、誤差関数
(
先ほど説明した二乗誤差などは全ての入力に対する誤差を足したもので、これを最急降下法で最小化する場合、毎回全ての入力から出力を計算し、その後重みを更新する事になります。
機械学習ではデータ数
そこで、全ての入力に対する誤差を小さくするのではなく、ランダムに1つデータを選び、その誤差を小さくする事を考えます。
二乗誤差を例に取ると、
このように、ランダムにデータを1つ選び、その誤差を小さくしていくという処理を繰り返す事を確率的勾配降下法(SGD)といいます。
また、1つではなく8つを選ぶなど、少量のデータに対してこの処理を行うものもあります。(この時の少量のデータをミニバッチといいます)
誤差逆伝播法
誤差関数を小さくする(学習する)手法として、最急降下法(確率的勾配降下法)を紹介しました。
これにより各重みに対する偏微分を計算すれば学習を進める事ができる事がわかりました。
しかし、各重みに対して次のような数値微分(プログラム上での微分の計算)を行うと、同じ入力に対して何度も出力値を求める必要があります。
(
重みの数が増えるとこの部分の処理に時間がかかってしまい、結局学習を進める事ができません。
そこで、微分の連鎖律を利用する事で効率良く学習を進める誤差逆伝播法について触れます。
ここから先はこの資料の中では恐らく最も複雑で、頭が痛くなるくらい大量の数式が出てくると思います。
後で用いるライブラリではこの辺の処理は自動でやってくれるので、興味のない人は飛ばしても構いません。
講座でこの話をするかどうかは時間と参加者の気分で決めようかな…
(正直この辺の話は少し怪しい…)
まず、連鎖律の確認をします。
例えば2変数関数
例えば、
となります。
となり、一致します。
ここから
(ある層のユニットはその前の層のすべてのユニットと繋がっているとします)
まず、計算のために多層パーセプトロンの計算を以下のような式で表記します。
(ここでは全体の二乗誤差
また、
先ほど述べたように、最急降下法(確率的勾配降下法)では各重み
(重みは
まず、
(連鎖律の例で
右辺の後半について、以下の式が成り立ちます。
右辺の前半ですが、
右辺の後半について、以下の式が成り立ちます。
右辺の前半についてですが、
右辺の後半について、以下の式が成り立ちます。
これまでの結果を
この式から、後ろの層の計算結果を利用してその1つ前の層の値が求められる事が分かります。
この式を利用する事で各重みについて出力を毎回計算するのではなく、一度出力を計算するだけで後ろの層から各重みに対する微分値を求め、重みを更新する事ができます。
一番後ろでは出力と教師の誤差を計算していて、これが前の方に伝わっていく様子から誤差逆伝播法という名前がついています。(と思われます)
また、用いる活性化関数によって
-
シグモイド関数:
$\cfrac{\partial f(x)}{\partial x} = f(x)(1 - f(x))$ -
Hyperbolic Tangent:
$\cfrac{\partial f(x)}{\partial x} = 1 - f(x)^2$ -
ReLU:
$\cfrac{\partial f(x)}{\partial x} = \begin{cases} 1 & (x \geq 0) \\ 0 & (x < 0) \end{cases}$