Newer
Older
TIASJudgeModel / docs / 06_TEST / TEST_07_セグメンテーションの再現と判定モデルの書き出し.md

セグメンテーションの再現と判定モデルの書き出し (Segmentation Reproduction & Model Export)

TIASjudge への組み込み(Issue #9)に向けて,(1) DeepTIAS 2.7 の舌セグメンテーション(検出+ResUNet)を Python で再現して正解マスク付きデータで IoU を測り,(2) 色特徴+ロジスティック回帰の最終モデルを全データで学習して書き出した結果.引き渡し仕様は SPEC_04.

セグメンテーションの評価 (Segmentation Evaluation)

項目内容
実行日時2026-09-28 23:28〜23:34(約 5 分)
実行場所Newton の CPU(tias-remote run --cpu)
コマンドtias-seg eval --config configs/seg/eval_newton.yaml
データResUNet の開発時の正解マスク付きデータ(研究室 PC から両サーバの ~/data/TongueSegmentation/input/ に配置.ENV_03)
モデルDeepTIAS 2.7 同梱の ResUNet.onnx(開発元フォルダの ONNX とハッシュが一致)と,Detection_Normal.pb を scripts/convert_detection_to_onnx.py(tf2onnx 1.17・opset 13)で変換した Detection_Normal.onnx
コード405ab01-dirty(本ブランチの実装を未コミットのまま使用)

評価セットは,開発時に切り出し済みの画像(cropped.学習時と同じ入力条件)と,撮影画像そのもの(fullsize).fullsize では舌の枠の決め方を 3 通り比べた.

評価セット枚数枠の決め方IoU 平均中央値10 % 点最小IoU 0.8 未満1 枚の秒数
test(切り出し済み)170画像全体0.9590.9660.9260.88000.25
test_extra(切り出し済み)180画像全体0.9560.9650.9160.85800.21
train(切り出し済み.学習に使ったもの)382画像全体0.9810.9860.9650.85000.23
test(撮影画像)170検出モデル0.9580.9670.9180.86400.39
test(撮影画像)170正解マスクの外接矩形0.9470.9510.9140.86000.23
test(撮影画像)170検出なし(画像全体)0.4580.4440.2380.1031620.24
  • IoU は舌(前景)の IoU.正解マスク(JPEG)は 128 以上を前景とした.小領域除去(後処理)の有無で平均は変わらなかった(後処理が働いたのは検出なしで 42 枚,それ以外は 0〜2 枚)
  • 出力チャンネル 0 を舌として使うと IoU 0.96,チャンネル 1 を使うと 0.003〜0.04 で,チャンネル 0 が舌であることを確認した(DeepTIAS の C# の読み取りと一致)
  • 画像ごとの IoU はサーバ上の predictions.csv にだけ置き,回収していない(回収したのは集計値と IoU のヒストグラムのみ)

分かったこと (Findings)

  1. DeepTIAS の手順を Python で再現できた.撮影画像から検出モデル → ResUNet の流れで IoU 0.958(最小 0.864).DeepTIAS の開発時の報告値(ResUNet のモデル名に付いた 0.9518)と同じ水準で,切り出し済みの評価セット(0.959)とも差が無い
  2. 検出は必須.検出を省いて撮影画像全体に ResUNet を掛けると IoU 0.46 に落ちる(ResUNet は切り出し後の画像で学習されているため)
  3. 変換した検出モデルは 170 枚すべてで舌を見つけた(スコア 0.5 超).正解マスクの外接矩形よりも IoU がやや高いのは,検出の枠に余白があり,学習時の切り出し方に近いためと考えられる
  4. 1 枚あたり約 0.4 秒(Newton の CPU.検出+ResUNet+後処理).TIASjudge の手元 PC でも実用的な速さと見込まれる

注意 (Caveats)

  • DeepTIAS の細部で確かめられていない値がある(検出モデルへ渡す色の順,枠のサイズに戻したマスクの 2 値化のしきい値,輪郭の数え方の Canny のしきい値など).いずれも設定で変えられ,IoU には大きく効かないと見られるが,学習データのマスクとビット単位で一致するかは確かめていない
  • 学習データ(舌色データセット)のマスクとの一致は未確認.舌色データセットはマスク適用後の画像しか無く,元の撮影画像が無いため.元画像が残っていれば,同じ画像で DeepTIAS の出力と比べられる
  • OpenCV のバージョン(DeepTIAS は 3.x,本実装は 5.0)による resize・大津の 2 値化の微小な差はありうる

判定モデルの書き出し (Model Export)

項目内容
実行日時2026-09-28 23:26〜23:28
実行場所Archimedes の CPU
コマンドtias-train color-export --config configs/export/color_logistic_<with_mild \| without_mild>.yaml
分類器色特徴(107 次元)+ロジスティック回帰(class_weighting なし).C は全データの患者単位 5-fold(seed 42)の held_out macro F1 の平均で選ぶ
設定学習枚数採用した CC の候補ごとの fold 平均 macro F1(0.01 / 0.1 / 1 / 10 / 100)
ややあり除外754(淡白 53・淡紅 337・紅 61・暗赤紅 247・紫 56)0.10.636 / 0.669 / 0.645 / 0.602 / 0.546
ややあり込み1085(淡白 104・淡紅 337・紅 119・暗赤紅 380・紫 145)0.10.575 / 0.580 / 0.553 / 0.528 / 0.491
  • ここでの macro F1 は C を選ぶための値で,held_out にも data.severities を適用している(除外の設定では held_out にもややありが無い).評価指標としては TEST_05 の値(common macro F1 0.630〜0.644)を使う
  • 書き出した color_model.json(約 28 KB)には,特徴の定義・標準化の値・係数・切片・クラス・学習条件・来歴が入り,患者 ID・ファイル名・画像単位の値は含まない(テストで確認)
  • NumPy だけの参照実装 src/tias_judge_model/deploy/color_model.py で読み込み,学習側と同じ予測になることを確かめた(特徴はビット一致,予測確率の差は 1e-12 以下.合成データでのテスト)

次の一手 (Next Steps)

  • TIASjudge 側(TIASjudge の Issue #13)で,SPEC_04 に従って判定モードを組み込む
  • TIASjudge にはややあり除外のモデルを渡すと決めた(2026-09-29.SPEC_04「渡す判定モデル」)
  • 元の撮影画像が残っていれば,舌色データセットのマスクとの一致を確かめる

実験 ID (Run IDs)

手元の runs/ に回収済み(.gitignore 対象).

ls -d runs/20260928-232850_eval_newton_405ab01-dirty runs/*_color_logistic_*_405ab01-dirty