banner
Fight4354

Fight4354

AI,Chem,Science,Study,Share,Hobby,LLM,Life,Sport

Pytorch学習記録

最近、李沐大神の「動手学深度学习」コースを見ています。ここで、いくつかの重要な知識点を記録しておきます。知識があちこちに散らばらないように、知識をまとめましょう。

1、PyTorch の backward はスカラーでなければならない#

import torch
x = torch.arange(4.0,requires_grad=True)
y = 2 * torch.dot(x,x)
y.backward()
# デフォルトでは、PyTorchは勾配を蓄積するため、以前の値をクリアする必要があります
# 非スカラーに対して 'backward' を呼び出すには、微分関数を指定する 'gradient' パラメータを渡す必要があります
x.grad.zero_()  # 以前のxの勾配をクリア
y = x * x  # ここでのyはスカラーではなく、ベクトルです
print(y)
# y.backward(torch.ones(len(x))) と同等です
y.sum().backward() # y.sum()の後にベクトルをスカラーに変換し、スカラーの微分を求めます
x.grad

🔹 重要なポイント:PyTorch の backward はスカラーでなければならない

PyTorch では、.backward() の設計は 連鎖律 に基づいており、主にスカラー(単一の出力値)に対する入力の勾配に関係しています。

y.backward() を呼び出す場合、ここでの y はスカラーでなければなりません。なぜなら:

xy=yx\nabla_x y = \frac{\partial y}{\partial x}
  • xy\nabla_x yy の x に関する勾配 と呼ばれます。

  • yx\frac{\partial y}{\partial x}y の x に対する偏導関数 です。

しかし、具体的に何であるかは、$y$ と $x$ の次元によります。


🔸 ケース 1:y はスカラー、x はベクトル

仮定:

  • xRnx \in \mathbb{R}^n

  • yRy \in \mathbb{R}

したがって:

xy=[yx1yx2yxn]Rn\nabla_x y = \begin{bmatrix} \frac{\partial y}{\partial x_1} \\ \frac{\partial y}{\partial x_2} \\ \vdots \\ \frac{\partial y}{\partial x_n} \end{bmatrix} \in \mathbb{R}^n

つまり:

長さ nn のベクトルで、y が各 x 成分に対する偏導数を表します。

これは機械学習で最も一般的なケースであり、例えば 損失が重みの勾配 に関するものです。


🔸 ケース 2:y はベクトル、x はベクトル

仮定:

  • xRnx \in \mathbb{R}^n

  • yRmy \in \mathbb{R}^m

したがって:

yx=JRm×n\frac{\partial y}{\partial x} = J \in \mathbb{R}^{m \times n}

この行列 JJヤコビ行列 と呼ばれ、その (i,j)(i, j) 要素は:

Jij=yixjJ_{ij} = \frac{\partial y_i}{\partial x_j}

2、ヤコビ行列#

ヤコビ行列は:

ベクトル関数の入力ベクトルに対する偏導行列 です。

仮定:

  • 入力:xRnx \in \mathbb{R}^n

  • 出力:y=f(x)Rmy = f(x) \in \mathbb{R}^m

ヤコビ行列:

J(x)=yx=[y1x1y1xnymx1ymxn]Rm×nJ(x) = \frac{\partial y}{\partial x} = \begin{bmatrix} \frac{\partial y_1}{\partial x_1} & \cdots & \frac{\partial y_1}{\partial x_n} \\ \vdots & \ddots & \vdots \\ \frac{\partial y_m}{\partial x_1} & \cdots & \frac{\partial y_m}{\partial x_n} \\ \end{bmatrix} \in \mathbb{R}^{m \times n}

直感的には:

  • ii 行:yiy_i がすべての xjx_j に対する偏導。

  • 説明:入力変数の小さな変動が各出力変数に与える線形影響。

3、ヘッセ行列#

ヘッセ行列は:

スカラー関数の入力ベクトルに対する二次偏導行列 です。

仮定:

  • 入力:xRnx \in \mathbb{R}^n

  • 出力:y=f(x)Ry = f(x) \in \mathbb{R}

ヘッセ行列:

H(x)=2yx2=[2yx122yx1x22yx2x12yx22]Rn×nH(x) = \frac{\partial^2 y}{\partial x^2} = \begin{bmatrix} \frac{\partial^2 y}{\partial x_1^2} & \frac{\partial^2 y}{\partial x_1 \partial x_2} & \cdots \\ \frac{\partial^2 y}{\partial x_2 \partial x_1} & \frac{\partial^2 y}{\partial x_2^2} & \cdots \\ \vdots & \vdots & \ddots \\ \end{bmatrix} \in \mathbb{R}^{n \times n}

しかし、yyベクトル の場合、勾配は実際には ヤコビ行列 であり、単一の勾配ベクトルではありません:

Jij=yixjJ_{ij} = \frac{\partial y_i}{\partial x_j}

4、pytorch における dtype と type の違い#

まず結論を示します:

dtype はテンソル内の要素の具体的な数値型であり、type はテンソルオブジェクト自体の Python 型(デバイス情報を含む)です。

それぞれが注目するレベルは全く異なります。


📍 1️⃣ dtype とは?

  • 指:テンソル内の各要素のストレージタイプ。

  • 例:

    • torch.float32 → 単精度浮動小数点数

    • torch.int64 → 64 ビット整数

    • torch.bool → ブール型

コードを見てみましょう:

x = torch.tensor([1, 2, 3], dtype=torch.float32)
print(x.dtype)  # 出力:torch.float32

これは「このテンソルの要素がどのフォーマットで保存されているか」を教えてくれます。


📍 2️⃣ type とは?

  • 指:PyTorch におけるテンソルオブジェクトのフルネーム、データ型とデバイスを含む。

  • 例:

    • torch.FloatTensor → float32 の CPU テンソル

    • torch.cuda.FloatTensor → float32 の GPU テンソル

    • torch.IntTensor → int32 の CPU テンソル

コードを見てみましょう:

x = torch.tensor([1, 2, 3])
print(x.type())  # 出力:torch.IntTensor(またはシステムのデフォルトタイプ)

これは「このテンソルオブジェクトが PyTorch システム内での完全なタイプ名」を教えてくれます。


📍 ⚠ 重要な違い

比較項目dtypetype
注目点要素の数値型テンソルオブジェクトの完全な PyTorch タイプ(デバイス情報を含む)
torch.float32, torch.int64torch.FloatTensor, torch.cuda.FloatTensor
主な用途精度、ストレージ、計算関連異なるテンソルの種類を区別し、デバッグ / チェック用
変更方法.to(dtype).float().type()(全体のタイプオブジェクトを変更)

5、ソフトラベル vs ハードラベル#

通常、分類モデルを訓練する際に使用するラベルは:
ハードラベル(hard label)
例えば、3 クラス分類タスクの場合、実際のラベル:

クラス A → [1, 0, 0]
クラス B → [0, 1, 0]
クラス C → [0, 0, 1]

このようなラベルは完全に ワンホットエンコーディング (one-hot) で、正誤のみを認識します。


ソフトラベル(soft label) は次のようになります:

各クラスに確率が対応し、ハードな 0 または 1 ではありません。

例えば:

ある画像に対して、ソフトラベル → [0.7, 0.2, 0.1]

これは次のことを示します:

  • クラス A である確率は 70%

  • クラス B である確率は 20%

  • クラス C である確率は 10%

言い換えれば、ラベルは「曖昧性を認める」ものであり、全か無かではありません。


6、ソフトマックス回帰とロジスティック回帰#

** 📦 共通点 **

本質的には分類モデル
✅ 線形関数 + 活性化(シグモイドまたはソフトマックス)を使用
✅ 損失関数として交差エントロピー(cross entropy)を使用

しかし、異なるタスクに使用されます。


🌟 主な違い


プロジェクトロジスティック回帰ソフトマックス回帰
タスクタイプ二分類(binary classification)多分類(multi-class classification)
出力層の活性化関数シグモイド(単一出力 0~1)ソフトマックス(ベクトル出力、各クラスの確率)
出力次元1 次元C 次元(C = クラス数)
目標ラベル0 または 1ワンホットエンコーディング、例えば [0,0,1,0]
決定方法出力 > 0.5 を正クラスと判定最大確率のクラスを予測結果とする


📊 ロジスティック回帰の詳細

  • あなたが持っていると仮定します:

    • 入力特徴 xx

    • 重み ww とバイアス bb

  • モデル計算:
    y^=σ(wTx+b)\hat{y} = \sigma(w^T x + b)
    ここで sigma\\sigma はシグモイド関数です。

出力 haty\\hat{y} は確率値(0 から 1)で、正クラスの確率を表します。

損失関数:
Binary Cross Entropy=[ylog(y^)+(1y)log(1y^)]\text{Binary Cross Entropy} = -[y \log(\hat{y}) + (1-y)\log(1-\hat{y})]


📊 ソフトマックス回帰の詳細

  • あなたが持っていると仮定します:

    • 入力特徴 xx

    • 重み行列 WW(形状: num_features × num_classes)

    • バイアス bb

  • モデル計算:
    y^i=ezijezj\hat{y}_i = \frac{e^{z_i}}{\sum_j e^{z_j}}
    ここで z=WTx+bz = W^T x + b

出力 $\hat {y}$ は長さ C のベクトルで、各要素は対応するクラスの確率です。

損失関数:
Cross Entropy=iyilog(y^i)\text{Cross Entropy} = -\sum_i y_i \log(\hat{y}_i)


** 🧠 なぜロジスティック回帰を多分類に直接使用できないのか?**

シグモイドは単一の値しか出力せず、多分類では複数のクラスの確率を出力する必要があり、これらの確率は次の条件を満たさなければなりません:

合計が 1 で、互いに排他的であること。

これがソフトマックスの設計目的です。


一言でまとめると

ロジスティック回帰 ≈ 2 クラスのソフトマックスの特例
ソフトマックス回帰 = 多分類のロジスティック回帰の拡張版


7、尤度と確率#

🌟 尤度関数とは何か?

簡単に言うと:

尤度関数(likelihood function)は、与えられたモデルパラメータの下で、観測されたデータの確率です。

これは次のように理解できます:
モデルがあるパラメータを仮定 → このパラメータの下で、現在手元にあるデータを生成する「可能性」がどれくらいあるか。


📊 確率との違いは?

多くの人が混同しやすいです:
✅ 確率:パラメータが既知で、事象の可能性を計算します。
✅ 尤度:データが既知で、どのパラメータがこれらのデータを生成する可能性が高いかを見ます。

数学的な公式は似ていますが、用途は逆になります。



🏗️ 数学的表現

仮定:

  • データ:x1,x2,...,xnx_1, x_2, ..., x_n

  • パラメータ:θ\theta

確率

P(xθ)P(x | \theta)

尤度関数

L(θx)=P(xθ)L(\theta | x) = P(x | \theta)

違いは:

  • 確率:θ\theta が固定され、xx を見ます。

  • 尤度:xx が固定され、θ\theta を見ます。



🌟** 簡単な例を挙げると **

あなたがコインを持っていて、10 回投げて、結果が 7 回表だったとします。
コインの表の確率 pp を推定したいとします。


モデル仮定
コインを投げる回数:10
表の確率:pp
事象:7 回表


尤度関数

L(p)=Cp7(1p)3L(p) = C \cdot p^7 (1-p)^3

ここで:

  • CC は組み合わせ数(固定値で、最大化には影響しません)。

  • 核心は:

    pp が与えられたとき、このデータ(7 表 3 裏)を生成する確率。


🌟 最大尤度推定(MLE)

通常、私たちは次のようにします:

尤度関数を最大にするパラメータを見つける。

この例では:

  • p7(1p)3p^7 (1-p)^3 を最大化します。

  • 最適な p=7/10=0.7p^* = 7 / 10 = 0.7

これが最大尤度推定です。



🔥 機械学習において

機械学習の多くの訓練は、実際には:

最大尤度を使用してパラメータをフィットさせることです。

例えば:

  • 回帰モデル → ガウス分布の最大尤度

  • 分類モデル → ソフトマックス下の最大尤度

  • ニューラルネットワーク → 交差エントロピー損失は、実際には最大尤度から導かれたものです。



一言でまとめると

尤度関数 = 与えられたパラメータの下で、現在のデータを観測する確率(それをパラメータの関数として見る)。

尤度を最大化することは、データを生成する可能性が最も高いパラメータを見つけることです。

8、パーセプトロン#

パーセプトロン(Perceptron) は非常に基本的な 二分類線形モデル であり、神経ネットワークの最初の形態(単層、隠れ層なし)と見なすことができます。

その主な特徴と要点は:

基本形式
パーセプトロンは、重みベクトル w とバイアス b を使用して、入力特徴ベクトル x に対して線形結合を行い、符号関数(sign function)を通じて出力が +1 か -1 かを決定します。

公式:
  f(x) = sign(w·x + b)

目標
すべてのサンプルが超平面で分けられるように w, b の組を見つけること(すなわち線形可分)。

訓練アルゴリズム

  • 重みとバイアスを初期化(通常はゼロまたは小さな値)。

  • 各誤分類サンプルに対して、重みを更新:
      w ← w + η * y * x
      b ← b + η * y
    ここで η は学習率、y は真のラベル(+1 または -1)。

  • すべてのサンプルが正しく分類されるまで(または最大反復回数に達するまで)繰り返します。

限界(欠点):

  • 線形可分な問題しか処理できない。非線形データ(例えば XOR 問題)には完全に無力です。

  • 確率出力がなく、単なるハード分類です。

  • ノイズや外れ値の影響を受けやすいです。

意義と歴史的地位
現在、深層学習はすでにパーセプトロンを超えていますが、パーセプトロンは神経ネットワークの発展の出発点です。かつて Minsky と Papert が 1969 年に書いた『Perceptrons』という本では、XOR 問題を解決できないことが指摘され、これが AI の冬 の到来を直接引き起こしました。多層ネットワーク(MLP)とバックプロパゲーションアルゴリズムが登場するまで、この限界は打破されませんでした。

9、多層パーセプトロン#

二分類問題の公式
image

image

二分類問題の公式と多分類問題の違いは、w2w_2の形状がmkm*kであることです。(k はクラスの数)

各隠れ層には活性化関数が必要です(非線形関数)。活性化関数がなければ、大きな線形関数と同じです。
出力層には活性化関数は必要ありません。

多層パーセプトロンの多分類問題とソフトマックス回帰の違いは、隠れ層が追加されている点であり、その他は同じです。

コード

import torch
from torch import nn

# モデルを構築し、隠れ層には256の隠れユニットを含み、ReLU活性化関数を使用
net = nn.Sequential(nn.Flatten(),nn.Linear(784,256),nn.ReLU(),nn.Linear(256,10))

コードの説明
nn.Sequential() は、一連のサブモジュール(層、活性化関数など)を順番にスタックして、前方伝播を自動的に組織します。言い換えれば、これは順序付きコンテナであり、必要なネットワークモジュールを順番に包みます。
nn.Flatten() は、入力の多次元テンソルを 1 次元ベクトルに展開します。
MNIST の場合、入力画像の形状は [batch_size, 1, 28, 28](グレースケール画像)で、Flatten 後は [batch_size, 784] になり、全結合層に接続しやすくなります。

10、活性化関数#

シグモイド関数#

シグモイド活性化関数 は次のように定義されます:

σ(x)=11+ex\sigma(x) = \frac{1}{1 + e^{-x}}

出力範囲
(0, 1) —— 任意の実数を 0 と 1 の間にマッピングします。

画像特徴

output

  • S 字型曲線(これがシグモイドと呼ばれる理由で、sigmoid = S 型)。

  • 中心は (0, 0.5) に対称です。

  • xx が非常に大きいか非常に小さい場合、勾配は 0 に近づきます —— 勾配消失。

利点

  • 確率として解釈できます(特に二分類の最後の層に適しています)。

  • 滑らかで、連続的で、微分可能です。

欠点(致命的な)

  • 勾配消失xx が非常に大きいか非常に小さい場合、導関数は 0 に近づき、逆伝播で重みをほとんど更新できません。

  • 出力が 0 を中心にしていない:これにより、勾配更新時の収束が遅くなります。正と負の勾配が非対称です。

  • 飽和しやすい:入力が大きすぎるか小さすぎると、圧縮されます。

現在の主流のやり方

  • 二分類の最後の層を除いて、隠れ層ではほとんどシグモイドを使用せず、代わりに ReLU やその進化版を使用します。

  • 二分類の場合、最後の層にシグモイドを使用し、損失関数にはバイナリ交差エントロピーを使用します。

Tanh 関数#

tanh(双曲正接)活性化関数 は次のように定義されます:

tanh(x)=exexex+ex\tanh(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}}

出力範囲
(-1, 1) —— 任意の実数を -1 から 1 の間に圧縮します。

画像特徴

output

  • S 字型曲線(シグモイドに似ていますが、上下対称です)。

  • 中心は (0, 0) に対称です(これはシグモイドよりも良く、出力の平均が 0 に近く、最適化の収束に役立ちます)。

  • xx が非常に大きいか非常に小さい場合でも、勾配消失が発生します。

利点

  • シグモイドと比較して、出力が 0 を中心にしており、勾配更新に対してより友好的です。

  • 滑らかで、連続的で、微分可能です。

欠点(核心的な問題)

  • シグモイドと同様に、飽和しやすい → 勾配消失。

現在の主流のやり方

  • 対称出力が必要なモデル(例えば RNN)では、tanh は依然として有用です。

  • しかし、深層神経ネットワークの隠れ層では、現代の主流は ReLU およびその改良版を使用しています。

ReLU 関数#

ReLU(Rectified Linear Unit)活性化関数 は次のように定義されます:

ReLU(x)=max(0,x)\text{ReLU}(x) = \max(0, x)

出力範囲
[0,+)[0, +\infty)

画像特徴

output

  • x<0x < 0 の場合、出力は 0 です。

  • x0x \geq 0 の場合、出力は xx です。
    シンプルで、直接的な折れ線です。

利点

  • 計算が簡単で、収束が早い。シグモイド関数や tanh 関数と比較して、両者は指数計算を必要とし、指数演算は高価です。

  • 勾配消失が発生しにくい(正の区間の勾配は常に 1 です)。

  • スパースアクティベーション(多くのニューロンが 0 を出力し、モデルを簡素化するのに役立ちます)。

欠点

  • 死んだ ReLU 問題:もしあるニューロンが訓練中に負の区間に固定され(出力が常に 0)、それ以降更新できなくなる可能性があります(負の区間の勾配は 0 です)。

  • 入力値に対して非対称です(正の値のみを保持します)。

現代の改良版

  • Leaky ReLU:負の区間に非常に小さな傾きを与えます。

  • Parametric ReLU (PReLU):負の区間の傾きを学習可能にします。

  • ELU、GELU、Swish:さらなる改良を加えています。

11、モデルの複雑さ#

image

12、正則化#

機械学習において、正則化手法はモデルの過学習を防ぎ、モデルの一般化能力を向上させるための技術の集合です。これは、モデルの学習プロセスにいくつかの「罰」や「制限」を導入することによって、モデルの複雑さを制約し、モデルが訓練データのすべての詳細(特にノイズ)を「完璧」にフィットしすぎないようにし、新しい、見たことのないデータにより適応できるようにします。
訓練中のみ使用し、予測時には必要ありません。

正則化とは何か?

一言で言えば:正則化は損失関数に「制約 / 罰」を追加することによって、モデルの自由度を積極的に制限し、簡潔一般化が良い規則を学ばせることを強制します。単に訓練セットのノイズを暗記するのではなく。

数学的には次のように書かれます

minθ  L(θ;X,y)  +  λΩ(θ)\min_{\theta}\; \mathcal{L}(\theta;\,X,y)\;+\;\lambda\,\Omega(\theta)
  • L\mathcal{L}:元の経験損失(交差エントロピー、MSE …)

  • Ω\Omega:正則項(大きいほどモデルが「複雑」になる)

  • λ\lambda:正則の強さ;λ=0\lambda=0 は正則なしに退化し、λ\lambda\to\infty はモデルを極端に単純化します

核心的な作用

目標説明
過学習の抑制分散を小さくし、見たことのないサンプルに対するロバスト性を向上させる
数値の安定性重みの爆発や行列の特異性を避ける
解釈性スパース化や構造的制約により、特徴 / サブネットワークがより読みやすくなる
共線性の防止高次元の共線性特徴の下でも一意の解を提供する

L1 正則化(Lasso 回帰)#

✅** 1. L1 正則化とは?**

一言で定義すると:

L1 正則化は損失関数に すべての重みの絶対値の和 を罰則項として追加することです。

その目標は:

重要でない重みを 自動的に 0 にする ことで、モデルを「よりシンプル」にすることです。


2. 数学的形式(簡潔に見ると)

通常の損失関数は:

Loss=モデル誤差(例えば交差エントロピー)\text{Loss} = \text{モデル誤差(例えば交差エントロピー)}

L1 正則化を追加すると、次のようになります:

Losstotal=元の誤差+λwi\text{Loss}_{\text{total}} = \text{元の誤差} + \lambda \sum |w_i|

ここで:

  • wiw_i は各重みパラメータ

  • λ\lambda は罰則の強度を制御するハイパーパラメータ(大きいほど「厳しく」なります)


3. L1 の最大の特徴:一部の重みを 0 にする(スパース化)

これが L1 と L2 の重要な違いです:

したがって、モデルが重要な特徴を自動的に選択し、ゴミの特徴を捨てることを望む場合、L1 正則化は理想的な選択です。


4. 例を挙げると(想像してください)

あなたが住宅価格予測タスクを行っていて、100 の入力特徴があるが、実際には 5 つだけが有用であるとします。

L1 正則化を使用すると、訓練後にモデルはこの 5 つの特徴の重みだけを保持し、残りの 95 は直接 0 になります。
これはモデルが自動的に特徴選択を行ったことになります。


一言でまとめると

L1 正則化 = 重みの絶対値に罰則を与える → 一部のパラメータを 0 に促す → 重要な特徴を自動的に選択する。

L2 正則化(重み減衰)(Ridge 回帰)#

一言で定義

L2 正則化 は損失関数に モデルパラメータの平方の罰則項 を追加し、
重みが大きくなりすぎるのを抑制し、過学習を避ける ことです。


数学的形式

モデルの元の損失関数を次のように設定します:

Loss=L(y^,y)\text{Loss} = L(\hat{y}, y)

L2 正則化を追加すると、次のようになります:

Losstotal=L(y^,y)+λwi2\text{Loss}_{\text{total}} = L(\hat{y}, y) + \lambda \sum w_i^2

ここで:

  • λ\lambda:正則化の強度(ハイパーパラメータ)は一般的に10210310410^{-2}、10^{-3}、10^{-4}を取ります。

  • wi2\sum w_i^2:すべての重みの平方和(これは L2 ノルムです)

image

image


実際の効果(直感的に)

L2 がない場合:

  • モデルは特定の重みを狂ったように大きくする可能性があり、訓練データに対して非常によくフィットしますが、一般化が非常に悪くなります。

L2 正則化がある場合:

  • モデルは「より保守的」になり、パラメータを大きくすることはありません。

  • モデルは入力の変動に対してより安定し(一般化能力が強化されます)。


PyTorch での使用方法は?

L2 正則化 = 重み減衰 なので、PyTorch では最適化器に次のように追加するだけです:

optimizer = torch.optim.SGD(model.parameters(), lr=0.1, weight_decay=1e-4)

この weight_decay パラメータは実際には λ\lambda です!デフォルトでは L2 正則化です。


sklearn での使用方法は?

from sklearn.linear_model import Ridge  # Ridge は L2 を持つ線形回帰です
model = Ridge(alpha=1.0)

一言でまとめると

L2 正則化 = 重みの平方に罰則を与え、すべてのパラメータを圧縮するが保持し、モデルの一般化能力を向上させる。

ドロップアウト(Dropout)#

一言で定義

ドロップアウトは、神経元をランダムにマスクする正則化手法です
これにより、神経ネットワークは訓練時により「頑健」になり、過学習を防ぎます。


背後にある動機

深層神経ネットワークは過学習しやすく、特に次のような場合に:

  • 層数が深い

  • 訓練データが少ない

  • パラメータが多く、モデルが複雑である

理由は:

モデルが「特定の神経元の組み合わせに依存して」訓練データを記憶するようになる → 一般化能力が低下します。

ドロップアウトはこの依存を打破します ——
訓練時に、一部の神経元をランダムにマスク(0 に設定)し、ネットワークが特定の神経元の小さなグループに依存できないように強制し冗長性を持つ必要があるようにします。


操作方法は?

訓練時:

ある隠れ層の出力ベクトル h=(h1,,hn)\mathbf h = (h_1,\dots,h_n) に対して、訓練期間中に次のように適用します:

h~=mph,miBernoulli(p)\tilde{\mathbf h}= \frac{\mathbf m}{p}\odot \mathbf h,\qquad m_i \sim \text{Bernoulli}(p)

保持確率 $p$ はあなたが設定します;通常は 0.5–0.9。

  • m\mathbf m:ランダムマスクで、ii 番目のユニットを「保持」するかどうかを決定します。

  • \odot:要素ごとの乗算です。

  • 1/p1/pinverted dropout で一般的な再スケーリング因子であり、E[h~i]=hi\mathbb E[\tilde h_i] = h_i を保証し、訓練 / 推論時の活性化スケールを一致させます。

したがって、数学的には、これは 乗法的二元ノイズの注入 であり、実際に神経元を物理的に削除するわけではありません。

ランダムマスク(random mask) は、0/1 の値で埋められたテンソルであり、現在の前方 / 逆伝播のラウンドでどのユニットが「一時的にオフ」になり、どのユニットが「正常に動作する」かを決定します。
ドロップアウト(または他のノイズ正則化)では、これはネットワークの最小「スイッチマトリックス」に乗算的ノイズを注入するものです。

要素値

mijBernoulli(p){1(保持)0(ドロップ)m_{ij} \sim \text{Bernoulli}(p)\quad \bigl\{ \begin{array}{l} 1\quad(\text{保持})\\ 0\quad(\text{ドロップ}) \end{array}

テスト時:

ドロップしない、すべてを活性化 しますが、出力はスケーリングしません。


使用位置:
全結合層(Dense Layer / Linear Layer)とその後の活性化関数(ReLU、Sigmoid、Tanh など)の間またはその後に使用します。

  • より一般的には、活性化関数の後に配置されます: Dense -> Activation -> Dropout
  • これは、ドロップアウトの目的が神経元の出力をランダムに「オフ」にすることだからです。活性化関数の出力は神経元の最終出力信号を表し、その出力にドロップアウトを適用することで、神経元のランダムな失活をより直接的にシミュレートできます。
  • 少数の場合、活性化関数の前に配置されることもあります: Dense -> Dropout -> Activation
    これは主流ではありませんが、時には効果を得られることもあるとする研究や実践もあります。その論理は、重みの計算された線形結合結果にドロップアウトを適用し、その後活性化関数を通すというものです。

通常は、1 つ以上の隠れ層(Hidden Layers)に適用されます

  • 深いネットワークの場合、複数の隠れ層の後にドロップアウトを使用することができます。
    すべての隠れ層で使用するかどうか、またどの程度のドロップアウト率(dropout rate/probability)を使用するかは、通常実験によって調整されるハイパーパラメータです。

出力層(Output Layer)でドロップアウトを使用することは一般的に推奨されません。

  • 出力層は最終的な予測結果を生成する役割を担っています。出力層でドロップアウトを使用すると、特に分類タスクにおいて、特定のクラスの予測信号がランダムにドロップされる可能性があり、これは通常望ましくありません。

PyTorch 実装:

import torch.nn as nn

net = nn.Sequential(
    nn.Linear(256, 128),
    nn.ReLU(),
    nn.Dropout(p=0.5),   # ドロップアウト層:訓練時に 50% の神経元をマスク
    nn.Linear(128, 10)
)

ドロップアウトの利点:

利点説明
過学習の抑制ネットワークが特定の特徴に依存できないように強制します
一般化能力の向上各訓練時に異なる「サブネットワーク」を訓練するようにします
簡単に使用できる一行のコードで追加できます

⚠️ 注意事項:

  • ドロップアウトは訓練段階でのみ機能し、テスト段階ではドロップアウトをオフにする必要があります

  • モデルがすでに小さいか、データ量が十分な場合、ドロップアウトは逆に性能を損なうことがあります(アンダーフィッティング)。


一言でまとめると

ドロップアウトは「訓練時にランダムにいくつかをドロップし、テスト時にはすべてをオンにする」戦略であり、モデルの頑健性を強化し、過学習を防ぎます。

アーリーストッピング(Early Stopping)#

一言で定義

アーリーストッピングは、検証セットのパフォーマンスを監視し、モデルが過学習を始める前に訓練を停止する方法です。


🧠 なぜアーリーストッピングが必要なのか?

モデルを訓練する際に、次のような現象をよく目にします:

エポック訓練セットの正確性検証セットの正確性
160%58%
1095%88% ✅
3099% ✅70% ❌

訓練セットはどんどん良くなりますが、検証セットはどんどん悪くなります。これは次のことを示しています:

モデルが「訓練データを暗記している」 → 過学習が始まった

この時点で訓練を続けることは時間の無駄であり、モデルを破壊する可能性すらあります。


✅** アーリーストッピングの核心的な考え方 **

非常にシンプルです:

検証セットのパフォーマンスを観察し、それが下降し始めたらすぐに訓練を停止し、最良の効果を持つモデルを保持します

こうすることで:

  • モデルは過学習しません

  • 訓練速度が速くなります

  • 一般的に複雑な正則項は必要ありません

👉 したがって、アーリーストッピングは訓練レベルの正則化手法であり、構造レベルのものではありません。


一言でまとめると

アーリーストッピングは最も素朴ですが非常に効果的な正則化戦略です:検証セットがもはや良くならないとき、すぐに停止します。

13、重みの初期化#

「信号の爆発や消失」を避けるために、私たちは望みます

ネットワーク内の各層の活性化(前方)と勾配(逆方)の平均 = 0、分散 = 定数

具体的には、各層の出力 hith_i^t と勾配 hit\frac{\partial \ell}{\partial h_i^t} を確率変数として扱います:

方向平均分散
前方E[hit]=0\mathbb E[h_i^t]=0Var[hit]=a\mathrm{Var}[h_i^t]=a
逆方E ⁣[hit]=0\mathbb E\!\left[\dfrac{\partial \ell}{\partial h_i^t}\right]=0Var ⁣[hit]=b\mathrm{Var}\!\left[\dfrac{\partial \ell}{\partial h_i^t}\right]=b

ここで a,ba,b はあなたが設定する定数(一般的には 1 または 2)であり、すべての層 tt とすべてのチャネル ii に対して同じです

一層の「分散保存」条件を導出します(全結合層の例)

仮定

hit=j=1ninWijtxjt1,xjt1 (上層の活性化)h_i^t=\sum_{j=1}^{n_{\text{in}}} W_{ij}^t\,x_j^{t-1},\qquad x_j^{t-1}~\text{(上層の活性化)}

一般的な仮定

  1. E[xjt1]=0,  Var[xjt1]=a\mathbb E[x_j^{t-1}]=0,\; \mathrm{Var}[x_j^{t-1}]=a

  2. E[Wijt]=0,  Var[Wijt]=σw2\mathbb E[W_{ij}^t]=0,\; \mathrm{Var}[W_{ij}^t]=\sigma_w^2

  3. xxWW は独立であり、要素間は近似的に独立です。

したがって

Var[hit]=ninσw2a\mathrm{Var}[h_i^t] = n_{\text{in}}\,\sigma_w^2\,a

出力の分散が aa に等しいことを要求する

ninσw2a=a    σw2=1nin.n_{\text{in}}\,\sigma_w^2\,a = a \;\Longrightarrow\; \sigma_w^2 = \frac{1}{n_{\text{in}}}.

逆方も同様に(勾配は WW^\top を通じて伝播します)、次の条件を要求します:

σw2=1nout.\sigma_w^2 = \frac{1}{n_{\text{out}}}.

両方を考慮して → 折衷案

σw2=2nin+nout\sigma_w^2 = \frac{2}{n_{\text{in}}+n_{\text{out}}}

これが Glorot/Xavier 初期化 です。ランダム初期化

Xavier 初期化(Glorot 初期化)#

一言で言えば:これはネットワークの重みの初期値を設定する戦略であり、前方の活性化逆方の勾配 が各層で分散が近くなるようにし、深層ネットワーク内の勾配消失 / 爆発の問題を緩和します。提案者は Xavier Glorot と Yoshua Bengio(2010)です。

具体的な公式

サンプリング分布推奨分散実際のサンプリング範囲 / 標準偏差
一様 U (−r, r)σw2=2nin+nout\sigma_w^2 = \dfrac{2}{n_\text{in}+n_\text{out}}r=6nin+noutr = \sqrt{\dfrac{6}{n_\text{in}+n_\text{out}}}
正規 𝒩(0, σ²)同上σ=2nin+nout\sigma = \sqrt{\dfrac{2}{n_\text{in}+n_\text{out}}}
  • n_in: 本層の各ニューロンが受け取る入力次元

  • n_out: 本層のニューロンの数

畳み込み層に対して
nin=kernelh×kernelw×in_channelsn_\text{in}= \text{kernel}_h \times \text{kernel}_w \times \text{in\_channels}


He 初期化との違い

名称推奨分散適用活性化
Xavier/Glorot2nin+nout\dfrac{2}{n_\text{in}+n_\text{out}}シグモイド、tanh、soft-sign などの両側活性化
He/Kaiming2nin\dfrac{2}{n_\text{in}}ReLU、Leaky-ReLU、GELU(単側活性化は 1/2 のエネルギーを失うため、より大きな分散が必要)

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。