こんにちは!
現役パラレルワーカー フクコです。
前回の記事↓に続き
来年の2月の試験に向けてE資格試験勉強中のため
E資格とは?の記事はコチラ↓
ゼロつくシリーズでおなじみ
オーライリーから出版されている
ディープラーニングの本格的な入門書でよくおススメされる
「ゼロからつくる Deep Learning」本
この本↑を毎日5ページずつコツコツこなすと
約2か月間で今年中に終了するので
来年のE資格試験までにこれで基礎力をつけることにしました。(^^)
ついつい私は何もないとだらけてしまうので(笑)
毎日5ページ終わった後の記録とまとめを書いていこうと思います。
と、まとめに入る前に…
やる気を出すためのコトバをシェアします!!(主に私のやる気を出すために 笑)
「一番弱い人が一番可能性を持ってるんだよ」
by 炭治郎
私の大好きな「鬼滅の刃」から
炭治郎の名言です。
そう!まだよくわかっていないひよっこな弱い立場だからこそ
これから大きく伸びる可能性があるんですよね。
あ~、もうホント「鬼滅の刃」のコトバはグッときますよね。(^^)
炭治郎、どうもありがとう! (^0^)
今日もやる気が出てきました!
よし!! 今日も頑張るぞ~! お~!!
というコトで、
まだまだへっぽこなプログラミング初心者な私ですが、とにかく努力と継続あるのみ!今日もノルマをこなしますよ! 笑
ではでは、いい加減まとめに入ります。笑
その前に本の目次の紹介です。
ゼロつくディープラーニングは、下記↓の合計8章で構成されています。
本の目次
- 1章 Python入門
- 2章 パーセプトロン
- 3章 ニューラルネットワーク
- 4章 ニューラルネットワークの学習
- 5章 誤差伝播法
- 6章 学習に関するテクニック
- 7章 畳み込みニューラルネットワーク
- 8章 ディープラーニング
ちなみに…
ゼロつくディープラーニングの第1章はPython入門のセクション(20ページ分)なので、
とりあえず今回私は飛ばし、第2章からまとめています。
現在は、第6章からで~す。
第6章 学習に関するテクニックつづき
ニューラルネットワークの学習において
キーとなる重要なアイディアを説明する。
ニューラルネットワークの学習を効率的に進め、認識精度を高める手法を紹介。
RMSPropについて
(なぜか本には書いていないですが)
RMSPropについてちょっと補足:
RMSProp:AdaGradの進化系。誤差をパラメータで微分したものと再定義した学習率の積を減算。
RMSPropの更新方法の数式は以下のとおり。
← +
← -
RMSPropの実装はPythonでは以下のとおり。
# RMSProp import numpy as np class RMSProp: def __init__(self, lr = 0.01): self.lr = lr self.h = None def update(self, params, grads): if self.h is None: self.h = {} for key, val in params.items(): self.h[key] = np.zeros(val) for key in params.keys(): self.h[key] *= self.decay_rate self.h[key] += (1-self.decay_rate) * grad[key] * grad[key] params[key] -= self.learning_rate * grad[key] / (np.sqrt(self.h[key])+1e-7)
6.1.6 Adam
↑1番よく使われる!!
は、ボールがお椀を転がるように物理法則に準じる動き。
は、の進化系、適応的に更新ステップを調整する。
では、このとくっつけるとどうなるか??
それが、という手法。
は、との融合した手法。
を数式で表すと以下のとおり。
← + ( 1‐ )
← + ( 1‐ )
=
ハイパーパラメータの「バイアス補正」が行われていることもAdamの特徴。
メリット:モメンタムとRMSPropのいいとこどりを取った最適化アルゴリズム
6.1.7 どの更新手法を用いるか?
5つのパラメータ更新法を見てきた。
1. SGD
2. Momentum
3. RMSProp
4. AdaGrad
5. Adam
最近では、一番Adamが使われている。
Pythonでそれぞれを実装して比較してみると
次の結果のとおり↓。
# coding: utf-8 import sys, os sys.path.append(os.pardir) # 親ディレクトリのファイルをインポートするための設定 import numpy as np import matplotlib.pyplot as plt from collections import OrderedDict from common.optimizer import * def f(x, y): return x**2 / 20.0 + y**2 def df(x, y): return x / 10.0, 2.0*y init_pos = (-7.0, 2.0) params = {} params['x'], params['y'] = init_pos[0], init_pos[1] grads = {} grads['x'], grads['y'] = 0, 0 optimizers = OrderedDict() optimizers["SGD"] = SGD(lr=0.95) optimizers["Momentum"] = Momentum(lr=0.1) optimizers["AdaGrad"] = AdaGrad(lr=1.5) optimizers["Adam"] = Adam(lr=0.3) idx = 1 for key in optimizers: optimizer = optimizers[key] x_history = [] y_history = [] params['x'], params['y'] = init_pos[0], init_pos[1] for i in range(30): x_history.append(params['x']) y_history.append(params['y']) grads['x'], grads['y'] = df(params['x'], params['y']) optimizer.update(params, grads) x = np.arange(-10, 10, 0.01) y = np.arange(-5, 5, 0.01) X, Y = np.meshgrid(x, y) Z = f(X, Y) # for simple contour line mask = Z > 7 Z[mask] = 0 # plot plt.subplot(2, 2, idx) idx += 1 plt.plot(x_history, y_history, 'o-', color="red") plt.contour(X, Y, Z) plt.ylim(-10, 10) plt.xlim(-10, 10) plt.plot(0, 0, '+') #colorbar() #spring() plt.title(key) plt.xlabel("x") plt.ylabel("y") plt.show()
Pythonでそれぞれを実装結果と結果を図にすると↓のとおり。
黄色ハイライトにあるように、Adamの結果がイチバン最適化されている。
6.1.8 MNISTデータセットによる更新手法の比較
MNISTデータをつかって
最適化手法の比較をPythonで実装してみると↓のとおり。
# coding: utf-8 import os import sys sys.path.append(os.pardir) # 親ディレクトリのファイルをインポートするための設定 import matplotlib.pyplot as plt from dataset.mnist import load_mnist from common.util import smooth_curve from common.multi_layer_net import MultiLayerNet from common.optimizer import * # 0:MNISTデータの読み込み========== (x_train, t_train), (x_test, t_test) = load_mnist(normalize=True) train_size = x_train.shape[0] batch_size = 128 max_iterations = 2000 # 1:実験の設定========== optimizers = {} optimizers['SGD'] = SGD() optimizers['Momentum'] = Momentum() optimizers['AdaGrad'] = AdaGrad() optimizers['Adam'] = Adam() #optimizers['RMSprop'] = RMSprop() networks = {} train_loss = {} for key in optimizers.keys(): networks[key] = MultiLayerNet( input_size=784, hidden_size_list=[100, 100, 100, 100], output_size=10) train_loss[key] = [] # 2:訓練の開始========== for i in range(max_iterations): batch_mask = np.random.choice(train_size, batch_size) x_batch = x_train[batch_mask] t_batch = t_train[batch_mask] for key in optimizers.keys(): grads = networks[key].gradient(x_batch, t_batch) optimizers[key].update(networks[key].params, grads) loss = networks[key].loss(x_batch, t_batch) train_loss[key].append(loss) if i % 100 == 0: print( "===========" + "iteration:" + str(i) + "===========") for key in optimizers.keys(): loss = networks[key].loss(x_batch, t_batch) print(key + ":" + str(loss)) # 3.グラフの描画========== markers = {"SGD": "o", "Momentum": "x", "AdaGrad": "s", "Adam": "D"} x = np.arange(max_iterations) for key in optimizers.keys(): plt.plot(x, smooth_curve(train_loss[key]), marker=markers[key], markevery=100, label=key) plt.xlabel("iterations") plt.ylabel("loss") plt.ylim(0, 1) plt.legend() plt.show()
そして結果が↓となる。
黄色ハイライトにあるように、今回もAdamの結果がイチバン最適化されている。
とはいうものの、必ずしも毎回Adamがイイとは限らない。
それぞれの最適化手法には特徴があり、
全てのモンダイで優れた手法というのは今のところない。