やりたいこと
- Pytorchを使用した機械学習の用語を理解する
- 参考書はこちらを使用
Tensor
- 多次元配列を扱うためのデータ構造
- Numpyのndarrayと似てる
- GPUの計算が可能
- ndarrayへの変換には,一度CPU上に移すことが必要
- requires_gradをTrueにすることで"自動微分"が可能
尤度
- 互いに独立なN個のデータの確率関数の値の積をΘとした関数
- 計算のしやすさから"対数尤度"の使用が一般的
最尤推定
- 尤度を最大とするパラメータΘを求めること
勾配降下法
- 対数尤度関数の微分が解けない場合に用いる数値最適化手法
- 対数尤度関数の符号を反転させたもの(損失関数)を最小化することが目的
- 勾配(微分係数)を利用して繰り返し最適化
勾配
- 全ての変数の偏微分をベクトルとしてまとめたもの
偏微分
- 複数の変数からなる関数の微分
微分
- ある瞬間の変化量
学習率
- 値が大きいと,損失関数の減少は速いが,収束せずに振動してしまう
- 値が小さいと,損失関数の減少が遅く,計算に時間がかかってしまう
- 調整が必要
ミニバッチ
- 対数尤度関数のように損失関数が同じ形の関数の和に分解できる場合,そこからランダムな値を得ること
誤差逆伝播法
- 重みパラメータの"勾配の"計算を効率的に行う手法
- 連鎖率を使用して計算
連鎖率
- ある関数が合成関数で表されるとき,その合成関数の微分は,合成関数を構成するそれぞれの関数の積で表せる
- "勾配を"効率的に計算可能
確率的勾配降下法(SGD)
- ミニバッチを使用した勾配降下法
- オプティマイザー(最適化アルゴリズム)の一種
- AdamなどはSGDの改良版
- 計算した勾配を使用して"パラメータを"更新する方法
ニューラルネットワークの学習
- ミニバッチ処理
- 訓練データからランダムに一部のデータを取り出す
- 順伝搬で損失を計算
- 各層の計算
- 予測値の出力
- 損失関数による誤差の導出
- 勾配の算出
- 誤差逆伝播法で計算
- パラメータの更新に必要な勾配を計算
- パラメータの更新
- SGDなどを使用
- 学習率や勾配などを使用
メモ1
- "勾配降下法"と"自動微分"を組み合わせることで,複雑な尤度関数も最適化可能
線形回帰モデル
- 複数の変数から1つまたは,複数の値を予測するための手法
- xからyを予測することが目的
- yは連続変数であることから回帰問題と呼ばれる
- 目的変数がパラメータaの一次式で表せる
- 確率モデルの一種
- 平均二乗誤差(MSE)をSGDで最小化することによって最尤推定が可能
ロジスティック回帰
- 名前に回帰とあるが,分類のための線形モデル
- 目的変数yは離散値
- 変数の線形結合だけでは値が[-∞, ∞]になるため,シグモイド関数(活性化関数)で[0, 1]の間の値に変換
- [0, 1]の間の値は「確立」で扱うことが可能
- ベルヌーイ分布に従うと仮定できる
- ベルヌーイ分布の"負の対数尤度"(損失関数)は,クロスエントロピーの一種
ベルヌーイ分布
- 1回の試行で成功・失敗かを表せる分布
- 二値分類を「確率」として扱うことを可能にした分布
クロスエントロピー
- 真の分布とモデルが予想した分布とのズレを測る量
- 概念であって単一の固定された式ではない
- 代入する分布によって式が変わる
多クラスのロジステック回帰
- ソフトマックスクロスエントロピーという損失関数を使用
- クロスエントロピーの多クラス版
多層パーセプトロン(MLP)
- 線形層を繋げたモデル
- 入力層,中間層(隠れ層),出力層を持つ
- 活性化関数で非線形に変換することで,複雑な関数を学習可能
- 層が一直線に積み重なったニューラルネットワーク(NN)を"Feedforward"型と呼ぶ
- Feedforward型のNNの微分を求めるに,動的計画法(Back propagation)を使用
TensorDataset
- ミニバッチ学習,データのシャッフル,並列処理等をPytorchで簡単に試すことが可能
- Datasetを継承したクラスで,特徴量XとラベルYのコンテナ
- DataLoaderに渡すことでデータの一部を簡単に受け取り可能
- Tensorのみ扱える
過学習
- 訓練用データにパラメータが最適化されすぎて他のデータでの判別が困難となる現象
- 少ないデータで深く学習させた場合などに起りやすい
正則化
- 過学習を抑えること
- Dropoutという,ランダムに一部のノード(変数)を意図的に使用しない方法が一般的
- Dropoutは,訓練時のみに使用し,予測時は使用しない方法が一般的
- "train"と"eval"メソッドでDropoutの有無を切り替え可能
Bach Nomalization
- 学習を安定化,加速させる方法
- Dropoutと同様,訓練時のみ使用
- ミニバッチ単位で,データの分布の平均が0,分散が1になるように正規化
- "train"と"eval"メソッドでBach Nomalizationの有無を切り替え可能
カスタム層
- nn.Moduleを継承したクラスを定義
- forwardメソッドで自動微分が可能
- nn.Moduleの__call__メソッドは内部でforwardメソッドを使用
- nn.Sequentialを使用せずにnn.Moduleだけで記述可能
class CustomLinear(nn.Module):
def __init__(self, in_features, out_features, bias=True, p=0.5):
super().__init__()
self.linear = nn.Lineare(in_features, out_features, bias)
self.relu = nn.ReLU()
self.drop = nn.Dropout(p)
def forward(self, x): # 計算グラフを構築
x = self.linear(x)
x = self.relu(x)
x = self.drop(x)
return x
class MyMLP(nn.Module):
def __init__(self, in_features, out_features):
super().__init__()
self.ln1 = CustomLinear(in_features, 200) # 64→200
self.ln2 = CustomLinear(200, 200)
self.ln3 = CustomLinear(200, 200)
self.ln4 = CustomLinear(200, out_features) # 200→10
def forward(self, x):
x = self.ln1(x)
x = self.ln2(x)
x = self.ln3(x)
x = self.ln4(x)
return x
mlp = MyMLP(64, 10)