# 言語モデルの学習：次トークン予測・パープレキシティ・AdamW・LoRA

> 自己回帰言語モデルの損失が列の対数尤度であること、パープレキシティが交差エントロピーの指数であることを示し、Adam のバイアス補正と更新量の上界、AdamW と L2 正則化の違い、LoRA が表せる更新が階数 r 以下の行列全体であることを証明する。
> https://rikai.mugen-giken.com/computer-science/llm-architecture/training-language-models

## 0. この記事の要点

文章を途中まで読んで、次に来る言葉を予想する遊びを思い浮かべてください。言語モデルは、この予想を確率で答える仕組みです。この記事では、その仕組みの中にある数値（重み）を、大量の文章からどう決めるかを扱います。読み終えると、予想の外れ具合を表す損失とパープレキシティの読み方、学習で標準的に使われる Adam と AdamW の更新の性質、重みの一部だけを小さな部品で調整する LoRA が何を表せるかを、証明つきで説明できるようになります。

- 言語モデルは「これまでのトークン列から次のトークンの確率分布を出す関数」です。その積 $\prod_t p_\theta(x_t \mid x_{<t})$ は列全体の上の確率分布になり、逆にどんな同時分布もこの形に分解できます（<Ref to="thm-autoregressive-distribution" />）。したがって次トークン予測の損失を最小にすることは、コーパスの尤度を最大にすること（[最尤推定](/computer-science/math-for-ml/why-math-for-ml#def-mle)）と同じです（<Ref to="prop-mle-cross-entropy-lm" />）。
- パープレキシティは平均交差エントロピーの指数で、正解に割り当てた確率の幾何平均の逆数です。$1$ 以上で、一様に当てずっぽうなら語彙の大きさ $|V|$ に一致し、対数の底に依りません（<Ref to="thm-perplexity" />）。データの分布のエントロピーが下限を決めます（<Ref to="prop-cross-entropy-lower-bound" />）。
- Adam の 1 次モーメント（勾配の移動平均）は過去の勾配の重みつき和で、重みの合計が $1 - \beta_1^t$ しかないので、それで割ると不偏になります（<Ref to="prop-adam-bias-correction" />）。更新量 $|m_t| / \sqrt{v_t}$ は勾配の大きさに依らない定数で抑えられます（<Ref to="prop-adam-step-bound" />）。この定数は $1$ より大きくなりえて、$(\beta_1, \beta_2) = (0.9, 0.999)$ では約 $7.27$ です。
- L2 正則化と重み減衰は、素の SGD では同じ更新ですが、Adam では違う更新になります（<Ref to="prop-adamw-decoupling" />）。重み減衰を勾配の外で掛けるのが AdamW です。
- LoRA は重みの更新を $\Delta W = BA$ の形に限る微調整です。パラメータ数は $r(d + k)$ で、表せる更新は「[階数](/mathematics/linear-algebra/matrices-and-linear-systems#def-rank) $r$ 以下の行列」全体にちょうど一致します（<Ref to="thm-lora-parameters" />）。実際の更新が低階数で足りるかどうかは定理ではなく、経験的な事柄です。

<Aside type="tip" title="この記事で使う事前知識">

- **勾配降下法**: 損失が最も速く減る向きに、重みを少しずつ動かして損失を下げていく方法。→ [勾配降下法](/computer-science/math-for-ml/gradient-descent#def-gradient-descent)
- **誤差逆伝播法**: 損失の勾配を、出力側から入力側へ向かって順に計算する方法。→ [誤差逆伝播法](/computer-science/math-for-ml/backpropagation)
- **最尤推定**: データが起こる確率（尤度）が最大になるようにパラメータを選ぶ方法。→ [最尤推定](/computer-science/math-for-ml/why-math-for-ml#def-mle)
- **期待値**: 確率で重みをつけた値の平均。→ [期待値](/mathematics/probability/random-variables#def-expectation)
- **階数**: 行列の列が張る空間の次元。→ [階数](/mathematics/linear-algebra/matrices-and-linear-systems#def-rank)

</Aside>

## 1. 動機：重みをどう決めるか

[Transformer ブロック](/computer-science/llm-architecture/transformer-block)までで、トークン列を受け取って各位置のロジット（語彙の大きさ $|V|$ の実数ベクトル）を返す関数が組み上がりました。この関数は数多くの重みを持ちますが、その値はまだ決まっていません。この章の問いは、その重みを何を基準に、どういう手続きで決めるかです。

基準は 1 つだけです。**文章の続きを当てる**こと、すなわちコーパスに現れた各位置で、実際に次に来たトークンに高い確率を割り当てることです。正解のラベルを人が付ける必要はありません。文章そのものが、入力（これまでの列）と正解（次のトークン）の組を大量に含んでいます。この考え方は、ニューラルネットワークによる言語モデルの出発点となった Bengio らの研究（2003）ですでに採られています。

この基準を採ると、次の問いが順に出てきます。

1. 「次のトークンの確率」を掛け合わせたものは、本当に文章全体の確率になっているのか。
2. 損失の値をどう読むのか。損失が $2.3$ というのは良いのか悪いのか。
3. 損失を下げる手続きとして、なぜ素の勾配降下法ではなく Adam や AdamW が使われるのか。その更新式について何が証明できるのか。
4. 学習済みの重みを別の用途に合わせ直すとき、重みを全部動かさずに済ませる方法（LoRA）は、何を表せて何を表せないのか。

勾配降下法そのものの性質（降下補題、凸の場合の収束、ミニバッチ勾配の不偏性）は[勾配降下法](/computer-science/math-for-ml/gradient-descent)で、勾配の計算方法は[誤差逆伝播法](/computer-science/math-for-ml/backpropagation)で扱いました。ここでは繰り返さず、言語モデルに固有の損失・指標・最適化手法・低階数の微調整を、証明できる命題として切り出します。

## 2. 準備：記号

[語彙](/computer-science/llm-architecture/tokenization-bpe#def-alphabet-vocab)を有限集合 $V$ とし、その大きさを $|V|$ と書きます。トークン列を $x = (x_1, \ldots, x_n) \in V^n$、その接頭辞を $x_{<t} = (x_1, \ldots, x_{t-1})$、$x_{\le t} = (x_1, \ldots, x_t)$ と書きます。$x_{<1}$ は空列です。実際のモデルでは列の先頭に開始を表す[特殊トークン](/computer-science/llm-architecture/tokenization-bpe#def-utf8)を置くので、$x_1$ の予測にも入力があります。

モデルの重みをまとめて $\theta \in \mathbb{R}^P$ と書きます。前章のモデルは、接頭辞 $x_{<t}$ に対してロジット $\boldsymbol{z}_t(\theta) \in \mathbb{R}^{|V|}$ を返し、softmax で確率に直します。

$$
p_\theta(v \mid x_{<t}) = \mathrm{softmax}(\boldsymbol{z}_t)_v = \frac{e^{z_{t,v}}}{\sum_{u \in V} e^{z_{t,u}}} \qquad (v \in V).
$$

softmax の値はすべて正で、和が $1$ です（<Ref to="computer-science/llm-architecture/self-attention#prop-softmax-basic" />）。対数は自然対数 $\log$ を既定とし、底を $2$ にするときは $\log_2$ と明記します。行列のフロベニウスノルムを $\|\cdot\|_F$、ベクトルのユークリッドノルムを $\|\cdot\|$ と書きます。

## 3. 自己回帰言語モデルと次トークン予測の損失

<Definition id="def-autoregressive-lm" title="自己回帰言語モデル">
各 $t = 1, \ldots, n$ と各接頭辞 $x_{<t} \in V^{t-1}$ に対して、$V$ 上の確率分布 $p_\theta(\cdot \mid x_{<t})$（各 $v \in V$ で $p_\theta(v \mid x_{<t}) \ge 0$、$\sum_{v \in V} p_\theta(v \mid x_{<t}) = 1$）を定める規則を、長さ $n$ の**自己回帰言語モデル**といいます。これに対して列 $x \in V^n$ の確率を

$$
p_\theta(x) = \prod_{t=1}^{n} p_\theta(x_t \mid x_{<t})
$$

で定めます。
</Definition>

定義の時点では $p_\theta(\cdot \mid x_{<t})$ という記号は「接頭辞ごとに与えた分布」という意味しかなく、何かの同時分布の条件付き確率であるとは言っていません。次の定理が、この記法を正当化します。

<Theorem id="thm-autoregressive-distribution" title="自己回帰の積は列の上の確率分布であり、任意の同時分布はこの形に書ける">
$V$ を有限集合、$n \ge 1$ とします。

1. <Ref to="def-autoregressive-lm" /> の $p_\theta(x)$ は $V^n$ 上の確率分布です。すなわち、すべての $x$ で $p_\theta(x) \ge 0$ で、$\sum_{x \in V^n} p_\theta(x) = 1$ です。さらに、この分布に従う確率変数の列 $(X_1, \ldots, X_n)$ について、$P(X_{<t} = x_{<t}) > 0$ のとき $P(X_t = v \mid X_{<t} = x_{<t}) = p_\theta(v \mid x_{<t})$ です。
2. 逆に、$V^n$ 上の任意の確率分布 $P$ に対して、ある自己回帰言語モデル $q$ があって、すべての $x \in V^n$ で $P(x) = \prod_{t=1}^{n} q(x_t \mid x_{<t})$ が成り立ちます。
</Theorem>

証明の方針です。1 は、最後の成分について和を取るたびに因子 $1$ が出ることを使う帰納法です。2 は、同時分布から「接頭辞の確率の比」として条件付き分布を作り、それを掛け合わせると、隣り合う分子と分母が打ち消し合って元の確率に戻る、という計算です。

<Proof of="thm-autoregressive-distribution">
**1.** 非負性は、非負の数の積なので成り立ちます。和が $1$ であることを $n$ についての帰納法（<Ref to="mathematics/foundations/proof-techniques#thm-induction" />）で示します。$n = 1$ のとき $\sum_{x_1} p_\theta(x_1 \mid x_{<1}) = 1$ は定義そのものです。$n - 1$ まで成り立つとします。長さ $n$ の列についての和を、最後の成分についての和と残りについての和に分けると

$$
\sum_{x \in V^n} \prod_{t=1}^{n} p_\theta(x_t \mid x_{<t})
= \sum_{x_{<n} \in V^{n-1}} \Bigl(\prod_{t=1}^{n-1} p_\theta(x_t \mid x_{<t})\Bigr) \sum_{x_n \in V} p_\theta(x_n \mid x_{<n}).
$$

内側の和は、$p_\theta(\cdot \mid x_{<n})$ が確率分布なので $1$ です。残った和は長さ $n - 1$ の自己回帰言語モデルの確率の総和で、帰納法の仮定により $1$ です。

同じ計算を $t$ 番目より後ろの成分についてだけ行うと、周辺分布が $P(X_{\le t} = x_{\le t}) = \prod_{s=1}^{t} p_\theta(x_s \mid x_{<s})$ であることが分かります（$x_{t+1}, \ldots, x_n$ についての和を後ろから順に取ると、そのたびに因子 $1$ が出ます）。したがって $P(X_{<t} = x_{<t}) > 0$ のとき、条件付き確率の定義（<Ref to="mathematics/hs-probability/finite-probability#def-conditional-hs" />）から

$$
P(X_t = v \mid X_{<t} = x_{<t}) = \frac{P(X_{<t} = x_{<t},\ X_t = v)}{P(X_{<t} = x_{<t})} = \frac{\prod_{s<t} p_\theta(x_s \mid x_{<s}) \cdot p_\theta(v \mid x_{<t})}{\prod_{s<t} p_\theta(x_s \mid x_{<s})} = p_\theta(v \mid x_{<t})
$$

です。

**2.** $P$ に従う確率変数の列を $(X_1, \ldots, X_n)$ とし、接頭辞の確率を $\pi_t(x_{\le t}) = P(X_{\le t} = x_{\le t})$ と書きます（$\pi_0 = 1$ と約束します）。$q$ を

$$
q(v \mid x_{<t}) =
\begin{cases}
\pi_t(x_{<t}, v) / \pi_{t-1}(x_{<t}) & (\pi_{t-1}(x_{<t}) > 0) \\
1 / |V| & (\pi_{t-1}(x_{<t}) = 0)
\end{cases}
$$

で定めます。$\sum_{v} \pi_t(x_{<t}, v) = \pi_{t-1}(x_{<t})$（事象 $\{X_{<t} = x_{<t}\}$ を $X_t$ の値で分割したもの）なので、どちらの場合も $q(\cdot \mid x_{<t})$ は $V$ 上の確率分布です。

$x \in V^n$ を取ります。すべての $t$ で $\pi_{t-1}(x_{<t}) > 0$ なら、乗法定理（<Ref to="mathematics/hs-probability/finite-probability#thm-bayes-hs" /> の 1）を繰り返し使った形として

$$
\prod_{t=1}^{n} q(x_t \mid x_{<t}) = \prod_{t=1}^{n} \frac{\pi_t(x_{\le t})}{\pi_{t-1}(x_{<t})} = \frac{\pi_n(x)}{\pi_0} = P(x)
$$

が成り立ちます（隣り合う分子と分母が打ち消し合います）。そうでないとき、$\pi_{t}(x_{\le t}) = 0$ となる最小の $t \ge 1$ を取ります。$\pi_{t-1}(x_{<t}) > 0$ なので $q(x_t \mid x_{<t}) = 0 / \pi_{t-1}(x_{<t}) = 0$ で、積は $0$ です。一方 $\{X = x\} \subset \{X_{\le t} = x_{\le t}\}$ なので $P(x) \le \pi_t(x_{\le t}) = 0$ で、やはり一致します。
</Proof>

この定理の 2 は、自己回帰という形に分解しても表現力を失わないことを言っています。制約になるのは分解の形ではなく、条件付き分布を「重み $\theta$ を持つ決まった形の関数」で表すところです。

<Remark id="rem-variable-length">
実際の文章は長さが決まっていません。終端を表す特殊トークンを語彙に入れ、それが出たら列が終わると約束すれば、長さの違う列の全体の上の分布も同じ積の形で定義できます。この章の命題は、列の長さ $n$ を固定した形で述べます。
</Remark>

<Definition id="def-next-token-loss" title="次トークン予測の損失と教師強制">
コーパスを列の有限の集まり $x^{(1)}, \ldots, x^{(M)}$（$x^{(m)} \in V^{n_m}$）とし、総トークン数を $T = \sum_{m} n_m$ とします。

$$
\mathcal{L}(\theta) = -\frac{1}{T} \sum_{m=1}^{M} \sum_{t=1}^{n_m} \log p_\theta\bigl(x^{(m)}_t \mid x^{(m)}_{<t}\bigr)
$$

を**次トークン予測の損失**（平均負対数尤度）といいます。各位置の条件には、モデル自身が出力したトークンではなく、コーパスにある正しい接頭辞 $x^{(m)}_{<t}$ を入れます。これを**教師強制**といいます。
</Definition>

[因果マスク](/computer-science/llm-architecture/self-attention#def-attention)つきの Transformer では、長さ $n$ の列を 1 回順伝播するだけで、$n$ 個の位置すべての $p_\theta(\cdot \mid x_{<t})$ が、接頭辞だけを入力したときと同じ値で得られます（<Ref to="computer-science/llm-architecture/self-attention#cor-parallel-next-token" />）。教師強制の損失を 1 回の順伝播と 1 回の逆伝播（<Ref to="computer-science/math-for-ml/backpropagation#thm-reverse-mode" />）で計算できるのは、このためです。

<Proposition id="prop-mle-cross-entropy-lm" title="次トークン予測の損失の最小化は最尤推定である">
<Ref to="def-next-token-loss" /> の設定で、すべての $\theta$ とすべての $m, t$ について $p_\theta(x^{(m)}_t \mid x^{(m)}_{<t}) > 0$ とします（softmax の出力ならつねに成り立ちます）。コーパスの尤度を $\mathrm{Lik}(\theta) = \prod_{m=1}^{M} p_\theta(x^{(m)})$ とします。

1. $\mathcal{L}(\theta) = -\dfrac{1}{T} \log \mathrm{Lik}(\theta)$ です。したがって $\mathcal{L}$ の最小点の集合と $\mathrm{Lik}$ の最大点の集合は一致します（どちらも空集合である場合を含みます）。
2. コーパスに現れた接頭辞 $c$ ごとに、その出現回数を $N_c$、直後のトークンが $v$ であった回数を $N_{c,v}$ とし、経験分布を $\hat{p}(v \mid c) = N_{c,v} / N_c$ とします。このとき
$$
\mathcal{L}(\theta) = \sum_{c} \frac{N_c}{T}\, H\bigl(\hat{p}(\cdot \mid c),\ p_\theta(\cdot \mid c)\bigr)
$$
です。ここで $H(p, q) = -\sum_v p_v \log q_v$ は交差エントロピー（<Ref to="computer-science/ai-era/relearning-mathematics#def-cross-entropy" />）で、和はコーパスに現れた接頭辞の全体にわたります。
3. 1 つの位置の損失 $\ell = -\log \mathrm{softmax}(\boldsymbol{z})_y$ のロジットについての勾配は $\nabla_{\boldsymbol{z}} \ell = \mathrm{softmax}(\boldsymbol{z}) - \boldsymbol{e}_y$ です（$\boldsymbol{e}_y$ は正解 $y$ の one-hot ベクトル）。
</Proposition>

<Proof of="prop-mle-cross-entropy-lm">
**1.** <Ref to="def-autoregressive-lm" /> から $\log p_\theta(x^{(m)}) = \sum_{t=1}^{n_m} \log p_\theta(x^{(m)}_t \mid x^{(m)}_{<t})$ です（仮定により各因子は正なので、対数が定義されます）。$m$ について足すと $\log \mathrm{Lik}(\theta) = \sum_m \sum_t \log p_\theta(x^{(m)}_t \mid x^{(m)}_{<t}) = -T \mathcal{L}(\theta)$ です。$T > 0$ で、$\log$ は狭義単調増加なので、$\mathcal{L}(\theta) \le \mathcal{L}(\theta')$ と $\mathrm{Lik}(\theta) \ge \mathrm{Lik}(\theta')$ は同値です。したがって最小点と最大点は一致します。これは 2 値の場合の <Ref to="computer-science/math-for-ml/logistic-regression#prop-mle-ce" /> と同じ議論で、違いはクラスの数が $|V|$ であることと、1 つの列が $n_m$ 個の予測を含むことだけです。

**2.** $\mathcal{L}$ の和の $T$ 個の項を、接頭辞 $c$ と次のトークン $v$ の組ごとにまとめます。組 $(c, v)$ に対応する項はどれも $-\log p_\theta(v \mid c)$ で、$N_{c,v}$ 個あります。したがって

$$
\mathcal{L}(\theta) = -\frac{1}{T} \sum_{c} \sum_{v \in V} N_{c,v} \log p_\theta(v \mid c)
= \sum_{c} \frac{N_c}{T} \Bigl(-\sum_{v \in V} \frac{N_{c,v}}{N_c} \log p_\theta(v \mid c)\Bigr)
$$

で、括弧の中が $H(\hat{p}(\cdot \mid c), p_\theta(\cdot \mid c))$ です。

**3.** $\ell$ は、正解の分布を $\boldsymbol{y} = \boldsymbol{e}_y$ としたときの交差エントロピー $-\sum_i y_i \log \mathrm{softmax}(\boldsymbol{z})_i$ です。<Ref to="computer-science/math-for-ml/backpropagation#prop-softmax-ce" /> により、その勾配は $\mathrm{softmax}(\boldsymbol{z}) - \boldsymbol{y}$ です。
</Proof>

2 の式は、損失が「接頭辞ごとに、実際に続いたトークンの頻度分布とモデルの分布の交差エントロピー」の重みつき平均であることを示しています。同じ接頭辞のあとに複数の続き方があるかぎり、損失は $0$ になりません。その下限は次の節で求めます。

3 の式は、逆伝播の出発点です。出力層に入ってくる誤差信号は「モデルの確率から正解の位置の $1$ を引いたもの」で、正解に確率 $1$ を与えたときにだけ $\boldsymbol{0}$ になります。

## 4. パープレキシティ

損失の値は対数の単位（ナット）で測った量で、そのままでは大きさを掴みにくいものです。指数を取って「選択肢がいくつあるのと同じ程度に迷っているか」に直したものがパープレキシティです。

<Definition id="def-perplexity" title="パープレキシティ">
列 $x \in V^n$ に対して、モデルが各位置の正解に割り当てた確率を $q_t = p_\theta(x_t \mid x_{<t})$ とし、すべて正とします。平均負対数尤度を $\ell = -\frac{1}{n} \sum_{t=1}^{n} \log q_t$ とするとき、

$$
\mathrm{PPL} = \exp(\ell)
$$

を、このモデルの $x$ に対する**パープレキシティ**といいます。
</Definition>

<Theorem id="thm-perplexity" title="パープレキシティの基本性質">
<Ref to="def-perplexity" /> の記号のもとで、次が成り立ちます。

1. $\mathrm{PPL} = \Bigl(\prod_{t=1}^{n} q_t\Bigr)^{-1/n} = p_\theta(x)^{-1/n}$ です。すなわち、正解に割り当てた確率の幾何平均の逆数です。
2. $\mathrm{PPL} \ge 1$ で、等号はすべての $t$ で $q_t = 1$ のとき、かつそのときに限ります。
3. すべての $t$ で $q_t = 1 / |V|$（一様分布のモデル）なら $\mathrm{PPL} = |V|$ です。
4. $b > 1$ を任意の底とし、$\ell_b = -\frac{1}{n} \sum_t \log_b q_t$ とすると、$b^{\ell_b} = \mathrm{PPL}$ です。とくに、ビットで測った平均負対数尤度 $\ell_2$ とナットで測った $\ell$ は $\ell = \ell_2 \log 2$ の関係にあり、$2^{\ell_2} = e^{\ell}$ です。
5. $\mathrm{PPL} \le \dfrac{1}{n} \sum_{t=1}^{n} \dfrac{1}{q_t}$ です。
</Theorem>

<Proof of="thm-perplexity">
**1.** 指数関数と対数の関係から

$$
\exp\Bigl(-\frac{1}{n} \sum_{t=1}^{n} \log q_t\Bigr) = \exp\Bigl(\log \Bigl(\prod_{t=1}^{n} q_t\Bigr)^{-1/n}\Bigr) = \Bigl(\prod_{t=1}^{n} q_t\Bigr)^{-1/n}
$$

で、$\prod_t q_t = p_\theta(x)$ は <Ref to="def-autoregressive-lm" /> です。

**2.** $0 < q_t \le 1$ なので $-\log q_t \ge 0$ で、$\ell \ge 0$、したがって $\mathrm{PPL} = e^{\ell} \ge e^0 = 1$ です。等号は $\ell = 0$ のときで、非負の項の和が $0$ になるのは各項が $0$、すなわちすべての $t$ で $q_t = 1$ のときに限ります。

**3.** $\ell = -\frac{1}{n} \cdot n \log (1 / |V|) = \log |V|$ なので $\mathrm{PPL} = e^{\log |V|} = |V|$ です。

**4.** 底の変換 $\log_b q = \log q / \log b$ から $\ell_b = \ell / \log b$ です。したがって $b^{\ell_b} = \exp(\ell_b \log b) = \exp(\ell) = \mathrm{PPL}$ です。$b = 2$ とすれば後半です。

**5.** $f(u) = e^{u}$ は凸関数です。$u_t = -\log q_t$、$\lambda_t = 1/n$ として Jensen の不等式（<Ref to="mathematics/hs-algebra/identities-and-inequalities#thm-jensen-finite" />）を使うと

$$
\mathrm{PPL} = \exp\Bigl(\sum_{t=1}^{n} \frac{1}{n} u_t\Bigr) \le \sum_{t=1}^{n} \frac{1}{n} e^{u_t} = \frac{1}{n} \sum_{t=1}^{n} \frac{1}{q_t}
$$

です。
</Proof>

2 と 3 が、パープレキシティの目盛りを与えます。$1$ が「まったく迷っていない」、$|V|$ が「語彙全体から一様に選ぶのと同じ」です。その間の値 $k$ は、「毎回 $k$ 個の選択肢から一様に選ぶモデルと同じ損失」と読めます。softmax の出力はつねに $1$ 未満なので、ニューラル言語モデルのパープレキシティは $1$ には到達せず、$1$ は下限です。

<Example id="ex-perplexity-hand" title="語彙 4・長さ 5 の列のパープレキシティ">
$|V| = 4$ とし、あるモデルが長さ $5$ の列の各位置の正解に割り当てた確率が

$$
(q_1, \ldots, q_5) = \Bigl(\tfrac{1}{2},\ \tfrac{1}{4},\ \tfrac{1}{2},\ \tfrac{1}{8},\ \tfrac{1}{4}\Bigr)
$$

だったとします。底 $2$ の対数は $-\log_2 q_t = 1, 2, 1, 3, 2$ で、和は $9$、平均は $\ell_2 = 9 / 5 = 1.8$ ビットです。<Ref to="thm-perplexity" /> の 4 により

$$
\mathrm{PPL} = 2^{1.8} \approx 3.482
$$

です。積で確かめると $\prod_t q_t = 2^{-9} = 1/512$ で、$512^{1/5} \approx 3.482$ と一致します。ナットで測った損失は $\ell = 1.8 \log 2 \approx 1.248$ で、$e^{1.248} \approx 3.482$ です。

一様分布のモデルのパープレキシティは $4$ なので、このモデルは当てずっぽうよりは良いものの、差は大きくありません。4 番目の位置の $q_4 = 1/8$ は一様分布の $1/4$ より小さく、全体を押し上げています。<Ref to="thm-perplexity" /> の 5 の右辺は $(2 + 4 + 2 + 8 + 4) / 5 = 4$ で、確かに $3.482 \le 4$ です。
</Example>

では、損失とパープレキシティはどこまで下げられるのでしょうか。データが確率的に生成されているなら、下限はモデルではなくデータの側で決まります。

<Proposition id="prop-cross-entropy-lower-bound" title="期待損失の下限はデータのエントロピー">
$P$ を $V^n$ 上の確率分布（データの分布）、$Q$ を $V^n$ 上の確率分布で、すべての $x$ で $Q(x) > 0$ とします。$X$ が $P$ に従うとき、1 トークンあたりの損失 $\ell(X) = -\frac{1}{n} \log Q(X)$ とパープレキシティ $\mathrm{PPL}(X) = e^{\ell(X)}$ について

$$
\mathbb{E}[\ell(X)] = \frac{1}{n} H(P, Q) \ \ge\ \frac{1}{n} H(P),
\qquad
\mathbb{E}[\mathrm{PPL}(X)] \ \ge\ \exp\bigl(\mathbb{E}[\ell(X)]\bigr) \ \ge\ \exp\Bigl(\frac{H(P)}{n}\Bigr)
$$

が成り立ちます。ここで $H(P) = -\sum_x P(x) \log P(x)$ は $P$ のエントロピーです。最初の不等式の等号は $Q = P$ のとき、かつそのときに限ります。
</Proposition>

<Proof of="prop-cross-entropy-lower-bound">
期待値の定義から $\mathbb{E}[\ell(X)] = -\frac{1}{n} \sum_x P(x) \log Q(x) = \frac{1}{n} H(P, Q)$ です。ギブスの不等式（<Ref to="computer-science/ai-era/relearning-mathematics#prop-gibbs" />）により $H(P, Q) \ge H(P)$ で、等号は $P(x) > 0$ であるすべての $x$ で $Q(x) = P(x)$ のときに限ります。このとき $\sum_{x : P(x) > 0} Q(x) = \sum_{x : P(x) > 0} P(x) = 1$ なので、$P(x) = 0$ である $x$ での $Q(x)$ の和は $0$ になります。$Q(x) > 0$ を仮定しているので、そのような $x$ は存在せず、$Q = P$ です。逆に $Q = P$ なら等号です。

2 番目の主張は、凸関数 $e^{u}$ に Jensen の不等式（<Ref to="mathematics/hs-algebra/identities-and-inequalities#thm-jensen-finite" />）を、点 $u_x = \ell(x)$ と重み $\lambda_x = P(x)$ で使うと $\exp(\sum_x P(x) \ell(x)) \le \sum_x P(x) e^{\ell(x)}$、すなわち $\exp(\mathbb{E}[\ell]) \le \mathbb{E}[\mathrm{PPL}]$ です。最後の不等式は、最初の不等式と指数関数の単調性から従います。
</Proof>

<Remark id="rem-entropy-unknown">
この命題は下限が存在することを言うだけで、自然言語の $H(P)$ の値を教えてはくれません。データの分布 $P$ そのものが未知だからです。測れるのは交差エントロピー $H(P, Q)$ の標本平均（検証用の文章での損失）で、それは $H(P)$ の上からの評価になります。また、異なる語彙（トークン化）のモデルのパープレキシティは、1 トークンが表す文字数が違うので、そのままでは比べられません。比べるときは 1 文字あたり・1 バイトあたりのビット数に直します（[トークン化](/computer-science/llm-architecture/tokenization-bpe)の圧縮率を参照）。
</Remark>

## 5. Adam と AdamW

損失 $\mathcal{L}(\theta)$ は $T$ 個の項の平均なので、その一部（ミニバッチ）だけで勾配を見積もる確率的勾配降下法（<Ref to="computer-science/math-for-ml/gradient-descent#def-sgd" />）が使えます。ミニバッチ勾配は真の勾配の不偏推定量です（<Ref to="computer-science/math-for-ml/gradient-descent#prop-minibatch" />）。Transformer の学習では、これをそのまま使う代わりに、勾配の移動平均と 2 乗の移動平均で成分ごとに歩幅を調整する Adam（Kingma–Ba, 2015）が標準的に使われています。Vaswani らの原論文も Adam を使っています。

<Definition id="def-adam" title="Adam">
$0 \le \beta_1 < 1$、$0 \le \beta_2 < 1$、学習率 $\eta > 0$、$\varepsilon \ge 0$ とします。時刻 $t = 1, 2, \ldots$ の（確率的）勾配を $\boldsymbol{g}_t$ とし、$\boldsymbol{m}_0 = \boldsymbol{v}_0 = \boldsymbol{0}$ から

$$
\begin{aligned}
\boldsymbol{m}_t &= \beta_1 \boldsymbol{m}_{t-1} + (1 - \beta_1)\, \boldsymbol{g}_t, &
\boldsymbol{v}_t &= \beta_2 \boldsymbol{v}_{t-1} + (1 - \beta_2)\, \boldsymbol{g}_t \odot \boldsymbol{g}_t, \\
\hat{\boldsymbol{m}}_t &= \frac{\boldsymbol{m}_t}{1 - \beta_1^t}, &
\hat{\boldsymbol{v}}_t &= \frac{\boldsymbol{v}_t}{1 - \beta_2^t}, \\
\theta_t &= \theta_{t-1} - \eta\, \frac{\hat{\boldsymbol{m}}_t}{\sqrt{\hat{\boldsymbol{v}}_t} + \varepsilon}
\end{aligned}
$$

と更新する方法を **Adam** といいます。$\odot$ は成分ごとの積で、平方根と割り算も成分ごとに行います。$\boldsymbol{m}_t$ を 1 次モーメントの推定、$\boldsymbol{v}_t$ を 2 次モーメントの推定、$1 - \beta^t$ で割る操作を**バイアス補正**といいます。
</Definition>

更新は成分ごとに独立なので、以下の命題は 1 つの成分（スカラー $g_t, m_t, v_t$）について述べます。

<Proposition id="prop-adam-bias-correction" title="移動平均の閉じた形とバイアス補正">
$0 \le \beta < 1$、$a_0 = 0$、$a_t = \beta a_{t-1} + (1 - \beta) c_t$（$t \ge 1$）とします。

1. $a_t = (1 - \beta) \sum_{i=1}^{t} \beta^{t-i} c_i$ です。重みの和は $(1 - \beta) \sum_{i=1}^{t} \beta^{t-i} = 1 - \beta^t$ です。
2. $c_1, \ldots, c_t$ が確率変数で、期待値 $\mathbb{E}[c_i] = \mu$ が $i$ に依らないなら、$\mathbb{E}[a_t] = (1 - \beta^t)\mu$ で、$\mathbb{E}[a_t / (1 - \beta^t)] = \mu$ です。

$c_t = g_t$、$\beta = \beta_1$ とすれば $m_t$、$c_t = g_t^2$、$\beta = \beta_2$ とすれば $v_t$ についての主張になります。
</Proposition>

<Proof of="prop-adam-bias-correction">
**1.** $t$ についての帰納法で示します。$t = 1$ のとき $a_1 = (1 - \beta) c_1$ で、右辺の和も $(1 - \beta)\beta^0 c_1$ です。$t - 1$ で成り立つとすると

$$
a_t = \beta (1 - \beta) \sum_{i=1}^{t-1} \beta^{t-1-i} c_i + (1 - \beta) c_t = (1 - \beta) \sum_{i=1}^{t-1} \beta^{t-i} c_i + (1 - \beta) \beta^{0} c_t = (1 - \beta) \sum_{i=1}^{t} \beta^{t-i} c_i
$$

です。重みの和は、$j = t - i$ と置き換えると $(1 - \beta) \sum_{j=0}^{t-1} \beta^j$ で、有限等比級数の和（<Ref to="mathematics/foundations/what-is-a-number#prop-geometric" />）$\sum_{j=0}^{t-1} \beta^j = (1 - \beta^t) / (1 - \beta)$ により $1 - \beta^t$ です。

**2.** 期待値の線形性（<Ref to="mathematics/hs-probability/finite-probability#thm-linearity-expectation" />）と 1 から $\mathbb{E}[a_t] = (1 - \beta) \sum_{i=1}^{t} \beta^{t-i} \mu = (1 - \beta^t) \mu$ です。$1 - \beta^t > 0$ は定数なので、割れば $\mu$ です。
</Proof>

バイアス補正が効くのは学習の初めだけです。$\beta_2 = 0.999$ のとき $1 - \beta_2^t$ は $t = 1$ で $0.001$、$t = 1000$ で約 $0.632$、$t = 5000$ で約 $0.993$ です。補正をしないと、初めの数百ステップは $v_t$ が実際の $g^2$ の大きさよりずっと小さく見積もられ、歩幅 $m_t / \sqrt{v_t}$ が大きくなりすぎます。

<Remark id="rem-stationarity">
<Ref to="prop-adam-bias-correction" /> の 2 の仮定「勾配の期待値が時刻に依らない」は、学習中には厳密には成り立ちません（重みが動けば勾配の分布も変わります）。この命題が保証するのは、勾配の分布がゆっくりしか変わらない範囲で、初期値 $0$ に由来する偏りが取り除かれることです。Kingma–Ba の原論文も同じ仮定のもとで補正を導いています。
</Remark>

<Example id="ex-adam-three-steps" title="最初の 3 ステップを手で追う">
$\beta_1 = 0.9$、$\beta_2 = 0.999$ とし、ある成分の勾配が $g_1 = 1$、$g_2 = 2$、$g_3 = -1$ だったとします。

| $t$ | $g_t$ | $m_t$ | $v_t$ | $m_t / \sqrt{v_t}$ | $\hat{m}_t$ | $\hat{v}_t$ | $\hat{m}_t / \sqrt{\hat{v}_t}$ |
|---|---|---|---|---|---|---|---|
| 1 | $1$ | $0.1000$ | $0.001000$ | $3.1623$ | $1.0000$ | $1.0000$ | $1.0000$ |
| 2 | $2$ | $0.2900$ | $0.004999$ | $4.1016$ | $1.5263$ | $2.5008$ | $0.9652$ |
| 3 | $-1$ | $0.1610$ | $0.005994$ | $2.0795$ | $0.5941$ | $2.0000$ | $0.4201$ |

たとえば $t = 2$ では $m_2 = 0.9 \times 0.1 + 0.1 \times 2 = 0.29$、$v_2 = 0.999 \times 0.001 + 0.001 \times 4 = 0.004999$、$\hat{m}_2 = 0.29 / (1 - 0.81) = 1.5263$、$\hat{v}_2 = 0.004999 / (1 - 0.998001) = 2.5008$ です。$\hat{m}_2$ は $g_1, g_2$ の重みつき平均（重み $0.9 / 1.9$ と $1 / 1.9$）、$\hat{v}_2$ は $g_1^2, g_2^2$ のほぼ単純平均になっています。

補正なしの比 $m_t / \sqrt{v_t}$ は $2$〜$4$ 程度で、補正ありの比の数倍です。$t = 1$ では、補正ありの比はどんな $g_1 \ne 0$ でも $g_1 / |g_1| = \pm 1$ になります。最初の 1 歩は、勾配の大きさに関係なく、各成分がちょうど $\eta$ だけ動きます。
</Example>

この例で見た「比が勾配の大きさに依らない」という性質は、一般に成り立ちます。

次の命題のねらいは、更新量 $|m_t| / \sqrt{v_t}$ に、勾配の大きさに依らない上限があると示すことです。$m_t$ は勾配の重みつき和、$v_t$ は勾配の 2 乗の重みつき和なので、$m_t$ の 2 乗を $v_t$ で抑える形にすれば比の上限が出ます。そのためにコーシー・シュワルツの不等式を使い、重み $\beta_1^{t-i}$ を $(\beta_1/\sqrt{\beta_2})^{t-i}$ と $(\sqrt{\beta_2})^{t-i}$ の積に分けます。後者が $v_t$ の重みの平方根に当たり、前者の 2 乗の和が等比級数 $\sum \rho^{t-i}$（$\rho = \beta_1^2/\beta_2$）になります。

<Proposition id="prop-adam-step-bound" title="Adam の更新量の上界とスケール不変性">
$0 \le \beta_1 < 1$、$0 < \beta_2 < 1$、$\rho = \beta_1^2 / \beta_2 < 1$ とします。実数 $g_1, \ldots, g_t$ のうち少なくとも 1 つが $0$ でないとし、$m_t, v_t$ を <Ref to="def-adam" /> の 1 成分とします。

1. $\dfrac{|m_t|}{\sqrt{v_t}} \le \dfrac{1 - \beta_1}{\sqrt{1 - \beta_2}} \sqrt{\dfrac{1 - \rho^t}{1 - \rho}} \le \dfrac{1 - \beta_1}{\sqrt{(1 - \beta_2)(1 - \beta_1^2 / \beta_2)}}$ です。
2. バイアス補正をした量については $\dfrac{|\hat{m}_t|}{\sqrt{\hat{v}_t}} \le \dfrac{\sqrt{1 - \beta_2^t}}{1 - \beta_1^t} \cdot \dfrac{1 - \beta_1}{\sqrt{1 - \beta_2}} \sqrt{\dfrac{1 - \rho^t}{1 - \rho}}$ です。
3. $c > 0$ として勾配を一律に $g_i \mapsto c\, g_i$ と置き換えても、$m_t / \sqrt{v_t}$ と $\hat{m}_t / \sqrt{\hat{v}_t}$ は変わりません。

したがって $\varepsilon = 0$ の Adam では、1 ステップで各成分が動く量 $\eta\, |\hat{m}_t| / \sqrt{\hat{v}_t}$ は、勾配の大きさに依らず、$\eta$ と $\beta_1, \beta_2, t$ だけで決まる定数以下です。
</Proposition>

<Proof of="prop-adam-step-bound">
**1.** <Ref to="prop-adam-bias-correction" /> の 1 から $m_t = (1 - \beta_1) \sum_{i=1}^{t} \beta_1^{t-i} g_i$、$v_t = (1 - \beta_2) \sum_{i=1}^{t} \beta_2^{t-i} g_i^2$ です。少なくとも 1 つの $g_i$ が $0$ でなく $\beta_2 > 0$ なので $v_t > 0$ です。各項を

$$
\beta_1^{t-i} g_i = \Bigl(\frac{\beta_1}{\sqrt{\beta_2}}\Bigr)^{t-i} \cdot \bigl(\sqrt{\beta_2}\bigr)^{t-i} g_i
$$

と 2 つの因子に分け、$\mathbb{R}^t$ の標準内積についてのコーシー・シュワルツの不等式（<Ref to="mathematics/linear-algebra/inner-product-spaces#thm-cauchy-schwarz" />）を使うと

$$
\Bigl(\sum_{i=1}^{t} \beta_1^{t-i} g_i\Bigr)^2 \le \Bigl(\sum_{i=1}^{t} \rho^{t-i}\Bigr) \Bigl(\sum_{i=1}^{t} \beta_2^{t-i} g_i^2\Bigr) = \frac{1 - \rho^t}{1 - \rho} \cdot \frac{v_t}{1 - \beta_2}
$$

です。最後の等号では、等比級数の和（<Ref to="mathematics/foundations/what-is-a-number#prop-geometric" />）$\sum_{j=0}^{t-1} \rho^j = (1 - \rho^t)/(1 - \rho)$ と $v_t$ の閉じた形を使いました。両辺に $(1 - \beta_1)^2$ を掛けて平方根を取り、$\sqrt{v_t}$ で割ると最初の不等式です。$0 \le \rho^t$ なので $1 - \rho^t \le 1$ で、2 番目の不等式が従います。

**2.** $|\hat{m}_t| / \sqrt{\hat{v}_t} = \bigl(|m_t| / (1 - \beta_1^t)\bigr) \cdot \sqrt{1 - \beta_2^t} / \sqrt{v_t}$ なので、1 の両辺に $\sqrt{1 - \beta_2^t} / (1 - \beta_1^t)$ を掛けたものです。

**3.** $m_t$ は $g_i$ の 1 次式なので $c$ 倍に、$v_t$ は $g_i^2$ の 1 次式なので $c^2$ 倍になります。$c > 0$ なので $\sqrt{c^2 v_t} = c \sqrt{v_t}$ で、比は変わりません。バイアス補正は $g$ に依らない定数で割るだけなので、$\hat{m}_t / \sqrt{\hat{v}_t}$ も変わりません。
</Proof>

上界の値は $\beta_1, \beta_2$ の組で大きく変わります。$(\beta_1, \beta_2) = (0.9, 0.999)$ では $0.1 / \sqrt{0.001 \times (1 - 0.81/0.999)} \approx 7.27$、Vaswani らが使った $(0.9, 0.98)$ では $0.1 / \sqrt{0.02 \times (1 - 0.81/0.98)} \approx 1.70$ です。勾配が $g_i \propto (\beta_2 / \beta_1)^i$ のように毎ステップ一定の比で大きくなり続けるとき、各 $t$ で 1 の最初の不等式が等号になり（コーシー・シュワルツの不等式の等号条件）、$t \to \infty$ で右端の値に近づきます。したがって右端の値は、これより小さくできない上限です。勾配が一定のときは $\hat{m}_t / \sqrt{\hat{v}_t} = \pm 1$ ちょうどで、勾配の符号が毎回入れ替わるときは $1$ よりずっと小さくなります（<Ref to="exr-adam-sign-flip" /> では約 $1/19$）。下のコードで上限に近づく場合と一定の場合を確かめます。

次の注意は、原論文の記述と本記事の上界が食い違って見える点についてです。結論だけ先に言うと、原論文の値は典型的な場合の目安で、本記事の値は最悪の場合の上限です。

<Aside type="caution">
この上界は $1$ を超えます。「Adam の 1 ステップは学習率 $\eta$ 以下」とは**言えません**。Kingma–Ba の原論文（§2.1、学習率を $\alpha$ と書いています）は、$\varepsilon = 0$ のときの更新量について、$1 - \beta_1 > \sqrt{1 - \beta_2}$ の場合は $\alpha (1 - \beta_1)/\sqrt{1 - \beta_2}$、そうでない場合は $\alpha$ という 2 つの上界を挙げ、前者は「現在の時刻以外の勾配がすべて $0$」という最も疎な場合にだけ起こると述べたうえで、更新量は「おおよそ $\alpha$ で抑えられる」とまとめています。$(\beta_1, \beta_2) = (0.9, 0.999)$ では $(1 - \beta_1)/\sqrt{1 - \beta_2} \approx 3.16$ です。

これは典型的な場合（勾配の分布がほぼ定常な場合と、勾配が疎な場合）についての目安として読むもので、あらゆる勾配列に対する上界ではありません。<Ref to="prop-adam-step-bound" /> が示すとおり、最悪の場合の上限は $(0.9, 0.999)$ で約 $7.27$ で、$3.16$ より大きくなります。極端な列でなくても、勾配の大きさが毎ステップ $1\%$ ずつ増え続ける（$g_t = 1.01^t$）だけで、$m_t / g_t \to (1 - \beta_1)/(1 - \beta_1/1.01)$、$v_t / g_t^2 \to (1 - \beta_2)/(1 - \beta_2/1.01^2)$ から比は約 $4.18$ に近づきます。逆に、勾配の大きさがほぼ一定の間は比は $1$ 前後かそれ以下です。「1 ステップは $\eta$ 程度」という経験則は、勾配の大きさが急に変わらないことを前提にしています。
</Aside>

スケール不変性（3）は、Adam が損失を定数倍しても同じ軌道をたどることを意味します。素の勾配降下法では、損失を $10$ 倍すると歩幅も $10$ 倍になり、学習率を調整し直す必要があります。一方でこの性質は、次の命題のとおり、L2 正則化の効き方を変えてしまいます。

<Definition id="def-adamw" title="L2 正則化・重み減衰・AdamW">
損失 $f(\theta)$ と $\lambda \ge 0$ に対して、

- **L2 正則化**: $f$ の代わりに $f(\theta) + \frac{\lambda}{2} \|\theta\|^2$ を最小化します。勾配は $\nabla f(\theta) + \lambda \theta$ になります。
- **重み減衰**: $f$ の勾配による更新とは別に、ステップごとに $\theta$ から $\eta \lambda \theta$ を引きます。
- **AdamW**: <Ref to="def-adam" /> の $\boldsymbol{g}_t$ には $f$ だけの勾配を使い、更新を $\theta_t = \theta_{t-1} - \eta \Bigl( \dfrac{\hat{\boldsymbol{m}}_t}{\sqrt{\hat{\boldsymbol{v}}_t} + \varepsilon} + \lambda\, \theta_{t-1} \Bigr)$ とします。
</Definition>

<Remark id="rem-adamw-parametrization">
Loshchilov–Hutter の原論文は、減衰の項に学習率を掛けない形（減衰率とスケジュールの乗数だけを掛ける形）で書いています。上の定義は減衰率を $\eta\lambda$ とまとめた形で、$\lambda$ の値の読み替えだけの違いです。以下の命題は、どちらの書き方でも同じ内容になります。
</Remark>

<Proposition id="prop-adamw-decoupling" title="L2 正則化と重み減衰は SGD では一致し、Adam では一致しない">
$f$ を微分可能な損失、$\eta > 0$、$\lambda \ge 0$ とします。

1. 素の（確率的）勾配降下法では、L2 正則化つきの 1 ステップ $\theta' = \theta - \eta (\boldsymbol{g} + \lambda \theta)$ と、重み減衰つきの 1 ステップ $\theta' = (1 - \eta\lambda)\theta - \eta \boldsymbol{g}$ は、同じ $\theta, \boldsymbol{g}$ に対して同じ値を与えます。
2. $\varepsilon = 0$ の Adam の最初の 1 ステップ（$m_0 = v_0 = 0$）を 1 成分で考え、その成分の損失の勾配を $g \ne 0$、重みを $\theta_0$ とし、$g + \lambda\theta_0 \ne 0$ とします。L2 正則化つきの Adam は $\theta_1 = \theta_0 - \eta\, \mathrm{sgn}(g + \lambda\theta_0)$、AdamW は $\theta_1 = (1 - \eta\lambda)\theta_0 - \eta\, \mathrm{sgn}(g)$ を与えます。$\lambda\theta_0 \ne 0$ で $g$ と $g + \lambda\theta_0$ の符号が同じなら、両者の差は $\eta\lambda\theta_0 \ne 0$ です。
</Proposition>

<Proof of="prop-adamw-decoupling">
**1.** $\theta - \eta(\boldsymbol{g} + \lambda\theta) = \theta - \eta\lambda\theta - \eta \boldsymbol{g} = (1 - \eta\lambda)\theta - \eta \boldsymbol{g}$ です。

**2.** 最初のステップでは、使う勾配を $\tilde{g}$ とすると $m_1 = (1 - \beta_1)\tilde{g}$、$v_1 = (1 - \beta_2)\tilde{g}^2$ で、バイアス補正により $\hat{m}_1 = \tilde{g}$、$\hat{v}_1 = \tilde{g}^2$ です。したがって $\hat{m}_1 / \sqrt{\hat{v}_1} = \tilde{g} / |\tilde{g}| = \mathrm{sgn}(\tilde{g})$ です。L2 正則化つきの Adam は $\tilde{g} = g + \lambda\theta_0$ を使うので $\theta_1 = \theta_0 - \eta\, \mathrm{sgn}(g + \lambda\theta_0)$ です。AdamW は $\tilde{g} = g$ を使い、別に $\eta\lambda\theta_0$ を引くので $\theta_1 = \theta_0 - \eta\, \mathrm{sgn}(g) - \eta\lambda\theta_0$ です。符号が同じとき、差は $\eta\lambda\theta_0$ です。
</Proof>

2 の式を見ると、違いの理由が分かります。L2 正則化の項 $\lambda\theta$ は勾配に足されるので、2 次モーメントで割られる側に入ります。すると <Ref to="prop-adam-step-bound" /> のスケール不変性によって、その大きさの情報が失われます。$\theta_0$ が $10$ でも $1000$ でも、最初の 1 歩で引かれる量は $\eta$ です。AdamW は減衰の項を割り算の外に出すので、重みの大きさに比例した量が引かれます。

<Example id="ex-adamw-one-step" title="1 ステップの値を比べる">
$\theta_0 = 10$、損失の勾配 $g = 1$、$\lambda = 0.1$、$\eta = 0.1$ とします。

- SGD + L2 正則化: $10 - 0.1 \times (1 + 0.1 \times 10) = 9.8$。
- SGD + 重み減衰: $(1 - 0.01) \times 10 - 0.1 \times 1 = 9.8$。一致します。
- Adam + L2 正則化: $\tilde{g} = 2$ で $\mathrm{sgn}(\tilde{g}) = 1$、$\theta_1 = 10 - 0.1 = 9.9$。
- AdamW: $\theta_1 = 10 - 0.1 \times 1 - 0.1 \times 0.1 \times 10 = 9.8$。

Adam + L2 正則化では、正則化の項は勾配を $1$ から $2$ に変えましたが、符号が同じなので更新には何の影響も与えていません。
</Example>

次のコードは、Adam と AdamW を 1 つの関数にまとめ、上の例と、曲率が成分によって $10^4$ 倍違う 2 次関数での結果を比べます。

```python
# Python 3.12.14, NumPy 2.5.2
import numpy as np

def run(grad, theta, steps, eta=0.1, b1=0.9, b2=0.999, eps=1e-8, l2=0.0, wd=0.0):
    """l2: 損失に (l2/2)|theta|^2 を足す（Adam + L2）。wd: 重み減衰（AdamW）。"""
    theta = np.array(theta, dtype=float); m = np.zeros_like(theta); v = np.zeros_like(theta)
    for t in range(1, steps + 1):
        g = grad(theta) + l2 * theta                 # L2 正則化は勾配に入る
        m = b1 * m + (1 - b1) * g
        v = b2 * v + (1 - b2) * g * g
        mhat, vhat = m / (1 - b1 ** t), v / (1 - b2 ** t)
        theta = theta - eta * mhat / (np.sqrt(vhat) + eps) - eta * wd * theta   # 減衰は外で掛ける
    return theta

# (a) 1 ステップ: theta = 10, 損失の勾配 g = 1, lambda = 0.1, eta = 0.1
g1 = lambda th: np.ones_like(th)
print("1 step  Adam+L2:", run(g1, [10.0], 1, l2=0.1), " AdamW:", run(g1, [10.0], 1, wd=0.1))
print("1 step  SGD+L2 :", 10.0 - 0.1 * (1 + 0.1 * 10.0), " SGD+decay:", (1 - 0.1 * 0.1) * 10.0 - 0.1 * 1)

# (b) 曲率が 10^4 倍違う 2 成分: f(theta) = 100*(th1 - 1)^2/2 + 0.01*(th2 - 1)^2/2
h = np.array([100.0, 0.01])
gq = lambda th: h * (th - 1.0)
print("exact minimizer with L2 (lambda=0.01):", h / (h + 0.01))
print("Adam+L2, 2000 steps:", run(gq, [0.0, 0.0], 2000, eta=0.01, l2=0.01))
print("AdamW  , 2000 steps:", run(gq, [0.0, 0.0], 2000, eta=0.01, wd=0.01))

# (c) |m_t|/sqrt(v_t) の上界と、それに近づく勾配列 g_i = (b2/b1)^i
b1, b2 = 0.9, 0.999
bound = (1 - b1) / np.sqrt((1 - b2) * (1 - b1 ** 2 / b2))
m = v = 0.0
for i in range(1, 201):
    g = (b2 / b1) ** i
    m = b1 * m + (1 - b1) * g; v = b2 * v + (1 - b2) * g * g
print(f"bound = {bound:.4f}, attained ratio after 200 steps = {m/np.sqrt(v):.4f}")
m = v = 0.0
for i in range(1, 201):
    m = b1 * m + (1 - b1) * 3.0; v = b2 * v + (1 - b2) * 9.0
print(f"constant gradient 3: m/sqrt(v) = {m/np.sqrt(v):.4f}, corrected = {(m/(1-b1**200))/np.sqrt(v/(1-b2**200)):.4f}")
```

```text
1 step  Adam+L2: [9.9]  AdamW: [9.8]
1 step  SGD+L2 : 9.8  SGD+decay: 9.8
exact minimizer with L2 (lambda=0.01): [0.99990001 0.5       ]
Adam+L2, 2000 steps: [0.99990001 0.5       ]
AdamW  , 2000 steps: [0.99921108 0.99921107]
bound = 7.2703, attained ratio after 200 steps = 7.2703
constant gradient 3: m/sqrt(v) = 2.3482, corrected = 1.0000
```

(b) の関数 $f(\theta) = \frac{100}{2}(\theta_1 - 1)^2 + \frac{0.01}{2}(\theta_2 - 1)^2$ に $\frac{\lambda}{2}\|\theta\|^2$ を足したものの最小点は、成分ごとに $h_i / (h_i + \lambda)$ で、$\lambda = 0.01$ なら $(0.9999, 0.5)$ です。Adam + L2 正則化はこの点に収束しています（停留点では勾配が $\boldsymbol{0}$ なので、割り算の有無は停留点の位置を変えません）。曲率の小さい第 2 成分は半分まで縮みます。AdamW は $2000$ ステップの時点で別の点 $(0.9992, 0.9992)$ にあり、曲率が $10^4$ 倍違う 2 つの成分がほぼ同じ値になっています（この点で止まっているわけではなく、さらに続けると両成分とも $1$ のすぐ下まで近づきます。同じコードで $20$ 万ステップ回すと、どちらも $0.99999$ より大きくなります）。AdamW が最小化しているのは $f + \frac{\lambda}{2}\|\theta\|^2$ ではない、ということです。どちらが汎化に良いかは証明できる事柄ではなく、Loshchilov–Hutter が実験で比較しています。

## 6. 学習率スケジュールと勾配クリッピング

<Definition id="def-lr-schedule" title="ウォームアップつきの学習率スケジュール">
ステップ $t$ ごとに学習率 $\eta_t$ を変える規則を**学習率スケジュール**といいます。Vaswani らは、モデルの次元 $d$ とウォームアップのステップ数 $w$ に対して

$$
\eta(t) = d^{-1/2} \min\bigl(t^{-1/2},\ t\, w^{-3/2}\bigr) \qquad (t > 0)
$$

を使いました。初めの $w$ ステップで学習率を $0$ 近くから直線的に上げることを**線形ウォームアップ**、その後 $t^{-1/2}$ に比例して下げることを**逆平方根減衰**といいます。ウォームアップのあと、総ステップ数 $T_{\max}$ までを $\eta(t) = \frac{1}{2} \eta_{\max} \bigl(1 + \cos(\pi (t - w) / (T_{\max} - w))\bigr)$ で下げる規則を**コサイン減衰**といいます。
</Definition>

<Proposition id="prop-warmup-schedule" title="Vaswani らのスケジュールの形">
$d, w > 0$ とし、$\eta(t) = d^{-1/2} \min(t^{-1/2}, t\, w^{-3/2})$（$t > 0$）とします。

1. $0 < t \le w$ では $\eta(t) = d^{-1/2} w^{-3/2}\, t$（$t$ の 1 次式で狭義単調増加）、$t \ge w$ では $\eta(t) = d^{-1/2} t^{-1/2}$（狭義単調減少）です。
2. $\eta$ は $t > 0$ で連続で、$t = w$ でただ 1 つの最大値 $\eta(w) = (d\, w)^{-1/2}$ を取ります。
</Proposition>

<Proof of="prop-warmup-schedule">
**1.** $t, w > 0$ について、$t\, w^{-3/2} \le t^{-1/2}$ は両辺に $t^{1/2} w^{3/2} > 0$ を掛けて $t^{3/2} \le w^{3/2}$、すなわち $t \le w$ と同値です。したがって $t \le w$ では最小値は $t\, w^{-3/2}$、$t \ge w$ では $t^{-1/2}$ です。前者は傾きが正の 1 次式、後者は $t^{-1/2}$ の導関数が $-\frac{1}{2} t^{-3/2}$ で負なので狭義単調減少です（<Ref to="mathematics/calculus/mean-value-and-taylor#cor-monotonicity" /> の 3 を $-\eta$ に使います）。

**2.** $t = w$ では 2 つの式がともに $d^{-1/2} w^{-1/2}$ を与えるので、$\eta$ は $t = w$ でつながっています。それぞれの区間の上では連続な関数なので、$\eta$ は $t > 0$ 全体で連続です。1 により、$t$ が $w$ より小さいとき $\eta(t)$ は $\eta(w)$ より小さく、$w$ より大きいときも $\eta(w)$ より小さいので、最大値は $t = w$ だけで取られ、その値は $d^{-1/2} w^{-1/2} = (d\, w)^{-1/2}$ です。
</Proof>

原論文の基本の構成は $d = 512$、$w = 4000$ なので、最大の学習率は $(512 \times 4000)^{-1/2} \approx 6.99 \times 10^{-4}$ です。$t = 2000$ ではその半分の $3.49 \times 10^{-4}$、$t = 16000$ でも $3.49 \times 10^{-4}$ です（$t^{-1/2}$ は $t$ が $4$ 倍で半分になります）。

ウォームアップがなぜ要るのかは、定理ではありません。ただ、<Ref to="ex-adam-three-steps" /> で見たように、学習の初めは $\hat{v}_t$ がごく少数の勾配だけから見積もられ、どの成分も $\eta$ 程度ずつ動きます。初めの学習率を小さくしておけば、見積もりが安定するまでの動きを抑えられます。これは 1 つの説明で、証明された必要条件ではありません。

<Definition id="def-gradient-clipping" title="ノルムによる勾配クリッピング">
しきい値 $c > 0$ に対して、

$$
\mathrm{clip}_c(\boldsymbol{g}) = \boldsymbol{g} \cdot \min\Bigl(1,\ \frac{c}{\|\boldsymbol{g}\|}\Bigr) \quad (\boldsymbol{g} \ne \boldsymbol{0}), \qquad \mathrm{clip}_c(\boldsymbol{0}) = \boldsymbol{0}
$$

を**ノルムによる勾配クリッピング**といいます。
</Definition>

<Proposition id="prop-gradient-clipping" title="クリッピングは方向を保ち、1 ステップの損失の増加を抑える">
$c > 0$ とします。

1. $\mathrm{clip}_c(\boldsymbol{g})$ は $\boldsymbol{g}$ の非負の定数倍で、$\|\mathrm{clip}_c(\boldsymbol{g})\| = \min(\|\boldsymbol{g}\|, c) \le c$ です。$\|\boldsymbol{g}\| \le c$ なら $\mathrm{clip}_c(\boldsymbol{g}) = \boldsymbol{g}$ です。
2. $f : \mathbb{R}^P \to \mathbb{R}$ を $C^1$ 級で $L$-平滑（<Ref to="computer-science/math-for-ml/gradient-descent#def-l-smooth" />）とします。任意のベクトル $\hat{\boldsymbol{g}}$（真の勾配でなくてもかまいません）で $\theta' = \theta - \eta\, \mathrm{clip}_c(\hat{\boldsymbol{g}})$ と更新すると
$$
f(\theta') \le f(\theta) + \eta\, c\, \|\nabla f(\theta)\| + \frac{L}{2} \eta^2 c^2
$$
です。
3. 2 でとくに $\hat{\boldsymbol{g}} = \nabla f(\theta) \ne \boldsymbol{0}$ とし、$s = \min(1, c / \|\nabla f(\theta)\|)$ とおくと
$$
f(\theta') \le f(\theta) - \eta\, s \Bigl(1 - \frac{L \eta s}{2}\Bigr) \|\nabla f(\theta)\|^2
$$
で、$0 < \eta < 2/L$ なら $f(\theta') < f(\theta)$ です。
</Proposition>

<Proof of="prop-gradient-clipping">
**1.** $\boldsymbol{g} \ne \boldsymbol{0}$ のとき、$s = \min(1, c/\|\boldsymbol{g}\|) > 0$ は正の数で、$\mathrm{clip}_c(\boldsymbol{g}) = s \boldsymbol{g}$ です。ノルムは $s \|\boldsymbol{g}\| = \min(\|\boldsymbol{g}\|, c)$ です。$\|\boldsymbol{g}\| \le c$ なら $c / \|\boldsymbol{g}\| \ge 1$ で $s = 1$ です。$\boldsymbol{g} = \boldsymbol{0}$ のときは定義から明示的に $\boldsymbol{0}$ で、主張はどれも成り立ちます。

**2.** $\boldsymbol{u} = \mathrm{clip}_c(\hat{\boldsymbol{g}})$ とおくと、1 から $\|\boldsymbol{u}\| \le c$ です。降下補題（<Ref to="computer-science/math-for-ml/gradient-descent#lem-descent" />）を $\boldsymbol{v} = \theta - \eta \boldsymbol{u}$ に使うと

$$
f(\theta - \eta \boldsymbol{u}) \le f(\theta) - \eta \langle \nabla f(\theta), \boldsymbol{u} \rangle + \frac{L}{2} \eta^2 \|\boldsymbol{u}\|^2
$$

です。コーシー・シュワルツの不等式（<Ref to="mathematics/linear-algebra/inner-product-spaces#thm-cauchy-schwarz" />）から $-\langle \nabla f(\theta), \boldsymbol{u} \rangle \le \|\nabla f(\theta)\| \|\boldsymbol{u}\| \le c\, \|\nabla f(\theta)\|$ で、$\|\boldsymbol{u}\|^2 \le c^2$ なので主張が従います。

**3.** $\boldsymbol{u} = s \nabla f(\theta)$ を同じ不等式に入れると $\langle \nabla f(\theta), \boldsymbol{u} \rangle = s \|\nabla f(\theta)\|^2$、$\|\boldsymbol{u}\|^2 = s^2 \|\nabla f(\theta)\|^2$ なので

$$
f(\theta') \le f(\theta) - \eta s \|\nabla f(\theta)\|^2 + \frac{L}{2} \eta^2 s^2 \|\nabla f(\theta)\|^2
$$

で、まとめると主張の式です。$0 < s \le 1$ と $\eta < 2/L$ から $L\eta s / 2 < 1$ で、括弧の中は正です。
</Proof>

2 の上界が要点です。クリッピングがなければ、右辺の $c$ のところに $\|\hat{\boldsymbol{g}}\|$ が入り、たまたま巨大な確率的勾配が出た 1 ステップで損失が大きく増えることがあります。クリッピングをすると、どんな $\hat{\boldsymbol{g}}$ が来ても、1 ステップの増加は $\eta c \|\nabla f(\theta)\| + \frac{L}{2}\eta^2 c^2$ で頭打ちになります。Pascanu らは、再帰型ネットワークの勾配が急に大きくなる現象への対処としてこの方法を提案しました。なお、ニューラルネットワークの損失が大域的に $L$-平滑であるとは限らないので、2・3 は仮定が成り立つ範囲での主張です。

## 7. 小さなモデルを実際に学習する

ここまでの部品を 1 つにまとめ、前章のモデルを 1 層・1 ヘッドに縮めてバイアスを省いたもの（埋め込み、Pre-LN のブロック 1 つ、最後の[層正規化](/computer-science/llm-architecture/transformer-block#def-layer-norm)、入力と共有した出力行列）を、$68$ 文字の自作の文で学習します。トークンは文字、語彙は $15$ 種類です。逆伝播は手で書き、数値微分と照合します。

コードの `ln_back` などの逆伝播の関数は、各層の微分を連鎖律で順にたどったものです。細部を読み込まなくても、直後の検査（数値微分との差が小さいこと）で合っていることが確かめられます。

```python
# Python 3.12.14, NumPy 2.5.2
import numpy as np

text = "the cat sat on the mat. the dog sat on the log. the cat saw the dog."
chars = sorted(set(text)); V = len(chars)
ids = np.array([chars.index(c) for c in text])
x, y = ids[:-1], ids[1:]; n = len(x); d = 16; dff = 32
held = np.array([chars.index(c) for c in "the dog sat on the mat."])
rng = np.random.default_rng(20261010)
P = {"E": rng.normal(0, 0.1, (V, d)), "pos": rng.normal(0, 0.1, (n, d)),
     "Wq": rng.normal(0, 0.1, (d, d)), "Wk": rng.normal(0, 0.1, (d, d)),
     "Wv": rng.normal(0, 0.1, (d, d)), "Wo": rng.normal(0, 0.1, (d, d)),
     "W1": rng.normal(0, 0.1, (d, dff)), "W2": rng.normal(0, 0.1, (dff, d))}
for k in ("g1", "g2", "g3"): P[k] = np.ones(d)
for k in ("b1", "b2", "b3"): P[k] = np.zeros(d)

def ln(h, g, b):                       # 層正規化（行ごと）
    s = np.sqrt(h.var(axis=1, keepdims=True) + 1e-5)
    xh = (h - h.mean(axis=1, keepdims=True)) / s
    return g * xh + b, (xh, s)

def ln_back(dy, g, cache):             # 層正規化の逆伝播
    xh, s = cache; dxh = dy * g
    dx = (dxh - dxh.mean(axis=1, keepdims=True)
          - xh * (dxh * xh).mean(axis=1, keepdims=True)) / s
    return dx, (dy * xh).sum(axis=0), dy.sum(axis=0)

def loss_and_grad(P, x, y):
    n = len(x); mask = np.triu(np.full((n, n), -np.inf), 1)   # 因果マスク
    h0 = P["E"][x] + P["pos"][:n]
    a, c1 = ln(h0, P["g1"], P["b1"])
    q, k, v = a @ P["Wq"], a @ P["Wk"], a @ P["Wv"]
    S = q @ k.T / np.sqrt(d) + mask
    A = np.exp(S - S.max(axis=1, keepdims=True)); A /= A.sum(axis=1, keepdims=True)
    av = A @ v; h1 = h0 + av @ P["Wo"]
    m, c2 = ln(h1, P["g2"], P["b2"])
    pre = m @ P["W1"]; r = np.maximum(pre, 0); h2 = h1 + r @ P["W2"]
    f, c3 = ln(h2, P["g3"], P["b3"])
    z = f @ P["E"].T                                  # 重み共有: 出力側も E
    z = z - z.max(axis=1, keepdims=True)
    logp = z - np.log(np.exp(z).sum(axis=1, keepdims=True))
    loss = -logp[np.arange(n), y].mean()
    G = {}
    dz = np.exp(logp); dz[np.arange(n), y] -= 1; dz /= n   # softmax - one-hot
    G["E"] = dz.T @ f
    dh2, G["g3"], G["b3"] = ln_back(dz @ P["E"], P["g3"], c3)
    G["W2"] = r.T @ dh2; dpre = (dh2 @ P["W2"].T) * (pre > 0)
    G["W1"] = m.T @ dpre
    dm, G["g2"], G["b2"] = ln_back(dpre @ P["W1"].T, P["g2"], c2)
    dh1 = dh2 + dm
    G["Wo"] = av.T @ dh1; dav = dh1 @ P["Wo"].T
    dA = dav @ v.T; dv = A.T @ dav
    dS = A * (dA - (dA * A).sum(axis=1, keepdims=True)) / np.sqrt(d)
    dq, dk = dS @ k, dS.T @ q
    G["Wq"], G["Wk"], G["Wv"] = a.T @ dq, a.T @ dk, a.T @ dv
    da = dq @ P["Wq"].T + dk @ P["Wk"].T + dv @ P["Wv"].T
    dh, G["g1"], G["b1"] = ln_back(da, P["g1"], c1)
    dh0 = dh1 + dh
    G["pos"] = np.zeros_like(P["pos"]); G["pos"][:n] = dh0; np.add.at(G["E"], x, dh0)
    return loss, G

# 逆伝播の検査: 中心差分との最大のずれ
loss, G = loss_and_grad(P, x, y); worst = 0.0
for name in P:
    for _ in range(3):
        i = tuple(rng.integers(0, s) for s in P[name].shape)
        old = P[name][i]; eps = 1e-5
        P[name][i] = old + eps; lp = loss_and_grad(P, x, y)[0]
        P[name][i] = old - eps; lm = loss_and_grad(P, x, y)[0]
        P[name][i] = old
        worst = max(worst, abs((lp - lm) / (2 * eps) - G[name][i]))
print(f"|V| = {V}, n = {n}, parameters = {sum(p.size for p in P.values())}")
print(f"max |numeric - backprop| = {worst:.2e}")

# Adam（バイアス補正つき）で全系列を 1 バッチとして学習
m1 = {k: np.zeros_like(p) for k, p in P.items()}
m2 = {k: np.zeros_like(p) for k, p in P.items()}
eta, b1, b2, eps = 0.01, 0.9, 0.999, 1e-8
print(" step    loss  perplexity  held-out ppl")
for t in range(1, 301):
    loss, G = loss_and_grad(P, x, y)
    if t in (1, 10, 50, 100, 200, 300):
        ho = loss_and_grad(P, held[:-1], held[1:])[0]
        print(f"{t:5d}  {loss:6.3f}  {np.exp(loss):10.3f}  {np.exp(ho):12.3f}")
    for k in P:
        m1[k] = b1 * m1[k] + (1 - b1) * G[k]
        m2[k] = b2 * m2[k] + (1 - b2) * G[k] ** 2
        P[k] -= eta * (m1[k] / (1 - b1 ** t)) / (np.sqrt(m2[k] / (1 - b2 ** t)) + eps)
print(f"log |V| = {np.log(V):.3f}")
```

```text
|V| = 15, n = 67, parameters = 3456
max |numeric - backprop| = 6.43e-11
 step    loss  perplexity  held-out ppl
    1   2.787      16.231        15.772
   10   1.442       4.229         5.430
   50   0.021       1.021         1.764
  100   0.005       1.005         1.961
  200   0.002       1.002         2.129
  300   0.001       1.001         2.249
log |V| = 2.708
```

読み取れることを 3 つ挙げます。

- 逆伝播と数値微分の差は $10^{-10}$ 程度で、手で書いた勾配（出力層の $\mathrm{softmax} - \text{one-hot}$ から始まる連鎖）が合っていることが確かめられます。
- 学習前の損失 $2.787$ は $\log |V| = 2.708$ に近く、パープレキシティ $16.2$ は語彙の大きさ $15$ に近い値です。小さな乱数で初期化したモデルはほぼ一様分布を出すので、<Ref to="thm-perplexity" /> の 3 のとおりになります。
- 学習に使った列のパープレキシティは下限の $1$ に近づきます。これは $67$ 個の位置の答えを $3456$ 個の重みで丸暗記した結果で、文の規則を身につけたことを意味しません。学習に使っていない文「the dog sat on the mat.」のパープレキシティは、表示した中では $50$ ステップ目の $1.76$ が最も小さく、その後は上がっています。学習データの損失だけを見ていても、この過学習（学習に使ったデータには合うが、新しいデータには合わなくなること）は分かりません。

実際の学習では、コーパスを文脈長ごとの断片に切ってミニバッチにし、検証用のデータの損失を見て学習を止める時点を決めます。手続きの骨組み（順伝播、交差エントロピー、逆伝播、Adam の更新）はこのコードと同じです。

## 8. 微調整と LoRA

<Definition id="def-finetuning" title="事前学習と微調整">
大きなコーパスで次トークン予測の損失を最小化する学習を**事前学習**、その結果の重み $\theta_0$ を初期値として、別の（ふつうはずっと小さい）データで学習を続けることを**微調整**といいます。すべての重みを更新する微調整を**全体の微調整**といいます。
</Definition>

全体の微調整は、用途ごとに元のモデルと同じ大きさの重みを 1 組ずつ保存することになります。Hu らの LoRA は、重み行列の**更新**を低階数の積に限ることで、保存し学習する量を減らします。

<Definition id="def-lora" title="低階数適応（LoRA）">
事前学習済みの重み行列 $W_0 \in \mathbb{R}^{d \times k}$ と整数 $r \ge 1$ に対して、$B \in \mathbb{R}^{d \times r}$、$A \in \mathbb{R}^{r \times k}$ を新しい重みとして導入し、

$$
W = W_0 + \Delta W, \qquad \Delta W = B A
$$

とおきます。$W_0$ は固定し、$A$ と $B$ だけを学習する方法を**低階数適応**（LoRA）といい、$r$ をその**階数**（の上限）といいます。原論文では $A$ を乱数、$B$ を零行列で初期化し、$\Delta W$ に定数 $\alpha / r$ を掛けます。
</Definition>

<Figure caption="大きな更新 ΔW（d×k）を、細長い 2 つの行列 B（d×r）と A（r×k）の積で置き換える。保存する数は dk 個から r(d+k) 個になる。">

<svg viewBox="0 0 720 230" width="100%" role="img" aria-label="d×k の行列 ΔW を、d×r の行列 B と r×k の行列 A の積に置き換える図">
  <g fill="none" stroke="currentColor" stroke-width="1.4">
    <rect x="20" y="30" width="200" height="140" rx="4" />
    <rect x="310" y="30" width="40" height="140" rx="4" stroke="var(--sl-color-accent)" />
    <rect x="390" y="30" width="200" height="40" rx="4" stroke="var(--sl-color-accent)" />
  </g>
  <g fill="currentColor" font-size="14" text-anchor="middle">
    <text x="120" y="105">ΔW</text>
    <text x="120" y="195">d × k 個</text>
    <text x="270" y="105" font-size="22">=</text>
    <text x="330" y="105">B</text>
    <text x="330" y="195">d × r 個</text>
    <text x="370" y="55" font-size="22">×</text>
    <text x="490" y="55">A</text>
    <text x="490" y="95">r × k 個</text>
  </g>
</svg>

</Figure>

LoRA のねらいは、保存して学習する数を減らすことです。左の大きな更新を、右の細い 2 つの行列に分けて持ちます。ここで $r$ が小さいほど、右の 2 つの行列の成分の数は少なくなります。

この節では行列を列ベクトルに左から掛ける向き（$\boldsymbol{h} = W \boldsymbol{x}$、$\boldsymbol{x} \in \mathbb{R}^k$）で書きます。定数 $\alpha / r$ は $B$ に吸収できるので、以下では省きます。まず、積の階数についての補題を用意します。階数は像の次元（<Ref to="mathematics/linear-algebra/matrices-and-linear-systems#def-rank" />）です。

<Lemma id="lem-rank-product" title="積の階数">
$B \in \mathbb{R}^{d \times r}$、$A \in \mathbb{R}^{r \times k}$ に対して $\operatorname{rank}(BA) \le \min(\operatorname{rank} B, \operatorname{rank} A)$ です。とくに $\operatorname{rank}(BA) \le r$ です。
</Lemma>

<Proof of="lem-rank-product">
任意の $\boldsymbol{x} \in \mathbb{R}^k$ について $BA\boldsymbol{x} = B(A\boldsymbol{x}) \in \operatorname{Im} B$ なので $\operatorname{Im}(BA) \subset \operatorname{Im} B$ です。部分空間の次元は全体の次元以下（<Ref to="mathematics/linear-algebra/vector-spaces#prop-finite-dim-facts" /> の 3）なので $\operatorname{rank}(BA) \le \operatorname{rank} B$ です。

次に、転置を取ると $(BA)^{\mathsf{T}} = A^{\mathsf{T}} B^{\mathsf{T}}$ で、いま示したことから $\operatorname{rank}(A^{\mathsf{T}} B^{\mathsf{T}}) \le \operatorname{rank} A^{\mathsf{T}}$ です。行階数と列階数は等しい（<Ref to="mathematics/linear-algebra/dual-and-quotient-spaces#cor-row-column-rank" />）ので $\operatorname{rank}(BA) = \operatorname{rank}((BA)^{\mathsf{T}}) \le \operatorname{rank} A^{\mathsf{T}} = \operatorname{rank} A$ です。

最後に、$\operatorname{Im} B$ は $B$ の $r$ 本の列で張られるので次元は $r$ 以下で、$\operatorname{rank} B \le r$ です。
</Proof>

<Theorem id="thm-lora-parameters" title="LoRA のパラメータ数と、表せる更新の全体">
$d, k \ge 1$、$1 \le r \le \min(d, k)$ とし、$\Delta W = BA$（$B \in \mathbb{R}^{d \times r}$、$A \in \mathbb{R}^{r \times k}$）とします。

1. 学習するパラメータの数は $r(d + k)$ です。これが全体の微調整の $dk$ より小さいことは、$r < \dfrac{dk}{d + k}$ と同値です。
2. $\operatorname{rank} \Delta W \le r$ です。
3. 逆に、$\operatorname{rank} M \le r$ である任意の $M \in \mathbb{R}^{d \times k}$ は、ある $B \in \mathbb{R}^{d \times r}$、$A \in \mathbb{R}^{r \times k}$ によって $M = BA$ と書けます。したがって
$$
\{\, BA : B \in \mathbb{R}^{d \times r},\ A \in \mathbb{R}^{r \times k} \,\} = \{\, M \in \mathbb{R}^{d \times k} : \operatorname{rank} M \le r \,\}
$$
です。
4. $B = O$ で初期化すると、$A$ が何であっても学習開始時に $\Delta W = O$ で、モデルの出力は事前学習済みのモデルと一致します。
5. 学習後に $W = W_0 + BA$ を 1 つの $d \times k$ 行列として計算しておけば、推論時の $\boldsymbol{x} \mapsto W\boldsymbol{x}$ の乗算回数は $dk$ で、元のモデルと同じです。まとめずに $W_0 \boldsymbol{x} + B(A\boldsymbol{x})$ と計算すると $dk + r(d + k)$ 回です。
</Theorem>

<Proof of="thm-lora-parameters">
**1.** $B$ の成分が $dr$ 個、$A$ の成分が $rk$ 個で、合わせて $r(d + k)$ 個です。$d + k > 0$ なので、$r(d + k) < dk$ の両辺を $d + k$ で割れば $r < dk/(d + k)$ です。

**2.** <Ref to="lem-rank-product" /> です。

**3.** $s = \operatorname{rank} M \le r$ とします。$s = 0$ なら $M = O$ で、$B = O$、$A = O$ とすればよいので、$s \ge 1$ とします。$\operatorname{Im} M$ は $s$ 次元の部分空間なので、基底 $\boldsymbol{b}_1, \ldots, \boldsymbol{b}_s \in \mathbb{R}^d$ が取れます。$M$ の第 $j$ 列 $\boldsymbol{m}_j = M\boldsymbol{e}_j$ は $\operatorname{Im} M$ の元なので、係数 $a_{ij}$ によって

$$
\boldsymbol{m}_j = \sum_{i=1}^{s} a_{ij} \boldsymbol{b}_i \qquad (j = 1, \ldots, k)
$$

と書けます。$B$ を、初めの $s$ 列が $\boldsymbol{b}_1, \ldots, \boldsymbol{b}_s$ で残りの $r - s$ 列が $\boldsymbol{0}$ である $d \times r$ 行列、$A$ を、$(i, j)$ 成分が $i \le s$ のとき $a_{ij}$、$i > s$ のとき $0$ である $r \times k$ 行列とします。積 $BA$ の第 $j$ 列は、行列の積の定義から「$B$ の列を $A$ の第 $j$ 列の成分で 1 次結合したもの」で、$\sum_{i=1}^{s} a_{ij} \boldsymbol{b}_i + \sum_{i > s} 0 \cdot \boldsymbol{0} = \boldsymbol{m}_j$ です。すべての列が一致するので $BA = M$ です。集合の等式は、2 が左辺 $\subset$ 右辺を、いま示したことが右辺 $\subset$ 左辺を与えます。

**4.** $B = O$ なら $BA = O$ です。したがって $W = W_0$ で、この行列を使う層の出力、ひいてはモデルの出力は変わりません。

**5.** $d \times k$ 行列とベクトルの積は、出力の各成分に $k$ 回の乗算を使うので $dk$ 回です。$W_0 + BA$ も $d \times k$ 行列なので同じです。まとめない場合は、$W_0\boldsymbol{x}$ に $dk$ 回、$A\boldsymbol{x}$ に $rk$ 回、$B(A\boldsymbol{x})$ に $dr$ 回で、合計 $dk + r(d + k)$ 回です。
</Proof>

3 が、この定理の中心です。LoRA は「階数 $r$ 以下の更新」を過不足なく表します。$BA$ という積の形に書くこと自体は、階数 $r$ 以下という条件のほかに何の制約も加えていません。一方で、$B$ と $A$ の取り方は一意ではありません（正則な $r$ 次行列 $G$ について $(BG)(G^{-1}A) = BA$）。パラメータ数 $r(d + k)$ は、階数 $r$ 以下の行列を指定するのに必要な数より多めに数えています。

<Example id="ex-lora-count" title="パラメータ数の比較">
$d = k = 1000$、$r = 8$ とします。全体の微調整では $dk = 1{,}000{,}000$ 個、LoRA では $r(d + k) = 8 \times 2000 = 16{,}000$ 個で、$1.6\%$ です。LoRA のほうが少なくなる条件は $r < dk / (d + k) = 500$ です。$r = 500$ でちょうど同数、$r = 1000$（制約なしと同じ表現力）では $2{,}000{,}000$ 個と、かえって $2$ 倍になります。

$d = k = 768$、$r = 4$ なら $589{,}824$ 個に対して $6{,}144$ 個（約 $1.04\%$）です。
</Example>

<Remark id="rem-lora-best-approximation">
全体の微調整で得られた更新 $\Delta W^{\star}$ が与えられたとき、それを階数 $r$ 以下の行列で近似する誤差の最小値は、$\Delta W^{\star}$ の特異値 $\sigma_1 \ge \sigma_2 \ge \cdots$ で決まります。フロベニウスノルムでは $\min_{\operatorname{rank} M \le r} \|\Delta W^{\star} - M\|_F = \sqrt{\sum_{i > r} \sigma_i^2}$ で、特異値分解（<Ref to="mathematics/linear-algebra/matrix-decompositions#thm-svd" />）を上から $r$ 項で打ち切ったものが最小を与えます（<Ref to="computer-science/ai-era/relearning-mathematics#thm-eckart-young" />。作用素ノルムでは <Ref to="mathematics/linear-algebra/matrix-decompositions#prop-eckart-young" />）。<Ref to="thm-lora-parameters" /> の 3 と合わせると、これは「LoRA で表せる更新のうち $\Delta W^{\star}$ に最も近いもの」の誤差です。ただし LoRA は $\Delta W^{\star}$ を近似するように学習するのではなく、$BA$ の形のまま損失を直接下げるので、学習で得られる $BA$ がこの最良近似になるとは限りません。
</Remark>

次のコードは、3 の分解を特異値分解で実行し、パラメータ数と近似誤差を数えます。

```python
# Python 3.12.14, NumPy 2.5.2
import numpy as np
rng = np.random.default_rng(20261010)

def factor(M, r):
    """階数 r 以下の行列 M を B (d x r) と A (r x k) の積に分解する（特異値分解を使う）。"""
    U, s, Vt = np.linalg.svd(M, full_matrices=False)
    return U[:, :r] * s[:r], Vt[:r]

d, k, r = 60, 40, 4
M = rng.normal(size=(d, r)) @ rng.normal(size=(r, k))        # 階数 4 の 60 x 40 行列
B, A = factor(M, r)
print("rank M =", np.linalg.matrix_rank(M), " shapes:", B.shape, A.shape)
print(f"max |M - BA| = {np.abs(M - B @ A).max():.2e}")
print("parameters: full =", d * k, " LoRA =", r * (d + k))

# 階数が大きい行列を階数 r で近似したときの誤差は、切り捨てた特異値で決まる
W = rng.normal(size=(d, k)); s = np.linalg.svd(W, compute_uv=False)
for rr in (1, 4, 16, 40):
    Br, Ar = factor(W, rr)
    err = np.linalg.norm(W - Br @ Ar); pred = np.sqrt((s[rr:] ** 2).sum())
    print(f"r={rr:2d}  params={rr*(d+k):5d}  error={err:8.4f}  sqrt(sum of dropped sigma^2)={pred:8.4f}")

for (dd, kk, rr) in [(1000, 1000, 8), (768, 768, 4), (4096, 4096, 16)]:
    print(f"d={dd} k={kk} r={rr}: full={dd*kk:,} LoRA={rr*(dd+kk):,} ratio={rr*(dd+kk)/(dd*kk):.4%} threshold dk/(d+k)={dd*kk/(dd+kk):.1f}")
```

```text
rank M = 4  shapes: (60, 4) (4, 40)
max |M - BA| = 8.22e-15
parameters: full = 2400  LoRA = 400
r= 1  params=  100  error= 46.6109  sqrt(sum of dropped sigma^2)= 46.6109
r= 4  params=  400  error= 41.6740  sqrt(sum of dropped sigma^2)= 41.6740
r=16  params= 1600  error= 24.2220  sqrt(sum of dropped sigma^2)= 24.2220
r=40  params= 4000  error=  0.0000  sqrt(sum of dropped sigma^2)=  0.0000
d=1000 k=1000 r=8: full=1,000,000 LoRA=16,000 ratio=1.6000% threshold dk/(d+k)=500.0
d=768 k=768 r=4: full=589,824 LoRA=6,144 ratio=1.0417% threshold dk/(d+k)=384.0
d=4096 k=4096 r=16: full=16,777,216 LoRA=131,072 ratio=0.7812% threshold dk/(d+k)=2048.0
```

階数 $4$ の行列は、丸め誤差の範囲で $BA$ に戻っています。成分が独立な乱数の行列 $W$（階数 $40$）では、$r = 16$ まで上げても誤差は半分程度にしか減りません。乱数の行列は特異値がなだらかにしか減らないからです。低階数の近似が効くかどうかは、近似される行列の特異値の減り方で決まります。

<Remark id="rem-lora-empirical">
微調整での重みの更新が実際に低階数で足りるかどうかは、<Ref to="thm-lora-parameters" /> からは分かりません。これは経験的な事柄です。Hu らは、事前学習済みの言語モデルを下流の課題に適応させるときの重みの変化は「内在的な階数」が低いという仮説を立て、注意の射影行列に小さな $r$ の LoRA を入れて全体の微調整と比べる実験と、学習された $\Delta W$ の部分空間を調べる分析を報告しています。どの行列に入れるか、$r$ をいくつにするかは課題とモデルに依り、この章の命題が決めるものではありません。
</Remark>

## 9. 指示チューニングと人間のフィードバックによる強化学習（概観）

次トークン予測で事前学習したモデルは、文章の続きを書くモデルです。質問に答える、指示に従うといった振る舞いは、続けて行う学習で形づくられます。この節は、何を目的関数にして何を更新するのかの概観で、定理は立てません。

<Figure caption="事前学習のあとに続く学習の 3 段階。どの段階も、同じ形のモデルの重みを勾配で更新する。違うのは目的関数とデータである。">

<svg viewBox="0 0 720 200" width="100%" role="img" aria-label="事前学習、指示チューニング、報酬モデルの学習、強化学習の流れ">
  <defs>
    <marker id="tl-head" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="7" markerHeight="7" orient="auto">
      <path d="M 0 0 L 10 5 L 0 10 z" fill="currentColor" />
    </marker>
  </defs>
  <g fill="none" stroke="currentColor" stroke-width="1.4">
    <rect x="10" y="30" width="150" height="70" rx="6" />
    <rect x="200" y="30" width="150" height="70" rx="6" />
    <rect x="390" y="30" width="150" height="70" rx="6" stroke="var(--sl-color-accent)" />
    <rect x="580" y="30" width="130" height="70" rx="6" />
    <path d="M 160 65 L 196 65" marker-end="url(#tl-head)" />
    <path d="M 350 65 L 386 65" marker-end="url(#tl-head)" />
    <path d="M 540 65 L 576 65" marker-end="url(#tl-head)" />
  </g>
  <g fill="currentColor" font-size="13" text-anchor="middle">
    <text x="85" y="58">事前学習</text>
    <text x="85" y="80">次トークン予測</text>
    <text x="275" y="58">指示チューニング</text>
    <text x="275" y="80">次トークン予測</text>
    <text x="465" y="58">報酬モデルの学習</text>
    <text x="465" y="80">順位づけの損失</text>
    <text x="645" y="58">強化学習</text>
    <text x="645" y="80">報酬の期待値</text>
    <text x="85" y="130">データ: 大量の文章</text>
    <text x="275" y="130">データ: 指示と</text>
    <text x="275" y="148">望ましい応答の組</text>
    <text x="465" y="130">データ: 複数の応答への</text>
    <text x="465" y="148">人の順位づけ</text>
    <text x="645" y="130">データ: モデル自身の</text>
    <text x="645" y="148">出力と報酬モデルの値</text>
    <text x="85" y="180">更新: 言語モデル</text>
    <text x="275" y="180">更新: 言語モデル</text>
    <text x="465" y="180">更新: 報酬モデル</text>
    <text x="645" y="180">更新: 言語モデル</text>
  </g>
</svg>

</Figure>

- **指示チューニング**は、「指示と、それに対する望ましい応答」の組を集め、応答の部分に対する次トークン予測の損失（<Ref to="def-next-token-loss" />）で微調整することです。目的関数は事前学習と同じ形で、データだけが違います。<Ref to="prop-mle-cross-entropy-lm" /> はそのまま当てはまり、これは「人が書いた応答の尤度の最大化」です。
- **人間のフィードバックによる強化学習**（RLHF）は、手本を真似るのではなく、人の好みを直接の目的にします。Christiano らは、人が 2 つの振る舞いのどちらが良いかを比べた結果から報酬の関数を学習し、その報酬で方策を強化学習する方法を示しました。Ouyang らはこれを言語モデルに適用し、(1) 手本による教師あり微調整、(2) 複数の出力への人の順位づけから報酬モデルを学習、(3) その報酬モデルの値を報酬として言語モデルを強化学習で更新、という 3 段階を報告しています。
- (3) の目的関数は「モデルが生成した応答に対する報酬の期待値」で、次トークン予測の損失とは別の量です。生成は標本抽出を含むので（[推論](/computer-science/llm-architecture/inference-and-sampling)）、その勾配は逆伝播だけでは求まらず、方策勾配法（報酬の期待値が上がる向きに、生成の確率を動かす強化学習の方法）が使われます。

ここで押さえておくことは 2 つです。1 つは、どの段階もモデルの形を変えず、重みだけを変えることです。もう 1 つは、(2) の報酬モデルは人の判断の近似にすぎず、(3) はその近似を最大化するということです。報酬モデルが人の判断とずれているところでは、言語モデルはそのずれのほうに最適化されることがあります。特定のモデルがどのデータでどう学習されたかは、公開されている範囲が限られるので、ここでは扱いません。

## 10. 演習

<Exercise id="exr-perplexity-two-models" difficulty="易">
$|V| = 8$ とします。モデル A は長さ $4$ の列の各位置の正解に確率 $(1/2, 1/2, 1/2, 1/2)$ を、モデル B は $(1, 1, 1, 1/64)$ を割り当てました。それぞれのパープレキシティを求め、どちらが小さいか答えてください。また、モデル B の 4 番目の確率が $0$ に近づくとパープレキシティがどうなるかを述べてください。
<Solution>
モデル A: $-\log_2 q_t$ はどれも $1$ で、平均は $1$ ビット、$\mathrm{PPL} = 2^1 = 2$ です。

モデル B: $-\log_2 q_t$ は $0, 0, 0, 6$ で、平均は $6/4 = 1.5$ ビット、$\mathrm{PPL} = 2^{1.5} = 2\sqrt{2} \approx 2.83$ です。

モデル A のほうが小さくなります。B は 4 つのうち 3 つを確信を持って当てていますが、1 か所で正解に $1/64$（一様分布の $1/8$ より小さい値）しか与えず、その 1 か所が平均を押し上げています。4 番目の確率を $q$ とすると $\mathrm{PPL} = q^{-1/4}$ で、$q \to 0$ のとき限りなく大きくなります。パープレキシティは幾何平均なので、1 か所でも正解に $0$ に近い確率を付けると、ほかの位置がどれだけ良くても救われません。
</Solution>
</Exercise>

<Exercise id="exr-bigram-minimizer" difficulty="標準">
語彙 $V = \{\mathrm{a}, \mathrm{b}\}$ とし、モデルは直前の 1 トークンだけを見る（$p(\cdot \mid x_{<t})$ が $x_{t-1}$ だけで決まる）とします。コーパスは 1 本の列 $\mathrm{a\,b\,a\,a\,b\,a\,b\,b}$ で、2 番目以降の $7$ 個の位置を予測の対象にします。条件付き確率を自由に選べるとき、損失 $\mathcal{L}$ を最小にする $p(\cdot \mid \mathrm{a})$、$p(\cdot \mid \mathrm{b})$ と、そのときの損失・パープレキシティを求めてください。
<Solution>
直前のトークンと次のトークンの組を数えます。列の隣り合う組は ab, ba, aa, ab, ba, ab, bb の $7$ 個です。直前が a のものは ab, aa, ab, ab の $4$ 個で、次が a が $1$ 回、b が $3$ 回です。直前が b のものは ba, ba, bb の $3$ 個で、次が a が $2$ 回、b が $1$ 回です。

<Ref to="prop-mle-cross-entropy-lm" /> の 2 から $\mathcal{L} = \frac{4}{7} H(\hat{p}(\cdot \mid \mathrm{a}), p(\cdot \mid \mathrm{a})) + \frac{3}{7} H(\hat{p}(\cdot \mid \mathrm{b}), p(\cdot \mid \mathrm{b}))$ で、$\hat{p}(\cdot \mid \mathrm{a}) = (1/4, 3/4)$、$\hat{p}(\cdot \mid \mathrm{b}) = (2/3, 1/3)$ です。2 つの項は別々の変数に依るので、それぞれを最小にすればよく、ギブスの不等式（<Ref to="computer-science/ai-era/relearning-mathematics#prop-gibbs" />）により最小は $p(\cdot \mid c) = \hat{p}(\cdot \mid c)$ のときです。

そのときの損失は経験分布のエントロピーの重みつき平均で、

$$
H(1/4, 3/4) = \tfrac{1}{4}\log 4 + \tfrac{3}{4}\log\tfrac{4}{3} \approx 0.5623, \qquad H(2/3, 1/3) = \tfrac{2}{3}\log\tfrac{3}{2} + \tfrac{1}{3}\log 3 \approx 0.6365
$$

から $\mathcal{L} = \frac{4}{7} \times 0.5623 + \frac{3}{7} \times 0.6365 \approx 0.5941$、$\mathrm{PPL} = e^{0.5941} \approx 1.811$ です。一様分布のモデルの $2$ よりわずかに小さいだけで、この列は直前の 1 トークンからはあまり予測できないことが分かります。
</Solution>
</Exercise>

<Exercise id="exr-adam-sign-flip" difficulty="標準">
$\beta_1 = 0.9$ とし、勾配が $g_t = (-1)^{t}$ と毎回符号を変えるとします。$m_t$ の閉じた形を求め、$t \to \infty$ で $|m_t|$ がどの値に近づくかを答えてください。$v_t$ のバイアス補正後の値 $\hat{v}_t$ も求め、$|\hat{m}_t| / \sqrt{\hat{v}_t}$ の極限を、勾配が一定の場合の値 $1$ と比べてください。
<Solution>
<Ref to="prop-adam-bias-correction" /> の 1 から

$$
m_t = (1 - \beta_1) \sum_{i=1}^{t} \beta_1^{t-i} (-1)^i = (1 - \beta_1)(-1)^t \sum_{j=0}^{t-1} (-\beta_1)^{j} = (1 - \beta_1)(-1)^t\, \frac{1 - (-\beta_1)^t}{1 + \beta_1}
$$

です（$j = t - i$ と置き、$(-1)^{i} = (-1)^t (-1)^{-j} = (-1)^t (-1)^j$ を使いました。公比 $-\beta_1$ の有限等比級数の和は、$(1 + \beta_1)\sum_{j=0}^{t-1}(-\beta_1)^j = 1 - (-\beta_1)^t$ を展開して確かめられます）。$t \to \infty$ で $|m_t| \to (1 - \beta_1)/(1 + \beta_1) = 0.1 / 1.9 \approx 0.0526$ です。

$g_t^2 = 1$ は一定なので $v_t = 1 - \beta_2^t$、$\hat{v}_t = 1$ です。$\hat{m}_t = m_t / (1 - \beta_1^t)$ で $1 - \beta_1^t \to 1$ なので、$|\hat{m}_t| / \sqrt{\hat{v}_t} \to 0.0526$ です。

勾配が一定なら比は $1$ でしたから、符号が毎回入れ替わる成分の歩幅は約 $1/19$ になります。Adam は、向きの定まらない成分の動きを自動的に小さくします。
</Solution>
</Exercise>

<Exercise id="exr-lora-rank-one" difficulty="標準">
$M = \begin{pmatrix} 2 & 4 & 6 \\ 1 & 2 & 3 \end{pmatrix}$ を、$r = 1$ の LoRA の形 $M = BA$（$B \in \mathbb{R}^{2 \times 1}$、$A \in \mathbb{R}^{1 \times 3}$）に書いてください。また $M' = \begin{pmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \end{pmatrix}$ は $r = 1$ では書けないことを示してください。
<Solution>
$M$ の第 2 列は第 1 列の $2$ 倍、第 3 列は $3$ 倍なので、$\operatorname{Im} M$ は $\boldsymbol{b} = (2, 1)^{\mathsf{T}}$ で張られる 1 次元の空間です。<Ref to="thm-lora-parameters" /> の 3 の証明のとおり、$B = \begin{pmatrix} 2 \\ 1 \end{pmatrix}$、$A = \begin{pmatrix} 1 & 2 & 3 \end{pmatrix}$ とすれば $BA = M$ です。パラメータは $1 \times (2 + 3) = 5$ 個で、$M$ の成分の数 $6$ より少なくなっています。

$M'$ の第 1 列 $(1, 0)^{\mathsf{T}}$ と第 2 列 $(0, 1)^{\mathsf{T}}$ は線形独立なので $\operatorname{rank} M' = 2$ です。$r = 1$ の $BA$ は <Ref to="lem-rank-product" /> により階数が $1$ 以下なので、$M' = BA$ とは書けません。
</Solution>
</Exercise>

## 参考文献

- Y. Bengio, R. Ducharme, P. Vincent, C. Jauvin, "A Neural Probabilistic Language Model", *Journal of Machine Learning Research* 3 (2003), 1137–1155. [jmlr.org/papers/v3/bengio03a.html](https://www.jmlr.org/papers/v3/bengio03a.html)
- A. Vaswani, N. Shazeer, N. Parmar, J. Uszkoreit, L. Jones, A. N. Gomez, Ł. Kaiser, I. Polosukhin, "Attention Is All You Need" (2017), [arXiv:1706.03762](https://arxiv.org/abs/1706.03762) — §5.3（Adam の設定と学習率の式）。
- D. P. Kingma, J. Ba, "Adam: A Method for Stochastic Optimization", ICLR 2015, [arXiv:1412.6980](https://arxiv.org/abs/1412.6980) — アルゴリズム 1、§2.1（更新量の大きさ）、§3（バイアス補正）。
- I. Loshchilov, F. Hutter, "Decoupled Weight Decay Regularization", ICLR 2019, [arXiv:1711.05101](https://arxiv.org/abs/1711.05101) — 命題 1・2、アルゴリズム 2（AdamW）。
- R. Pascanu, T. Mikolov, Y. Bengio, "On the difficulty of training Recurrent Neural Networks" (2012), [arXiv:1211.5063](https://arxiv.org/abs/1211.5063) — ノルムによる勾配クリッピング。
- E. J. Hu, Y. Shen, P. Wallis, Z. Allen-Zhu, Y. Li, S. Wang, L. Wang, W. Chen, "LoRA: Low-Rank Adaptation of Large Language Models" (2021), [arXiv:2106.09685](https://arxiv.org/abs/2106.09685)
- L. Ouyang ほか, "Training language models to follow instructions with human feedback" (2022), [arXiv:2203.02155](https://arxiv.org/abs/2203.02155)
- P. Christiano, J. Leike, T. B. Brown, M. Martic, S. Legg, D. Amodei, "Deep reinforcement learning from human preferences" (2017), [arXiv:1706.03741](https://arxiv.org/abs/1706.03741)
