機械学習、特に深層学習を学ぶ上で、確率的勾配降下法(Stochastic Gradient Descent:SGD)は必須の知識です。今回の記事では、このSGDについて詳しく解説し、それがどのように実装されるかについて説明します。
SGDは機械学習における最適化アルゴリズムの一つで、特に深層学習(ニューラルネットワーク)の訓練で広く利用されています。基本的な考え方は、全体のデータセットを用いて勾配を計算する代わりに、ランダムに選択した一部のデータ(ミニバッチ)のみを用いて勾配を計算し、それに基づいてパラメータ(重みとバイアス)を更新するというものです。これにより、計算効率が大幅に向上します。確率的勾配降下法というよりも、「勾配を利用した損失の最小化手法」や「勾配に従って損失の最小値を探す手法」のような表現のほうが直感的にわかりやすいかもしれません。「確率的」であると呼ばれる理由は、各ステップで使用するデータサンプルがランダムに選択されるためです。この結果、パラメータの更新は確定的ではなく、一種の確率的な性質を持ちます。
SGDの実装は以下のようになります。
import torch
import torch.nn as nn
import torch.optim as optim
# 入力データ(身長と体重)
input_data = torch.tensor([180.0, 70.0])
# ニューラルネットワークの定義
model = nn.Sequential(
nn.Linear(2, 2), # 隠れ層(入力2次元、出力2次元)
nn.ReLU(), # 活性化関数(ReLU)
nn.Linear(2, 1), # 出力層(入力2次元、出力1次元)
)
# 仮のラベル(ここでは、この人物が合格するとします)
label = torch.tensor([1.0])
# 損失関数(平均二乗誤差)
loss_fn = nn.MSELoss()
# オプティマイザ(確率的勾配降下法)
optimizer = optim.SGD(model.parameters(), lr=0.01)
# モデルの出力
output = model(input_data)
# 損失の計算
loss = loss_fn(output, label)
# 勾配の計算
loss.backward()
# パラメータの更新
optimizer.step()
# 新しいモデルの出力
new_output = model(input_data)
# 新しい損失の計算
new_loss = loss_fn(new_output, label)
コードの中にあるbackward()
とSGD
はどのように関係しているのでしょうか?
backward()
は、PyTorchの自動微分エンジンにより、損失関数の勾配を自動的に計算するメソッドです。これにより、各パラメータに関する損失関数の勾配が計算されます。
一方、SGDは、これらの勾配を利用してパラメータを更新します。つまり、backward()
で計算された勾配を元に、パラメータを現在の値から学習率に比例したステップだけ勾配の逆方向(つまり誤差が減少する方向)に移動させることで、モデルのパラメータを更新します。
以上、SGDとその実装について解説しました。確率的勾配降下法は、ディープラーニングの最適化手法の一つで、ミニバッチという小さなデータセットを用いて効率的にパラメータの更新を行います。これにより、大量のデータを扱うディープラーニングの学習が実現可能となります。
なお、SGDと勾配計算は密接な関係性を持ちますが、それぞれが独立して行われます。つまり、SGDはパラメータの更新を行いますが、そのために必要な勾配はbackward()
メソッドによって計算されます。
これらを理解することで、ディープラーニングの背後にある基本的なメカニズムを理解し、より効果的なモデルを設計することが可能になります。