同じコードでも、結果は変わる
第7・8章の実験では、「乱数の種を8通りに変えると、正解率は0.936〜0.969」のように、結果に幅を付けて書いてきました。機械学習では、同じコード・同じデータでも、実行するたびに結果が変わる ことがよくあるからです。
実験:何を変えると、結果が変わるか
第6章の手書き数字のニューラルネットワーク(隠れ層32個)で、2種類の乱数を変えてみました。
(上の行は、分け方を固定して重みの初期値だけを変えたもの。下の行は、重みの初期値を固定して分け方だけを変えたもの。条件が少し違うので、行どうしの値の大きさは比べられません)
コードもデータも同じなのに、乱数を変えるだけで、正解率が0.02〜0.03も変わりました。
機械学習で、乱数が使われているところ
- 重みの初期値(第8章のHe法など)
- 訓練データとテストデータの分け方、交差検証の組の分け方
- ミニバッチを作るときの、データの並べ替え
- ドロップアウトで休ませるニューロンの選び方
- データ拡張(第7章で画像をずらす位置など)
さらに、GPUを使う計算では、足し算の順番がわずかに入れ替わるだけで、結果が少し変わることがあります。
「1回だけの結果」で比べてはいけない
例えば、新しい工夫を入れたモデルが0.918、入れていないモデルが0.898だったとします。差の0.02は、上の実験の「乱数の種を変えただけの差」と同じ大きさです。これだけでは、工夫が効いたのか、たまたまなのか、区別できません。乱数の種を何通りか変えて実験し、結果の幅を比べる必要があります。
結果を再現するために、記録すること
再現性 とは、同じ手順をもう一度行ったとき、同じ結果が得られることです。自分が後で確かめ直すとき、ほかの人に結果を確かめてもらうとき、モデルを作り直すときに必要になります。
記録するもの
結果の書き方
- 乱数の種を何通りか変えて実験し、平均と幅(最小〜最大、または標準偏差) を書く。一番よかった1回だけを書くのは、よい結果だけを選んで見せることになる
- 何回やって、何を変えたのかを書く
このコースでも、スライドの数値は、同じ環境(Pyodide 314.0.3、NumPy 2.4.3、scikit-learn 1.8.0)で乱数の種を固定して測り、幅があるものは幅を書いてきました。例えば、第7章のCNNでは、フィルター8枚の設定が「種によっては学習が進まない」ことを、乱数の種を変えた実験で見つけ、演習では安定するフィルター16枚を使っています。
機械学習のモデルを使う場面での再現性
モデルを実際に使う場面では、「このモデルが、なぜこう判定したのか」を後から確かめられることが求められます。そのときも、どのデータ・どのコード・どの設定で作ったモデルかを記録していなければ、確かめることができません。記録は、次のレッスンの公平性の点検や、問題が起きたときの原因調査の土台になります。
Pythonで再現できるようにする、よくある誤解と振り返り
import numpy as np
import sklearn
from sklearn.model_selection import train_test_split
from sklearn.neural_network import MLPClassifier
print("scikit-learn", sklearn.__version__, "/ numpy", np.__version__) # ライブラリの版を記録する
scores = []
for seed in range(5): # 乱数の種を5通り変えて実験する
model = MLPClassifier(hidden_layer_sizes=(32,), max_iter=100, random_state=seed)
# model.fit(X_train, y_train); scores.append(model.score(X_test, y_test))
...
scores = np.array([0.918, 0.898, 0.909, 0.916, 0.916]) # (上の実験の結果)
print(f"平均 {scores.mean():.3f}、最小 {scores.min():.3f}、最大 {scores.max():.3f}")
# → 平均 0.911、最小 0.898、最大 0.918
- scikit-learnの多くの関数は
random_state で乱数の種を決められます。決めないと、実行するたびに違う乱数が使われます
- NumPyでは
np.random.default_rng(種) で、決まった乱数を作る道具を用意します(第7・8章のコード)
sklearn.__version__ のように、ライブラリの版を調べられます
よくある誤解
- 「乱数の種を固定すれば、それで十分」: 種を固定すると、同じ結果は出せます。しかし、その種で「たまたまよかった」のかもしれません。種を何通りか変えて、結果の幅を確かめます
- 「一番よかった結果を報告すればよい」: よい結果だけを選ぶと、実力より高く見えます。何回やったかと、平均・幅を書きます
- 「同じコードなら、何年たっても同じ結果が出る」: ライブラリの版やデータが変わると、結果が変わることがあります。版も記録します
振り返り
- 機械学習の結果は、重みの初期値・データの分け方・ミニバッチの順番などの乱数で変わる
- 乱数の種・データの版・コードの版・ライブラリの版・ハイパーパラメータを記録する
- 比べるときは、乱数の種を何通りか変えて、平均と幅で比べる