diff --git a/CLAUDE.md b/CLAUDE.md index 7673e23..b408e9c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -5,7 +5,7 @@ ## 開発進捗 -最新: PLAN_02 Step 4〜5(学習・5-fold 交差検証)完了.4 モデル × 2 条件 × 3 seed を実行(TEST_03).次は Step 7(実験反復) +最新: PLAN_02 Step 7 の一部としてクラス不均衡対策(重み・バランス・サンプリング)を実装・実験(TEST_04).次は学習率の公平な選び直し ※ 本欄は**最新ステップ 1 行のみ上書き更新**.詳細な進捗履歴(動機・設計判断・失敗パターン)は [docs/PROGRESS.md](docs/PROGRESS.md) に追記する.運用ルールは `.claude/rules/progress-log.md` を参照(該当ファイル編集時に自動ロードされる). ## 必須ルール(コード実装時) @@ -101,3 +101,4 @@ - データセット構成調査: docs/06_TEST/TEST_01_データセット構成調査.md - データセット集計結果: docs/06_TEST/TEST_02_データセット集計結果.md - 交差検証結果: docs/06_TEST/TEST_03_交差検証結果.md +- クラス不均衡対策の実験: docs/06_TEST/TEST_04_クラス不均衡対策の実験.md diff --git "a/docs/03_PLAN/PLAN_02_\351\226\213\347\231\272\343\202\271\343\203\206\343\203\203\343\203\227.md" "b/docs/03_PLAN/PLAN_02_\351\226\213\347\231\272\343\202\271\343\203\206\343\203\203\343\203\227.md" index ee36225..d130a72 100644 --- "a/docs/03_PLAN/PLAN_02_\351\226\213\347\231\272\343\202\271\343\203\206\343\203\203\343\203\227.md" +++ "b/docs/03_PLAN/PLAN_02_\351\226\213\347\231\272\343\202\271\343\203\206\343\203\203\343\203\227.md" @@ -12,7 +12,7 @@ | 4 | 学習パイプライン最小版(ConvNeXt-Tiny を 1 本通す)✅ 完了 | Step 2・3 | | 5 | 評価・レポート生成(指標・混同行列・`runs/` 出力)✅ 完了(5-fold 交差検証として実装.結果は [TEST_03](../06_TEST/TEST_03_交差検証結果.md)) | Step 4 | | 6 | ベースライン比較(TIASjudge のルールベース)※ 後回し | Step 5 | -| 7 | 実験反復(不均衡対策・モデル比較・解像度検討) | Step 6 | +| 7 | 実験反復(不均衡対策・モデル比較・解像度検討)※ 一部実施(モデル比較: [TEST_03](../06_TEST/TEST_03_交差検証結果.md)・不均衡対策: [TEST_04](../06_TEST/TEST_04_クラス不均衡対策の実験.md)) | Step 6 | | 8 | 結論(5-fold 交差検証・評価レポート・配布形式の判断) | Step 7 | Step 1・2 はデータのコピー待ちの間に進められる. diff --git "a/docs/06_TEST/TEST_04_\343\202\257\343\203\251\343\202\271\344\270\215\345\235\207\350\241\241\345\257\276\347\255\226\343\201\256\345\256\237\351\250\223.md" "b/docs/06_TEST/TEST_04_\343\202\257\343\203\251\343\202\271\344\270\215\345\235\207\350\241\241\345\257\276\347\255\226\343\201\256\345\256\237\351\250\223.md" new file mode 100644 index 0000000..cdb6071 --- /dev/null +++ "b/docs/06_TEST/TEST_04_\343\202\257\343\203\251\343\202\271\344\270\215\345\235\207\350\241\241\345\257\276\347\255\226\343\201\256\345\256\237\351\250\223.md" @@ -0,0 +1,85 @@ +# クラス不均衡対策の実験 (Class Imbalance Experiments) + +[TEST_03](TEST_03_交差検証結果.md) で紫・淡白の再現率が低かったため,クラス不均衡への対策([SPEC_02「クラス不均衡」→「対策の設定」](../04_SPEC/SPEC_02_学習・評価仕様.md))を 2 モデル × 3 通り × 2 条件 × 3 seed で試した結果.対策なしの結果は TEST_03 のものを使い,**同じ seed・同じ fold どうしで対応比較**した.表は `uv run python scripts/summarize_cv.py runs` で再生成できる. + +| 項目 | 内容 | +| --- | --- | +| 実行日時 | 2026-09-28 08:50〜10:14 | +| 実行場所 | Archimedes の RTX A6000(GPU 1 の 1 枚.未使用の GPU のみを使用) | +| 本数 | 36 本(ConvNeXt-Tiny・ResNet-50 × 対策 3 通り × ややあり込み/除外 × seed 42・43・44) | +| モデルと学習率 | ConvNeXt-Tiny(1e-4)・ResNet-50(1e-3).TEST_03 の設定から対策のキーだけを変えた | +| 対策 | 重み `inverse`・重み `sqrt_inverse`・バランス・サンプリング `balanced` | +| コード | `f9d9ebd-dirty`(コミット `8387ebd` の内容を実行時点で未コミットのまま使用.既定のままなら変更前と同じ学習になることはテストで確認済み) | + +## 結果 (Results) + +common(「あり」と淡紅)の macro F1・正解率と,all(ややあり込みの全体)の macro F1.15 fold の平均 ± 標準偏差. + +| モデル | 対策 | 条件 | common macro F1 | common 正解率 | all macro F1 | +| --- | --- | --- | --- | --- | --- | +| ConvNeXt-Tiny | なし | 込み | 0.541 ± 0.066 | 0.668 ± 0.035 | 0.510 ± 0.056 | +| ConvNeXt-Tiny | 重み inverse | 込み | **0.585 ± 0.057** | 0.669 ± 0.063 | **0.546 ± 0.054** | +| ConvNeXt-Tiny | 重み sqrt | 込み | 0.563 ± 0.045 | 0.645 ± 0.057 | 0.524 ± 0.032 | +| ConvNeXt-Tiny | balanced | 込み | 0.566 ± 0.071 | 0.663 ± 0.081 | 0.528 ± 0.061 | +| ConvNeXt-Tiny | なし | 除外 | 0.592 ± 0.068 | 0.744 ± 0.035 | 0.480 ± 0.056 | +| ConvNeXt-Tiny | 重み inverse | 除外 | **0.632 ± 0.060** | 0.745 ± 0.030 | 0.528 ± 0.043 | +| ConvNeXt-Tiny | 重み sqrt | 除外 | 0.595 ± 0.060 | 0.750 ± 0.030 | 0.490 ± 0.049 | +| ConvNeXt-Tiny | balanced | 除外 | 0.611 ± 0.052 | 0.734 ± 0.041 | 0.509 ± 0.046 | +| ResNet-50 | なし | 込み | 0.546 ± 0.057 | 0.649 ± 0.066 | 0.520 ± 0.050 | +| ResNet-50 | 重み inverse | 込み | 0.558 ± 0.045 | 0.635 ± 0.055 | 0.535 ± 0.035 | +| ResNet-50 | 重み sqrt | 込み | **0.590 ± 0.057** | 0.666 ± 0.070 | **0.554 ± 0.043** | +| ResNet-50 | balanced | 込み | 0.562 ± 0.038 | 0.627 ± 0.045 | 0.533 ± 0.043 | +| ResNet-50 | なし | 除外 | **0.637 ± 0.062** | 0.748 ± 0.045 | 0.519 ± 0.056 | +| ResNet-50 | 重み inverse | 除外 | **0.637 ± 0.058** | 0.720 ± 0.045 | 0.542 ± 0.047 | +| ResNet-50 | 重み sqrt | 除外 | 0.633 ± 0.056 | 0.733 ± 0.045 | 0.534 ± 0.044 | +| ResNet-50 | balanced | 除外 | 0.616 ± 0.050 | 0.712 ± 0.062 | 0.523 ± 0.038 | + +## 対策なしとの対応比較 (Paired Comparison) + +対策あり − 対策なし(同じモデル・条件・seed・fold どうし.15 fold).recall は common でのクラス別再現率の差. + +| モデル | 対策 | 条件 | common F1 の差 | 上回った fold | 淡白 | 紫 | 淡紅 | 暗赤紅 | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | +| ConvNeXt-Tiny | 重み inverse | 込み | **+0.044 ± 0.064** | **11 / 15** | +0.19 | +0.15 | −0.03 | −0.05 | +| ConvNeXt-Tiny | 重み inverse | 除外 | **+0.040 ± 0.063** | **12 / 15** | +0.19 | +0.09 | −0.07 | +0.02 | +| ConvNeXt-Tiny | 重み sqrt | 込み | +0.021 ± 0.052 | 10 / 15 | +0.12 | +0.23 | −0.06 | −0.07 | +| ConvNeXt-Tiny | 重み sqrt | 除外 | +0.003 ± 0.074 | 8 / 15 | −0.01 | −0.04 | −0.02 | +0.06 | +| ConvNeXt-Tiny | balanced | 込み | +0.025 ± 0.060 | 9 / 15 | +0.07 | +0.19 | −0.00 | −0.09 | +| ConvNeXt-Tiny | balanced | 除外 | +0.018 ± 0.067 | 10 / 15 | +0.13 | +0.05 | −0.08 | +0.03 | +| ResNet-50 | 重み inverse | 込み | +0.011 ± 0.060 | 7 / 15 | +0.16 | +0.10 | −0.04 | −0.05 | +| ResNet-50 | 重み inverse | 除外 | −0.000 ± 0.053 | 5 / 15 | +0.11 | +0.08 | −0.04 | −0.12 | +| ResNet-50 | 重み sqrt | 込み | **+0.043 ± 0.065** | **11 / 15** | +0.12 | +0.10 | +0.01 | −0.03 | +| ResNet-50 | 重み sqrt | 除外 | −0.004 ± 0.065 | 8 / 15 | −0.01 | +0.10 | −0.01 | −0.07 | +| ResNet-50 | balanced | 込み | +0.016 ± 0.068 | 8 / 15 | +0.13 | +0.15 | −0.05 | −0.08 | +| ResNet-50 | balanced | 除外 | −0.021 ± 0.071 | 4 / 15 | +0.06 | +0.07 | −0.04 | −0.09 | + +クラス別再現率の差の標準偏差は 0.1〜0.3 と大きい(各 fold の held_out に淡白・紫は 11〜12 人しかいないため). + +## 分かったこと (Findings) + +1. **ConvNeXt-Tiny では重み `inverse` が安定して効く**.込み・除外とも common macro F1 が約 +0.04 上がり(11〜12/15 fold),除外では 0.632 となって ResNet-50 の最良(0.637)と並んだ +2. **ResNet-50(学習率 1e-3)では効果がほとんど無い**.除外ではどの対策も ±0.02 の範囲で,上回った fold も半分以下.込みで `sqrt_inverse` だけが +0.043(11/15) +3. **狙いどおり淡白・紫の再現率は上がる**が(多くの組み合わせで +0.1〜0.2),**淡紅・暗赤紅の再現率が下がる入れ替わり**が起きる(−0.03〜−0.12).macro F1 の改善が小さいのはこのため +4. **all(ややあり込みの全体)の macro F1 も上がる**(ConvNeXt・inverse で 0.510 → 0.546,ResNet-50・sqrt で 0.520 → 0.554) +5. 3 通りの対策の中では,**重み `inverse` が最も安定**.`balanced` は同じ画像を何度も学習するためか効果が不安定で,ResNet-50 の除外では下がった +6. 紫の再現率は対策後も 0.3〜0.55 に留まる.紫は枚数の少なさに加えて暗赤紅と色が近く([TEST_02](TEST_02_データセット集計結果.md).ΔE 4.6),不均衡対策だけでは解決しない + +## 注意 (Caveats) + +- 差の多くは fold 間のばらつき(標準偏差 0.05〜0.08)と同程度で,確定的に言えるのは「ConvNeXt・`inverse` はおおむね改善する」程度 +- ResNet-50 の学習率 1e-3 は TEST_03 で結果を見て選んだもので,その上に重ねた比較である(TEST_03「学習率について」) +- 対策の種類と強さも結果を見て選ぶことになるため,最終的な構成は入れ子の交差検証など評価とは別のデータで選ぶ必要がある + +## 次の一手 (Next Steps) + +- 今後の基準の構成を「ConvNeXt-Tiny・重み `inverse`」または「ResNet-50(1e-3)」とし,学習率の公平な選び直し(入れ子の交差検証)と組み合わせる +- 紫と暗赤紅の取り違えを混同行列で詳しく見る(紫の多くがどのクラスに流れているか) +- 入力解像度を上げる(224 → 320 等).色むらの細部が紫の判別に効く可能性がある + +## 実験 ID (Run IDs) + +手元の `runs/` に回収済み(`.gitignore` 対象).名前の末尾 `_cwinv`・`_cwsqrt`・`_balanced` が対策を表す.実験 ID の日時は 2026-09-28 08:50〜10:12. + +```bash +ls -d runs/*_f9d9ebd-dirty +``` diff --git a/docs/PROGRESS.md b/docs/PROGRESS.md index 54401e9..cc563fe 100644 --- a/docs/PROGRESS.md +++ b/docs/PROGRESS.md @@ -100,3 +100,13 @@ - 止めた判断: 残り時間はあったが,学習率の調整をこれ以上重ねると評価データへの合わせ込みが強まるため,追加実験はせず Step 7 の計画(入れ子の交差検証で全モデル同じ候補から選ぶ)に回した - 未実施: ベースライン比較(Step 6) - 対応済み: 36 本の重み(約 12 GB)が Archimedes の共用ディスク(残り 40 GB・98%)を圧迫していたため,ユーザーの判断で削除した(空き 52 GB に回復).重みは同じ設定で数分で作り直せる(ビット単位の一致はしない).今後は保存するかを設定で選べるようにする + +## Step 7(一部): クラス不均衡への対策 + +- [x] **損失のクラス重み(`inverse`・`sqrt_inverse`)とバランス・サンプリングを追加し,2 モデル × 3 通り × 2 条件 × 3 seed で実験**: TEST_03 で紫・淡白の再現率が低かったため.結果は [TEST_04](06_TEST/TEST_04_クラス不均衡対策の実験.md). + - 設計判断 ①: クラス重みは学習データでの平均が 1 になるよう正規化し,損失はバッチの件数で割る(PyTorch の `CrossEntropyLoss(weight=w)` の既定は重みの和で割るため正規化が効かない.tester の指摘で仕様に明記).損失の大きさを対策なしと揃え,学習率の意味を変えない + - 設計判断 ②: 既定のままなら変更前と同じ学習になるようにし,対策なしの TEST_03 の結果と同じ分割で対応比較した + - 結果: ConvNeXt-Tiny では重み `inverse` が安定して効く(込み・除外とも common macro F1 +0.04,11〜12/15 fold.除外で 0.632).ResNet-50(1e-3)ではほぼ効かない.淡白・紫の再現率は +0.1〜0.2 上がるが淡紅・暗赤紅が下がる入れ替わりがあり,macro F1 の改善は小さい.紫は対策後も 0.3〜0.55 + - 失敗パターン: キュー完了後の自動回収が,長くなったジョブログの末尾しか読めず 36 本中 27 本しか拾えなかった → サーバ上の実験ディレクトリの一覧から回収し直した.以後,回収はログではなくディレクトリの一覧を正とする + - 速度の調査: 学習中の GPU 使用率は平均 86% で計算律速(データ準備は余裕あり).性能を変えずに速くするなら channels_last・bf16(1〜3 割の見込み)や GPU の並列利用が候補(未実施) +