おひとりさま現役パラレルワーカーフクコろぐ

これからの会社員は、複数の収入源をもとう! 会社に翻弄されずアナタらしく仕事ができる。 そんなパラレルワーカーを広めるフクコのブログです。

【文系プログラミング初心者deE資格】ゼロつくディープラーニング #33

f:id:fukuko-parallel-work:20211202204536j:plain

こんにちは!

現役パラレルワーカー フクコです。

f:id:fukuko-parallel-work:20210212204833p:plain



前回の記事↓に続き

www.fukuko-parallel-work.com





来年の2月の試験に向けてE資格試験勉強中のため


E資格とは?の記事はコチラ↓

www.fukuko-parallel-work.com




ゼロつくシリーズでおなじみ

オーライリーから出版されている

ディープラーニングの本格的な入門書でよくおススメされる

「ゼロからつくる Deep Learning」本


f:id:fukuko-parallel-work:20211029220008j:plain





この本↑を毎日5ページずつコツコツこなす

約2か月間で今年中に終了するので

来年のE資格試験までにこれで基礎力をつけることにしました。(^^)


ついつい私は何もないとだらけてしまうので(笑)

毎日5ページ終わった後の記録とまとめを書いていこうと思います。


と、まとめに入る前に…

やる気を出すためのコトバをシェアします!!(主に私のやる気を出すために 笑)

善逸、極めろ。

泣いても良い。逃げても良い。ただ諦めるな!

信じるんだ。地獄のような鍛錬に耐えた日々を。

お前は必ず報われる。

極限まで叩き上げ、誰よりも強靭な刃になれ!!


by じいちゃん(桑島慈悟郎)


私の大好きな鬼滅の刃から

じいちゃんこと、桑島慈悟郎の名言です。


そう! 

別に弱音をはくのは、悪いことじゃない

イチバン肝心なのは、弱音をはいた後の行動

やらないであきらめてそのまま逃げるのか

それともあきらめず歯を食いしばってがんばるのか


そこが運命の別れ道!!なんですよね。


うう、じいちゃん、どうもありがとう! (^0^)

今日もやる気が出てきました! 

よし!! 今日も頑張るぞ~! お~!! 

というコトで、

今日も、たとえ眠くて疲れていても、あきらめず、私はノルマをこなしますよ! 笑


ではでは、いい加減まとめに入ります。笑




その前に本の目次の紹介です。

ゼロつくディープラーニングは、下記↓の合計8章で構成されています。

本の目次

  • 5章 誤差伝播法
  • 6章 学習に関するテクニック



ちなみに…

ゼロつくディープラーニング第1章はPython入門のセクション(20ページ分)なので、

とりあえず今回私は飛ばし、第2章からまとめています。

現在は、第6章からで~す。



第6章 学習に関するテクニックつづき


ニューラルネットワークの学習において

キーとなる重要なアイディアを説明する。

ニューラルネットワークの学習を効率的に進め、認識精度を高める手法を紹介。

6.5 ハイパーパラメータの検証


ニューラルネットワークでは、

ハイパーパラメータ(ヒトが設定する)が多く登場する。


そのため、

ハイパーパラメータは、

適切な設定にしなければ、性能の悪いモデルになってしまう。

では、

できるだけ効率的にハイパーパラメータを探索する方法はないのか

6.5.1 検証データ


ハイパーパラメータを調整するには、

ハイパーパラメータ専用の検証データが必要になる。


ーポイント!ー


  • 訓練データは、パラメータ(重みやバイアス)の学習に利用
  • 検証データは、ハイパーパラメータの性能評価
  • テストデータの汎化性能を評価するために利用

6.5.2 ハイパーパラメータの最適化


ハイパーパラメータの最適化を行う上で重要なポイント

ハイパーパラメータの「いい値」が存在する範囲を徐々に絞りこむ

というコト。


それを複数回繰り返して行い

認識精度の結果を観察

その結果からハイパーパラメータの「いい値」の範囲を狭めていく


ハイパーパラメータの範囲

「ざっくりと」、0.001(10^-3)~1000(10^3)ぐらいの「10のべき乗」のスケール範囲で指定


ーハイパーパラメータの最適化ー

0.ハイパーパラメータの範囲を設定
「ざっくりと」、0.001(10^-3)~1000(10^3)ぐらいの「10のべき乗」のスケール範囲

1.設定されたハイパーパラメータの範囲から、ランダムにサンプリングする

2.ステップ1でサンプリングされたハイパーパラメータの値を使用して学習を行い、検証データで認識精度を評価する

3.ステップ1とステップ2をある回数繰り返し、それらの認識精度の結果からハイパーパラメータの範囲を狭めていく


↑の方法は実践的なもの

より洗練された手法として、ベイズ最適化」(Bayesian Optimization)がある。

6.5.2 ハイパーパラメータ最適化の実装


MNISTデータを使用して

ハイパーパラメータの最適化をしてみる。


ハイパーパラメータの検証は、

0.001(10^-3)~1000(10^3)ぐらいの「10のべき乗」のスケール範囲


Pythonでの実装は↓のとおり。

# 6.5.2 ハイパーパラメータ最適化の実装
# coding: utf-8
import sys, os
sys.path.append(os.pardir)  # 親ディレクトリのファイルをインポートするための設定
import numpy as np
import matplotlib.pyplot as plt
from dataset.mnist import load_mnist
from common.multi_layer_net import MultiLayerNet
from common.util import shuffle_dataset
from common.trainer import Trainer

(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True)

# 高速化のため訓練データの削減
x_train = x_train[:500]
t_train = t_train[:500]

# 検証データの分離
validation_rate = 0.20
validation_num = int(x_train.shape[0] * validation_rate)
x_train, t_train = shuffle_dataset(x_train, t_train)
x_val = x_train[:validation_num]
t_val = t_train[:validation_num]
x_train = x_train[validation_num:]
t_train = t_train[validation_num:]


def __train(lr, weight_decay, epocs=50):
    network = MultiLayerNet(input_size=784, hidden_size_list=[100, 100, 100, 100, 100, 100],
                            output_size=10, weight_decay_lambda=weight_decay)
    trainer = Trainer(network, x_train, t_train, x_val, t_val,
                      epochs=epocs, mini_batch_size=100,
                      optimizer='sgd', optimizer_param={'lr': lr}, verbose=False)
    trainer.train()

    return trainer.test_acc_list, trainer.train_acc_list


# ハイパーパラメータのランダム探索======================================
optimization_trial = 100
results_val = {}
results_train = {}
for _ in range(optimization_trial):
    # 探索したハイパーパラメータの範囲を指定===============
    weight_decay = 10 ** np.random.uniform(-8, -4)
    lr = 10 ** np.random.uniform(-6, -2)
    # ================================================

    val_acc_list, train_acc_list = __train(lr, weight_decay)
    print("val acc:" + str(val_acc_list[-1]) + " | lr:" + str(lr) + ", weight decay:" + str(weight_decay))
    key = "lr:" + str(lr) + ", weight decay:" + str(weight_decay)
    results_val[key] = val_acc_list
    results_train[key] = train_acc_list

# グラフの描画========================================================
print("=========== Hyper-Parameter Optimization Result ===========")
graph_draw_num = 20
col_num = 5
row_num = int(np.ceil(graph_draw_num / col_num))
i = 0

for key, val_acc_list in sorted(results_val.items(), key=lambda x:x[1][-1], reverse=True):
    print("Best-" + str(i+1) + "(val acc:" + str(val_acc_list[-1]) + ") | " + key)

    plt.subplot(row_num, col_num, i+1)
    plt.title("Best-" + str(i+1))
    plt.ylim(0.0, 1.0)
    if i % 5: plt.yticks([])
    plt.xticks([])
    x = np.arange(len(val_acc_list))
    plt.plot(x, val_acc_list)
    plt.plot(x, results_train[key], "--")
    i += 1

    if i >= graph_draw_num:
        break

plt.show()


↑を実装した↓の結果を比べてみよう。

↓の結果を見る


f:id:fukuko-parallel-work:20211202215817j:plain


f:id:fukuko-parallel-work:20211202215837j:plain


うまく学習が進んでいるのは、

学習係数

0.001から0.01

Weighted Decay数が

 10^-8 から 10^-6

というコトがわかる。


6.6 第6章 学習に関するテクニック まとめ


第6章では、

ニューラルネットワークの学習を行ううえでの重要なテクニックを紹介した


ー第6章 学習に関するテクニック まとめー


  • パラメータの更新方法には、SGDのほかにMomentum, AdaGrad, Adamなどの手法がある。
  • 重みの初期値の与え方は、正しい学習を行う上で非常に大切
  • 重みの初期値として、「Xavierの初期値」(Sigmoid, tanh)「Heの初期値」(ReLU)などが有効。
  • Batch Normalizationを用いることで、学習を早く進めることができ、また初期値にたいしてロバスト(頑強)になる
  • 過学習を抑制するための正則化の技術として、Weighted DecayDropoutがある。
  • ハイパーパラメータの探索は、いい値が存在する範囲を徐々に絞りながら進めるのが最も効率いい方法


今日のまとめ


ハイ、今日はここまで!!

第6章の学習に関するテクニックがようやく終了!!(^^)ふう。

明日から第7章に入ります。あともう2章分!

引き続き頑張りまっす。


最後まで読んでくださり、ありがとうございます!

フクコ


ディープラーニング入門書おススメ本


E資格とは?

www.fukuko-parallel-work.com