# アーキテクチャ設計 (Architecture)

## 基本方針 (Principles)

1. **実データに触るコードはサーバでしか動かさない**．手元では合成データで同じコードパスを流す
2. **手元への回収はホワイトリスト方式**．回収対象を明示的に列挙し，列挙外（画像・manifest・患者 ID）は持ち帰れないようにする
3. 設定は YAML に集約し，pydantic で検証する．コードに絶対パス・閾値を書かない
4. 実験は `runs/<実験ID>/` に閉じる．同じ設定と seed で同じ結果に辿れるようにする

## ディレクトリ構成 (Directory Layout)

```text
TIASJudgeModel/
├── configs/                      # 実験設定 YAML
├── src/tias_judge_model/
│   ├── schema.py                 # pydantic 設定スキーマ
│   ├── data/                     # manifest 読み込み・Dataset・分割・前処理
│   ├── models/                   # timm ラッパ（アーキテクチャ差し替え点）
│   ├── training/                 # 学習ループ・損失・スケジューラ
│   ├── evaluation/               # 指標・混同行列・レポート生成
│   ├── baseline/                 # ルールベース比較（扱いは未定）
│   ├── remote/                   # リモート実行（tar over ssh・tmux・回収）
│   └── cli/                      # エントリポイント
├── scripts/                      # 合成データ生成・manifest 生成
├── tests/
├── data/                         # .gitignore（合成データ．実データは置かない）
└── runs/                         # .gitignore（実験結果）
```

依存方向は `cli` → `training` / `evaluation` → `data` / `models` の一方向とする．`data` と `models` は CLI・学習ループを import しない．

## データ契約 (Data Contract)

元データは研究室 PC の `C:\Users\Papin\clinical-data\TIASJudgeModel\` にラベルごとの 9 フォルダとして置かれている（[ENV_03](../02_ENV/ENV_03_管理者用環境構築手順.md)）．サーバへコピーした後の配置（`~/data/TIASJudgeModel/`）:

```text
~/data/TIASJudgeModel/
├── images/
│   ├── light_red_normal/    # ラベル＿程度のスラッグごとのディレクトリ
│   ├── dark_red_strong/
│   ├── dark_red_mild/
│   ├── purple_strong/
│   ├── purple_mild/
│   ├── red_strong/
│   ├── red_mild/
│   ├── pale_strong/
│   └── pale_mild/
└── manifest.csv             # 学習が読む唯一の入口
```

ディレクトリ名は `<label>_<severity>` のスラッグとする（研究室 PC 側の日本語フォルダ名との対応は [ENV_03](../02_ENV/ENV_03_管理者用環境構築手順.md)．日本語名のまま転送すると文字コード差で壊れるため）．

`manifest.csv` の列:

| 列名 | 内容 | 備考 |
| --- | --- | --- |
| `image_path` | `images/` からの相対パス | — |
| `patient_id` | 患者を一意に識別する ID | **必須**．分割の単位になる |
| `label` | 舌色 5 分類のいずれか | 元データのフォルダ名に由来 |
| `severity` | 程度（`strong` / `mild` / `normal`） | 学習には使わず，評価の層別分析に使う |
| `note` | 任意の備考 | 除外理由等 |

- manifest はサーバ上の生成スクリプトで作る．元データはラベルごとのフォルダに分かれているため，**フォルダ名から `label` と `severity` を決める**（対応表は [TEST_01 データセット構成調査](../06_TEST/TEST_01_データセット構成調査.md)）
- **`patient_id` について**: 現在のデータセットは 1 患者 1 枚であることを確認済み（2026-09-27）．したがって画像 ID をそのまま `patient_id` とする．**この前提が崩れる（同一患者の複数枚が追加される）場合は，実際の患者 ID を入れ直す必要がある**（同一患者が分割を跨ぐと評価が壊れるため）．分割処理は常に `patient_id` 単位で行い，前提が変わってもコードを変えずに済むようにする
- 前提が確認できない新規データに対しては，画像 ID を患者 ID と見なす代替を**自動では行わない**．生成を止めて人間が判断する

## クラス定義 (Class Definition)

内部表現は英字 slug，表示は日本語とし，整数 ID を固定して混同行列の軸をぶらさない．

| ID | slug | 表示 |
| --- | --- | --- |
| 0 | `pale` | 淡白 |
| 1 | `light_red` | 淡紅 |
| 2 | `red` | 紅 |
| 3 | `dark_red` | 暗赤紅 |
| 4 | `purple` | 紫 |

※ 表示名は元データのフォルダ名に合わせている（「暗赤紅」）．順序尺度として扱えるかは未確定（[SPEC_02](SPEC_02_学習・評価仕様.md) 参照）．

## 実験の出力 (Run Artifacts)

```text
runs/<実験ID>/
├── config.yaml            # 解決済み設定 ＋ git コミットハッシュ ＋ seed
├── history.csv            # エポックごとの損失・指標
├── metrics.json           # 最終指標（macro F1・accuracy・クラス別）
├── confusion_matrix.png   # 図
├── confusion_matrix.csv   # 数値
├── log.txt
└── checkpoints/best.pt
```

実験 ID の書式: `YYYYmmdd-HHMMSS_<設定ファイル名>_<git短縮ハッシュ>`

## 回収ホワイトリスト (Pull Whitelist)

手元へ回収できるのは以下のみ．リモート実行ツールにこの制約を実装する．

| 回収する | 回収しない |
| --- | --- |
| `config.yaml`・`history.csv`・`metrics.json`・`*.png`・集計のみの `*.csv`・`log.txt` | 画像・`manifest.csv`・患者 ID を含むファイル・個票の予測結果 |

- `checkpoints/` は既定では回収せず，明示的に指定したときのみ回収する
- 個票（画像ごとの予測）が必要な分析はサーバ上で行い，集計結果だけを持ち帰る

## CLI (Entry Points)

| コマンド | 役割 | 実行場所 |
| --- | --- | --- |
| データセット集計 | 枚数・患者数・クラス分布・画像サイズ・破損チェック | サーバ（結果の要約のみ手元へ） |
| 学習 | 設定 YAML を受け取って学習する | サーバ |
| 評価 | 学習済み run の評価・レポート生成 | サーバ |
| リモート実行 | コード送信・ジョブ実行・結果回収・GPU 空き確認 | 手元 |

コマンド名は実装時に確定し，[ENV_04 開発コマンド](../02_ENV/ENV_04_開発コマンド.md)に記載する．
