実装で学ぶ機械学習
このブログでは、機械学習やコンピュータサイエンスの仕組みを「解説する」のではなく、実際にコードを書いて動かし、出てきた数値をそのまま載せるという方針で書いています。 うまくいかなかった実験や、予想が外れた結果も削らずに残しています。
34本実験記事
numpyだけで一から実装
失敗もそのまま掲載
生成モデルを一から実装する — 拡散モデル・GAN・Normalizing Flow
画像生成AIの中核にある3つの流派を、PyTorchを使わずnumpyだけで実装し、同じデータ・同じ規模のネットワークで比較しました。
拡散モデル(DDPM)をnumpyで実装するノイズを予測するネットワークを手書きの逆伝播で学習させ、完全なノイズから形が浮かび上がるまでを可視化。
GAN(敵対的生成ネットワーク)を実装する生成器と識別器を競わせると、損失は理論値に収束したのに分布は最後まで揃わなかった。
Normalizing Flow(正規化流)を実装する可逆な変換だけでガウス分布をデータの形に変える流派。往復の再構成誤差は2.07×10⁻¹⁴。
文字レベルGPT(Transformer)を実装する2層Transformerをnumpyで組み、このブログ自身の記事で学習させた。数値微分で勾配の正しさも検証。
Transformerの仕組み — Self-Attentionと位置エンコーディング
ChatGPTなどの基盤になっている注意機構を、式とコードの両方から確かめました。
Self-Attention(QKV)を実装して確かめる教科書の「itがanimalに注目する」という説明図が、学習済みの射影行列なしでは成り立たないことを実験で確認。
位置エンコーディングは何をしているのかsin/cosの位置エンコーディングを外すと語順の情報が失われることを、実際に比較して可視化。
BPE(トークナイザ)を実装して日本語のトークン数を測るLLMのAPI料金に直結する話。「日本語は3倍高い」を実測すると、比較の取り方で2.83倍にも1.38倍にもなる。
強化学習 — バンディット問題とQ学習
探索と活用のトレードオフから、状態と遅延報酬のある迷路まで。
ε-greedy法を実装する(多腕バンディット)探索率を変えると最適行動の選択率が35.95%から79.31%まで変わる。
UCBとトンプソン抽出を比較するε-greedyより賢い2つの戦略を、リグレット曲線で比較。
Q学習で迷路を解く(SARSAとの違いも)価値がゴールから逆向きに伝播する様子を可視化。崖歩き問題でQ学習とSARSAの性格の違いも比較。
次元削減と多様体学習 — PCA・Isomap・t-SNE・UMAP
高次元のデータを2次元に「開く」手法を、見た目で分かるおもちゃデータで検証しました。
スイスロールをIsomapで展開する(PCAとの比較)PCAでは絶対に開けない渦巻きを、測地線距離を使うIsomapは相関0.992で展開した。
穴あきスイスロールで手法の頑健性を試す指標(相関0.99)は無事なのに、埋め込みの見た目は手法ごとに別物になる。
三つ葉結び目は次元削減でほどけるか位相的には円なのに、3次元では自己交差なしに平らにできない図形。
メビウスの輪(向き付け不可能な面)を平面に展開する不可能な要求に対してアルゴリズムは「潰す」ことで帳尻を合わせていた。
カーネルトリックを目で見る(SVM)2次元では直線で分けられないドーナツ型データが、3次元に持ち上げると平面1枚で分離できる。
次元の呪いを実際に測る次元が上がると距離の差が消えていく現象を数値で確認。
学習の挙動 — 過学習・最適化・正則化
モデルが「学習する」ときに実際に何が起きているのかを、条件を振って観察しました。
過学習と正則化を実験で確かめる15点のデータで多項式の次数を上げると、テスト誤差が40億まで爆発する。
SGD・Momentum・RMSprop・Adamを競走させる同じ損失地形で4つの最適化手法を走らせ、「Adamが最強」が常に正しいかを検証。
局所最適解と焼きなまし法200箇所から勾配降下すると正解は0箇所、焼きなまし法なら200箇所。
Grokking(突然の汎化)を再現する訓練精度が満点になってから27,400ステップ後、テスト精度が突然立ち上がる。
二重降下(double descent)を観測するパラメータを増やすほど性能が落ち、さらに増やすと再び良くなる現象。
破局的忘却を起こしてみる新しいタスクを学習すると、前のタスクの精度が0.9834から0.0000まで消える。
学習率のウォームアップは本当に必要か通説をアブレーションで検証したら、崩壊率は下がらなかった。
ドロップアウトは「暗黙のアンサンブル」か明示的なアンサンブルと比較すると、分散の相関はr=0.13しかなかった。
活性化関数(ReLU・sigmoid)の俗説を検証する24層で勾配消失を実測。sigmoidだけが精度0.49まで崩壊した。
統計とデータの見せ方 — 可視化の落とし穴
同じ数字でも、見せ方や比較の設計で受ける印象が変わることを実験で示しました。
Datasaurus(平均も分散も同じで形が違うデータ)を作る焼きなまし法で統計量を固定したまま恐竜をサーモンに変形させた。
ヒストグラムのビン幅とKDEのバンド幅で結論が変わる自動バンド幅選択は二峰性を残すが、谷の深さは大きく失われる。
コンドルセの陪審定理をシミュレーションする多数決は実力差を消さずに増幅する。p=0.55なら0.84、p=0.45なら0.16。
ロジスティック写像とバタフライ効果を実測するリアプノフ指数0.498/stepでの指数的発散を数値で確認。
フラクタル次元をボックスカウント法で測るシェルピンスキーの三角形の次元は1.58。
画像処理と点群 — フーリエ変換・ガボールフィルタ・法線推定
画像や3D点群を扱う古典的な手法を、自分で実装して確かめました。
画像のフーリエ変換で「形」の正体を見る低周波と高周波が画像の何に対応するかを分解して確認。
ガボールフィルタで画像の「向き」を検出する人間の視覚野の初期処理に近いとされるフィルタを実装。
点群の法線推定(PCA)と向きの伝播37.1%が裏返っていた法線を、最小全域木の伝播で0.6%まで改善。
VLMにBBoxをSFTすると何を学習するのか視覚言語モデルのファインチューニングで、モデルが実際に獲得したものを検証。
すべての記事
上記以外にも、生成AIの使い方やClaudeの実践的な話題を扱った記事があります。記事一覧、実験ギャラリー、タグ一覧からも探せます。