#80 モデルのコンパイル、トレーニング、評価
今回は、『#78 レイヤーの設定』で作成したモデルに対して、コンパイル、トレーニングを行い、さらにトレーニング済みのモデルを評価することを体験します。
コンパイルとは、後述しますが、トレーニングを進める方法や評価基準をどうするかというルールを設定して、モデルのトレーニングの準備することです。
その前に、ディープラーニングのしくみについて、簡単に説明しておきます。
1.ディープラーニングのしくみ
複数の隠れ層(中間層)を持つニューラルネットワーク、すなわちディープラーニングは、神経細胞をモデルにシステム上で動くように設計されたものです。神経細胞のニューロンに対応した人工ニューロンをノードと呼びます。下記のスライド図1では、〇で表されているところです。
このノードを拡大すると、図2のようになります。入力、入力の数、重み、バイアス、活性化関数、出力によって表されます。
ノードの構成する要素を簡単に説明すると下記のようになります。
重み
→入力情報の重要度を決定する倍率(係数)です。
→トレーニング前はランダムな初期値ですが、model.fit() によって最適な値に書き換えられていきます。
バイアス
→ノードの感度・発火のしやすさを調整する閾値(定数)です。
→重みと入力の積の総和に対して、ノード1個に対して1個の定数値として足し算されます。重みと同様にトレーニングによって自動更新されます。
活性化関数
→生物学的なニューロンにおける「一定以上の刺激を受けると発火する」動作を再現するスイッチの役割を担っています。
→この関数を用いて出力を算出するのですが、ニューラルネットワークやディープラーニングでは、この関数を用いることにより単なる一次関数ではなく、複雑な曲線や境界線(非線形なパターン)を学習する表現力を獲得することになります。
出力
→ノードの最終計算結果、すなわち次の層への入力値となります。
*************
ノードを構成している入力、入力の数、重み、バイアス、活性化関数を用いると出力は一つの数式で表すことができます。
すなわち、計算可能になります。
では、出力を求める計算式を考えてみましょう。ちゃんと計算できるかどうかを確かめるためですから、下図はざっくりと理解できれば大丈夫です。
ニューラルネットワークやディープラーニングでは、上記の式によって各ノードの出力を行いますが、結果に対して、重み付けやバイアスをチューニングして性能を向上させていくのが、バックプロパゲーション(Backpropagation/誤差逆伝播法)です。予測の誤差を、出力側から入力側へと「逆方向」に伝えていき、各層のパラメーター(重み、バイアス)をどれくらい修正すべきかを計算する機能ということができます。
ニューラルネットワークやディープラーニングのトレーニングでは、このバックプロパゲーションを使います。

2.コンパイル
モデルのトレーニングを行う前に、モデルのコンパイルを行います。
これは、作成したモデルに、トレーニングを進める方法や評価基準をどうするかというルールを設定して、モデルのトレーニングの準備することを意味します。
具体的には、model.compile()関数に次の3つの引数を指定します。
●オプティマイザ optimizer
●損失関数 loss
●評価指標 metrics
公式チュートリアルでは、下記のように引数を指定しています。
model.compile(optimizer='adam',
loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
コンパイルを行わずに model.fit() を呼び出すと、「どうやって採点すればいいの?どうやって重みを直せばいいの?」とAIがパニックを起こしてエラーになってしまいます。
さて、3つの引数は、何を指定しているのかを説明します。
オプティマイザ
予測を外したときに、『重み』や『バイアス』をどのように調整・更新するかという計算アルゴリズムを指定します。
→ adam(Adaptive Moment Estimation)というアルゴリズムが指定されていますが、AI開発において、現在、ほとんどの場面で optimizer=‘adam’ が標準となっています。他のアルゴリズムに関しては、下記を参照してください。
【参照】 機械学習のAdamやRMSPropなどの最適化手法まとめ:効率的なモデル構築の秘訣
損失関数
これは、AIが出した予測と実際の正解を比べて、どれくらい間違えているか(誤差)を計算するルールを設定しています。
→ 『keras.losses.』の部分はKerasが提供する損失関数のモジュールから呼び出す指示を表し、『SparseCategoricalCrossentropy( ) 』の部分は、使用する具体的な損失関数の名前と詳細設定を指示しています。SparseCategoricalCrossentropyとは、多クラス分類問題を解決するために一般的に使われる損失関数で、(from_logits=True)はモデルの出力はロジット(生データ)であることを指定しています。
評価指標
トレーニングの評価指標を指定しています。
→ 『=[‘accuracy’]』は、予測と、正解ラベルを全データ分比較して、正解した割合を算出して保持します。
3.モデルのトレーニング
モデルのトレーニングの準備、すなわちコンパイルを行った後に、model.fit関数を使って、モデルをトレーニングしていきます。他の機械学習と同様に、実際のデータを読み込ませて、教師あり学習を実行していきます。
model.fit関数は、モデルのコンパイルに従って、 設定した回数(引数epochs=数字)だけ、以下のループを繰り返す指示をしています。
1.予測してみる(順伝播 / Forward Pass)
→現在の重みとバイアスを使って、画像を読み込み「これはスニーカーかな?」と予測を出します。
2.採点する(損失の計算)
→ 『model.compile関数』で指定した損失関数を使って、正解ラベルとの「ズレの大きさ」を採点します。
3.間違えた原因を後ろから辿る(バックプロパゲーション)
→ 「どのノードの重みやバイアスが原因で予測を外したのか?」を、出力層から入力層に向かって逆向きに微分の計算をして突き止めます。
4.重みとバイアスを書き換える(パラメータの更新)
→『model.compile関数』で指定したオプティマイザ(adam)が、誤差が減る方向へ重みとバイアスをほんの少しだけ修正します。
model.fit関数の主な引数は下記のとおりです。
model.fit(入力データ名1,入力データの正解ラベル1, epochs=整数)
ここで、『epochs=整数』は、訓練データ全体を何回くり返して学習するかを指定するハイパーパラメータ(設定値)です。
今回は、10回に設定しました。
model.fit(train_images, train_labels, epochs=10)
実際のコードの実行結果は、下図のようになります。
『accuracy(正答率)』がトレーニングを繰り返すことによって、徐々に上昇していることがわかります。
4.【参考】 Google Colaboratoryのハードウエア アクセラレーター
モデルのトレーニングには、多くの時間がかかります。
Google Colaboratoryの設定を下記のように変更しておくことをお勧めします。
編集→ノートブックの設定→ハードウエア アクセラレーター
で、デフォルトの『CPU』を無料版でも利用可能な『T4 GPU』に変更しておきましょう。
ハードウエア アクセラレーターとは、Google Colaboratoryの頭脳である「CPU」の代わりに、特定の処理を専門的に超高速で肩代わり(加速)してくれる専用のハードウェア(チップや集積回路)のことです。
5.正解率を評価する
次に、トレーニングされたモデルが検証用のテストデータセットでどのように機能するか、正解率を評価します。
① 計算結果として『test_loss』、『test_acc』2つの数値を返す指示をしているコードです。
test_loss(損失/誤差)→正解データとモデルの予測結果のズレの大きさを示します(数値が小さいほど優秀)。
test_acc(正解率 / Accuracy)→モデルが正確に分類できた画像の割合を示します(1.0が100%)。
model.evaluate(...)→学習済みのモデルに『まだ見せていないテスト用データ』を投入し、どのくらい正確に予測できるかを計算する関数です。
test_images、test_labels→評価に使用する画像のデータセットとその正解ラベルです。
verbose=2→評価処理の実行ログ(進捗状況)をどのように表示するかを指定する引数です。『2』 は「エポックごとに1行のログを出力する」という標準的な表示モードです(0 は非表示、1 はプログレスバー表示)。
② 評価結果である正解率(test_acc)を画面に表示します。\n は改行を意味しており、ログの表示と被らないように見やすく整えています。
結果は、下記のように表示されました。
1行目
313/313→処理したバッチ(データのまとまり)の数です。このチュートリアルでは、10,000枚のテスト画像を32枚ごとのグループ(バッチ)に分けて処理します(10000/32≒313)。すべての処理が完了したことを示しています。
2s - 5ms/step→評価にかかった時間です。全体で2秒かかり、1ステップ(1バッチ)あたり約5ミリ秒で処理されました。
accuracy: 0.8800→テストデータに対する正解率(Accuracy)です。小数点表示なので、88.00% の割合で正しい画像を予測できたことを示します。
loss: 0.3475→損失値(Loss)です。モデルの予測と実際の正解との「誤差の大きさ」を表しており、数値が小さければ小さいほど優秀です。
2行目
Test accuracy→0.88 ではなく末尾に細かい数字が並んでいるのは、コンピュータ(浮動小数点数)内部の計算誤差によるもので、意味としては 約88.0%(約8,800枚を正解)と同じです。
テスト用データセットでの正解率は、トレーニング用データセットでの正解率よりも少し低くなります。(※ 正解率は、若干異なっている場合があります)
このトレーニング時の正解率とテスト時の正解率の差は、過学習の一例です。
過学習とは、新しいデータに対する機械学習モデルの性能が、トレーニング時と比較して低下する現象です。過学習モデルは、トレーニングデータセットのノイズと詳細を「記憶」するため、新しいデータでのモデルのパフォーマンスに悪影響を及ぼします。
*************
★今回、体験したコード
# モデルのコンパイル
model.compile(optimizer='adam',
loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
# モデルに投入する
model.fit(train_images, train_labels, epochs=10)
# 正解率を評価する
test_loss, test_acc = model.evaluate(test_images, test_labels, verbose=2)
print('\nTest accuracy:', test_acc)
# 正解率を評価する
test_loss, test_acc = model.evaluate(test_images, test_labels, verbose=2)
print('\nTest accuracy:', test_acc)





コメント
コメントを投稿