AIが賢くなる秘密の鍵!初心者でもわかる最適化アルゴリズムの世界
こんにちは。ゆうせいです。
みなさんは、AIがどうやって学習を進めているか想像したことはありますか?実はAIの学習とは、山頂からふもとの「正解」というゴールを目指して、険しい山道を下るような作業なのです。
この山を下るための戦略を、専門用語で「最適化アルゴリズム」と呼びます。どの道を選び、どれくらいのスピードで歩くのか。この戦略一つで、AIが天才になるかどうかが決まってしまうと言っても過言ではありません!
今回は、現代のAI開発には欠かせない5つの代表的な手法を、初心者の方にもわかりやすく解説しますね。
基本のキ!SGD(確率的勾配降下法)
まずは、すべての基本となるSGDから紹介しましょう。
仕組みと特徴
SGDを一言で表すと「足元の傾斜だけで進む」という、非常にストレートな方法です。目隠しをして山に立たされ、足の裏で感じる地面の角度だけを頼りに、一番低い場所を探すと想像してください。
数式で表すと、以下のようになります。
新しい値 = 元の値 - 学習率 今の傾き
ここで登場する「学習率」とは、一歩の大きさを決める歩幅のことです。今の傾きが急であれば大きく、緩やかであれば小さく動きます。
メリットとデメリット
メリットは、計算が非常にシンプルで動作が軽い点にあります。余計なことを考えず、今の状況に集中するタイプですね。
しかし、足元の情報しか見ていないため、小さな穴ぼこや、なだらかな平地が続く場所に迷い込むと、そこがゴールだと思い込んで動けなくなってしまう弱点があります。
勢いをつけて駆け抜ける!Momentum(モーメンタム)
次に登場するのが、SGDに「勢い」を加えたMomentumです。
仕組みと特徴
Momentumとは、物理の言葉で「慣性」を意味します。重いボールが坂道を転がるとき、スピードに乗ると少々のデコボコは気にせず突き進みますよね?
新しい値 = 元の値 - 学習率 (今の傾き + 過去の勢い)
このように、今の傾きだけでなく、これまでの進んできた勢いも計算に含めます。
メリットとデメリット
最大のメリットは、SGDが苦手としていた小さな窪みを、スピードに乗って突破できる点です。
ただ、勢いがつきすぎてしまい、本来止まるべきゴール地点を通り過ぎてしまうこともあります。まるでお調子者のランナーのようですね!
慎重派の歩幅調整!AdaGrad(アダグレード)
ここからは、歩幅を賢く変えていく手法を見ていきましょう。
仕組みと特徴
AdaGradは、過去にどれくらい動いたかに応じて、自分自身の歩幅(学習率)を自動で調整します。
新しい値 = 元の値 - (学習率 過去の傾きの蓄積)
今の傾き
何度も通って傾きが蓄積された道では、分母が大きくなるため、一歩の歩幅が小さくなります。
メリットとデメリット
初めて通る道は大胆に、よく知っている道は慎重に進むため、効率よく探索ができます。
一方で、学習が長く続くと蓄積された値がどんどん大きくなり、最終的には歩幅が極端に小さくなって、ゴールにたどり着く前に足が止まってしまうという致命的な弱点があります。
過去を適度に忘れる!RMSProp(アールエムエスプロップ)
AdaGradの「歩幅がなくなってしまう」という問題を解決したのが、このRMSPropです。
仕組みと特徴
仕組みはAdaGradに似ていますが、大きな違いは「古い記憶を適度に忘れる」という点にあります。
新しい値 = 元の値 - (学習率 最近の傾きの大きさ)
今の傾き
ずっと昔の蓄積をいつまでも抱え込まず、直近の傾きを重視して歩幅を決めます。
メリットとデメリット
AdaGradのメリットを活かしつつ、途中で足が止まるリスクを回避しました。非常にバランスの取れた手法です。
最強のハイブリッド!Adam(アダム)
最後に紹介するのが、現在もっとも人気のあるAdamです。
仕組みと特徴
Adamは、いわば「Momentum」の勢いと、「RMSProp」の賢い歩幅調整をガッチャンコさせた最強のアルゴリズムです。
新しい値 = 元の値 - (学習率 最近の傾きの大きさ)
(今の傾き + 過去の勢い)
勢いよく進みながら、状況に合わせて歩幅も変える。まさに非の打ち所がない現代の標準装備と言えます!
メリットとデメリット
ほとんどのケースにおいて、このAdamを選んでおけば間違いありません。それくらい優秀です。
弱点を挙げるとすれば、計算が少し複雑になるため、ほんの少しだけ処理に時間がかかることくらいでしょうか。
手法の比較まとめ
これまでの内容を表にまとめてみました。
| 手法名 | 特徴 | イメージ |
| SGD | 単純明快 | 足元の坂を下る |
| Momentum | 加速重視 | 勢いで突破する |
| AdaGrad | 慎重な歩幅 | 慣れた道はゆっくり |
| RMSProp | 改善された歩幅 | 過去を忘れて効率よく |
| Adam | 最強の合体 | 勢いよく、かつ賢く |
視覚的に確認できるPythonコード
各コードを実行すると、グラフが保存されるか画面に表示されます。ぜひ手元で動かしてみてくださいね。
準備:実験する「山」を定義する
まずは、私たちが下る山(関数)を決めましょう。
ここでは、 という、きれいな谷底(
)を持つ放物線を想定します。この谷底を見つけるのがプログラムのゴールです。
今の場所( )における傾きは、
で求められます。
1. SGD:コツコツ一歩ずつ進む
まずは基本のSGDです。坂道の角度に合わせて一定のルールで下りていきます。
import matplotlib.pyplot as plt
# 設定
x = 10.0
lr = 0.1
x_history = [x]
# 学習
for i in range(20):
grad = 2 * x
x = x - lr * grad
x_history.append(x)
# 可視化
plt.plot(x_history, 'o-', label='SGD')
plt.title('SGD Optimization')
plt.xlabel('Steps')
plt.ylabel('x value')
plt.legend()
plt.show()実行結果
2. Momentum:加速して一気に下る
過去の勢いを利用するため、最初はゆっくり、後半は加速していく様子に注目してください!
import matplotlib.pyplot as plt
# 設定
x = 10.0
lr = 0.05
v = 0
gamma = 0.9
x_history = [x]
# 学習
for i in range(20):
grad = 2 * x
v = gamma * v - lr * grad
x = x + v
x_history.append(x)
# 可視化
plt.plot(x_history, 'o-', color='orange', label='Momentum')
plt.title('Momentum Optimization')
plt.xlabel('Steps')
plt.ylabel('x value')
plt.legend()
plt.show()勢いがつきすぎて正解(x = 0)を飛び越えてしまっています。
3. AdaGrad:学習が進むほど慎重に
最初は大きく動きますが、次第に歩幅が小さくなっていくのがグラフの傾きからわかります。
import matplotlib.pyplot as plt
import numpy as np
# 設定
x = 10.0
lr = 1.5
h = 0
x_history = [x]
# 学習
for i in range(20):
grad = 2 * x
h = h + grad * grad
x = x - (lr / (np.sqrt(h) + 1e-7)) * grad
x_history.append(x)
# 可視化
plt.plot(x_history, 'o-', color='green', label='AdaGrad')
plt.title('AdaGrad Optimization')
plt.xlabel('Steps')
plt.ylabel('x value')
plt.legend()
plt.show()
4. RMSProp:効率よく、止まらずに進む
AdaGradのように極端に歩幅が小さくなりすぎず、スムーズにゴールへ向かいます。
import matplotlib.pyplot as plt
import numpy as np
# 設定
x = 10.0
lr = 0.6
h = 0
rho = 0.9
x_history = [x]
# 学習
for i in range(20):
grad = 2 * x
h = rho * h + (1 - rho) * grad * grad
x = x - (lr / (np.sqrt(h) + 1e-7)) * grad
x_history.append(x)
# 可視化
plt.plot(x_history, 'o-', color='red', label='RMSProp')
plt.title('RMSProp Optimization')
plt.xlabel('Steps')
plt.ylabel('x value')
plt.legend()
plt.show()
5. Adam:素早く正確にゴールへ
「勢い」と「歩幅調整」の良いとこ取りをしているので、非常に効率的なカーブを描きます!
import matplotlib.pyplot as plt
import numpy as np
# 設定
x = 10.0
lr = 0.6
m = 0
v = 0
beta1 = 0.9
beta2 = 0.999
x_history = [x]
# 学習
for i in range(20):
grad = 2 * x
m = beta1 * m + (1 - beta1) * grad
v = beta2 * v + (1 - beta2) * (grad * grad)
m_hat = m / (1 - beta1**(i+1))
v_hat = v / (1 - beta2**(i+1))
x = x - lr * m_hat / (np.sqrt(v_hat) + 1e-7)
x_history.append(x)
# 可視化
plt.plot(x_history, 'o-', color='purple', label='Adam')
plt.title('Adam Optimization')
plt.xlabel('Steps')
plt.ylabel('x value')
plt.legend()
plt.show()
さいごに
5つのグラフを見比べてみて、何か気づいたことはありましたか?
同じゴール( )を目指していても、そのたどり着き方はアルゴリズムによって千差万別です。
学習率( )の数字を少し変えるだけで、グラフの形が劇的に変わるのも面白いポイントですよ!
次は、これらのアルゴリズムを使って、実際のデータから「予測」を行う本格的な機械学習に挑戦してみませんか?