はじめに
ChatGPTやDeepLなどディープラーニングを用いた製品やサービスはたくさんありますが、その仕組みを全く知りませんでした。
「その仕組みを知りたい!」という気持ちからディープラーニングについて学習し始めたので、アウトプットも兼ねて今回、誤差逆伝播法の勾配を計算する部分について紹介したいと思います。ディープラーニングを勉強すると最初に躓く部分だと思うので、丁寧に説明できればと思います。
ディープランニング概要
ディープラーニングのモデルの学習の流れは以下の1~5のサイクルになっています。これらを繰り返すことで、より精度の高い出力ができるパラメータに更新し、精度の高いモデルを生成していきます。
- データを入力
- データを出力
- 損失を計算
- 勾配を計算
- パラメータを更新
今回は上記4番の「計算した損失から勾配を計算する仕組み」を紹介します。
誤差逆伝播法
これから紹介するMNIST画像の分類問題を行う中間層が2層のモデル(入力 → 中間層1 → 中間層2 → 出力 → 損失)を題材にします。
MNISTは手書き数字(0から9までの整数 = 10種類)の画像のデータセットです。
また、MNIST画像は のグレー画像で、各ピクセルは0から255までの値をとります。
1画像につき784ピクセルのデータがあるので、入力データは ベクトルになります( Nはバッチ数です )。
入力 から1つ目の中間層 への重み ( ) の次元は 、バイアス ( ) の次元は 、活性化関数は ReLU関数 としました。
ですので、中間層1の次元は になります。
1つ目の中間層から2つ目の中間層( layer2 )への重み ( ) の次元は 、バイアス ( ) の次元は 、活性化関数は ReLU関数 としました。
ですので、中間層2の次元は になります。
本モデルは10種類の分類問題なので、出力 ( output ) の次元を にする必要があります。
なので、2つ目の中間層から出力への重み ( ) の次元は 、バイアス ( ) の次元は 、活性化関数は softmax関数 としました。
また、損失関数には多値分類タスクによく使われるクロスエントロピー誤差を用います。 は正解データを表しています。
パラメータの更新のための勾配計算
まず、計算された損失 を受けて、パラメータ をどのように更新するか、つまり を求めていきます。
を求める流れは以下のようになっています。
- を求める。
- を求める。
- を求める。
では、最初に を求めます。損失は以下のような式で導出されます。
ただし、 はクロスエントロピー誤差を表しています。クロスエントロピーにより ベクトルを ベクトルの損失に変換しています。
クロスエントロピーの定義
ただし、 はモデルの出力値、 はそれに対応する正解値。
自然対数の微分()より、損失に対する の微分は以下のようにかけます。
次に、 を求めます。 は以下のような式で導出されます。
ただし、 はソフトマックス関数を表しています。ソフトマックス関数により ベクトルの を10種類の数字の確率を表す ベクトルに変換しています。
より、 は先ほど求めたので、ソフトマックス関数の微分 を求めれば、 が求まります。
ソフトマックス関数の微分
ソフトマックス関数の定義より、 ベクトルの出力 のある要素 からそれに対応する確率を導出する式は以下になっています。
ここで とおくと、 とできます。
のとき
分数関数の微分公式 ( ) を用いることで、以下のように書けます。
のとき
これらより、ソフトマックス関数の微分は以下のようになります。
前述した式
は連鎖律より以下のようにかけます。
より、これまでの計算結果とソフトマックス関数の微分の場合分けを考慮すると以下のように書けます。
これにより、損失 に対する、の微分を求めることができました。
これまでの計算結果より、遂に を求めることができます。
は以下の式で表されます。
まず、 は以下のように導出できます(右上に添えてある ( T ) は転置を表しています)。
上式は のように内積の順番と次元の整合性が取れていることがわかります。
次に、 は以下のように導出できます。
上式は のように内積の順番と次元の整合性が取れていることがわかります。
また、以降の計算のために も求めます。
上式は のように内積の順番と次元の整合性が取れていることがわかります。
パラメータの更新のための勾配計算
を求めます。
先ほどと違うのは、クロスエントロピー誤差を考慮しなくて良いこと。また、活性化関数がソフトマックス関数ではなくReLU関数であることです。
ただし、 はReLU関数を表しています。
まず、 を求めます。
については前節で既に求めているので、 を求めます。
ReLU関数の微分
について、微分 を求めることを考える。
ReLU関数の定義より は上記のように表すことができる。
より、 は以下のようになる。
ReLU関数の微分より、 は の要素が0より大きい時に1、小さい時に0をとる ベクトル( と同じ形)であることがわかりました。
これを とおくと、 は以下のように書けます( )。
それでは を求めます。
は先ほど求めたので、 より、以下のように求まります。
上式は のように内積の順番と次元の整合性が取れていることがわかります。
次に を求めます。
上式は のように内積の順番と次元の整合性が取れていることがわかります。
パラメータの更新のための勾配計算
の計算は の導出と同じ方法で求めることができます。
計算過程については省略します。
パラメータの更新のための計算まとめ
これまでの を で以下のように表すことができます。
ただし、 は を表しています。
活性化関数の種類により、 を計算する必要はありますが、基本的に のようなニューラルネットワークでは、 を上記のように計算できることがわかりました。
まとめ
今回はMNISTの分類問題のモデルという具体例を用いて、モデルの中でどのように勾配が計算されているのかを見ていきました。便利なライブラリを用いれば、このような仕組みを意識しなくても実装できると思いますが、理論の部分を理解するのも重要だと思っています。また、今回のタスクは分類タスクでしたが、回帰タスクでも損失関数から逆伝播させるのは出力データ と正解データ の差であることは変わらないようです。本記事では触れられませんでしたが、勾配を計算した後は、最適化によりパラメータを更新していきます。その最適化手法にも種類が様々あるようで、そちらの学習も今後進められればと思っています。