【Python】ディープラーニングの最適化とは?代表的な手法と使い分けを解説!

  • URLをコピーしました!

今回は、ディープラーニングの最適化について解説します。

代表的な最適化の手法を4つ、使い分けを解説していきます。

また、代表的な最適化の手法をPythonを使用し、実装する方法も合わせて説明していきます。

動画で詳しく学習したい方はこちらもおすすめ

目次

最適化とは

最適化は、予測値の精度を向上させるために、最適なパラメータを探す方法です。

ディープラーニングでは、ある入力から正しい出力を予測するために、重み、バイアスといったパラメータを調整します。

出力(予測値)と正解値の誤差をできるだけ小さくなるようにパラメータを調整していきます。

代表的な最適化の手法

最適化の手法は、いくつかあり、状況によって使い分けます。

ここでは以下の代表的な手法について紹介していきます

  • 確率的勾配降下法(SGD)
  • Momentum
  • AdaGrad
  • Adam

それぞれについて詳しく説明していきます。

1. 確率的勾配降下法(SGD)

最も基本的な最適化手法です。

ミニバッチごとに損失の勾配を計算し、パラメータを更新します。

以下の式で表されます。

$$ \textbf{W}_{t+1} = \textbf{W}_t – \eta\frac{\partial L}{\partial \textbf{W}_t} $$

\( \textbf{W} \): 重み \( \eta \): 学習係数 \( \frac{\partial L}{\partial \textbf{W}} \): 損失関数の勾配

損失関数の勾配を使用し、重みを更新していきます。

2. Momentum

Momentum(モーメンタム)は、SGDに「運動量」の要素を追加した手法です

以下の式で表されます。

$$ \textbf{v}_{t+1} = \alpha\textbf{v}_t – \eta\frac{\partial L}{\partial \textbf{W}_t} $$

$$ \textbf{W}_{t+1} = \textbf{W}_t + \textbf{v}_t $$

3. AdaGrad

AdaGradは、学習が進む(勾配が小さくなる)につれて学習係数を小さくする手法です。

以下の式で表されます。

$$ \textbf{h}_{t+1} = \textbf{h} + \frac{\partial L}{\partial \textbf{W}_t} \cdot \frac{\partial L}{\partial \textbf{W}_t} $$

$$ \textbf{W}_{t+1} = \textbf{W}_t – \eta\frac{1}{\sqrt{\textbf{h}}}\frac{\partial L}{\partial \textbf{W}_t} $$

学習係数\( \eta \)に\( \frac{1}{\sqrt{\textbf{h}}} \)を掛けることで、学習が進むにつれて学習係数が小さくなることを意味しています。

4. Adam

Adamは、先ほど紹介した「Momentum」と「AdaGrad」をかけ合わせた手法です。

この2つの手法のいいとこ取りをしています。

最近では、多くのひとがこのAdamを使用しています。

各手法の使い分け

これまで紹介した最適化の手法の使い分けは以下の通りです。

手法特徴用途
SGDシンプル学習過程を厳密に調整したいとき
MomentumSGDを高速化層が深いデータのとき
AdaGrad勾配に応じて学習係数を調整勾配が均一でないデータのとき
AdamMomentumとAdaGradのかけ合わせ一般的な用途

Python実践 最適化

それでは、Pythonを使用し最適化の各手法を実装する方法を紹介します。

Python実践 確率的勾配降下法(SGD)

Pythonを使用し、SGDを実装する方法を紹介します。

サンプルコードは以下の通りです。

import numpy as np
# パラメータ(重み)
param = np.array([1.0, 2.0])
# 勾配
grad = np.array([0.1, -0.2])
# 学習率
lr = 0.01

def Sgd(param, grad, lr=0.01):
    param -= lr * grad
    return param

# 実行例
param = sgd(param, grad, lr)
print("SGD後のparam:", param)

実行結果

SGD後のparam: [0.999 2.002]

学習係数lrに勾配をかけた値を引くことでパラメータを更新します。

Python実践 Momentum

Pythonを使用し、Momentumを実装する方法を紹介します。

サンプルコードは以下の通りです。

import numpy as np
# パラメータ(重み)
param = np.array([1.0, 2.0])
# 勾配
grad = np.array([0.1, -0.2])
# 学習率
lr = 0.01

def Momentum(param, grad, v, lr=0.01, momentum=0.9):
    v = momentum * v - lr * grad
    param += v
    return param, v

# 初期化
v = np.zeros_like(param)

# 実行例
param, v = Momentum(param, grad, v, lr)
print("Momentum後のparam:", param)

実行結果

Momentum後のparam: [0.99 2.02]

Python実践 AdaGrad

Pythonを使用し、AdaGradを実装する方法を紹介します。

サンプルコードは以下の通りです。

import numpy as np
# パラメータ(重み)
param = np.array([1.0, 2.0])
# 勾配
grad = np.array([0.1, -0.2])
# 学習率
lr = 0.01

def Adagrad(param, grad, h, lr=0.01):
    h += grad * grad
    param -= lr * grad / (np.sqrt(h) + 1e-8)
    return param, h

# 初期化
h = np.zeros_like(param)

# 実行例
param, h = Adagrad(param, grad, h, lr)
print("AdaGrad後のparam:", param)

実行結果

AdaGrad後のparam: [0.99 2.01]

Python実践 Adam

最後に、Pythonを使用し、Adamを実装する方法を紹介します。

サンプルコードは以下の通りです。

import numpy as np
# パラメータ(重み)
param = np.array([1.0, 2.0])
# 勾配
grad = np.array([0.1, -0.2])
# 学習率
lr = 0.01

beta1=0.9
beta2=0.999

def adam(param, grad, m, v, t, lr=0.001):
    t += 1
    m = beta1 * m + (1 - beta1) * grad
    v = beta2 * v + (1 - beta2) * (grad * grad)
    
    m_hat = m / (1 - beta1 ** t)
    v_hat = v / (1 - beta2 ** t)
    
    param = param - lr * m_hat / (np.sqrt(v_hat) + 1e-8)
    return param, m, v, t

# 初期化
m = np.zeros_like(param)
v = np.zeros_like(param)
t = 0

# 実行例
param, m, v, t = adam(param, grad, m, v, t, lr=0.001)
print("Adam後のparam:", param)

実行結果

Adam後のparam: [0.999 2.001]

まとめ

ディープラーニングの「最適化」について紹介しました。

最適化は、予測値の精度を向上させるために使用する手法です。

代表的な最適化の手法には以下があります。

  • 確率的勾配降下法(SGD)
  • Momentum
  • AdaGrad
  • Adam

それぞれ用途が異なるので、ぜひ各手法の特徴を覚えておくとよいと思います!

ここまで読んでくださりありがとうございます。

よかったらシェアしてね!
  • URLをコピーしました!

この記事を書いた人

エンジニア。20代。組み込みエンジニアとして働き始めるも、働き方や業務内容に限界を感じ、 AI,Web3エンジニアを目指して勉強中。 エンジニアとして思うことや、学んだことを発信します。

目次