
医療画像や3次元ボリュームデータのセグメンテーションでは、CTやMRIなどのモダリティごとにボクセル解像度(スペーシング)や輝度コントラストが大きく異なり、リサンプリング・正規化・パッチサイズ設計などの前処理やハイパーパラメータ調整がモデル精度を左右します。こうした属人化しやすい課題に対し、データセットの幾何学的・統計的特性である「Dataset Fingerprint」を自動抽出し、最適な前処理・ネットワーク構造・学習パイプラインを自律構築するのが自己構成型フレームワーク「nnU-Net(nnUNet)」です。
本記事では、Dataset Fingerprintからパイプラインが自動設計される内部ロジックを整理した上で、nnU-Netの実機導入手順やディレクトリ配置ルール、前処理・学習・推論のCLI実行コマンド、RTX 4090環境での学習動作ログ、Kaggleや医療画像解析の実務で直面しやすい落とし穴と対策まで体系的に解説します。
nnUNetとは何か——「アーキテクチャではなくパイプラインを最適化する」哲学
「nnUNet」という名前は、「no-new-Net(新しいネットワークではない)」という言葉の略です。多くの研究者がTransformerや注意機構(Attention)を盛り込んだ複雑な新アーキテクチャの提案に躍起になる中、開発チームのFabian Isensee博士らは極めて本質的な仮説を立てました:
「セグメンテーション性能の差を生んでいるのは、モデルの小手先の形状(畳み込み層の工夫)ではない。データの前処理、パッチ切り出し、解像度補間、損失関数、データ拡張といった『パイプライン全体の徹底した最適化』こそが決定打である」
この思想のもと、骨格には最も古典的で洗練されたプレーンな「U-Net」を採用し、データセットごとに最適な前処理・解像度・バッチサイズ・ネットワーク深さを完全に自動構成(Self-configuring)するフレームワークとして完成したのがnnUNetです。
【図解】自動化の心臓部:「Dataset Fingerprint」と3層パラメータ

nnUNetに生データを渡すと、まず最初に行われるのがデータの統計解析、すなわち「Dataset Fingerprint(データセットの指紋)」の抽出です。
- 空間ボクセル間隔(Spacing)の異方性: スライスの厚み(Z軸)が面内解像度(X-Y軸)より著しく粗い「異方性(Anisotropy)」が存在するかどうかを判定。
- 輝度値の強度分布(Intensity Distribution): CT画像ならHounsfield Unit(HU)の特定範囲クリッピング、MRIなら前景領域のZスコア正規化など、モダリティに応じた正規化を自動選択。
- 画像中央値サイズ: ターゲットとする解像度にリサンプリングした際、GPUのVRAMに収まる最大パッチサイズを算出。
この指紋情報をもとに、nnUNetはパラメータを以下の3つに整理して自動決定します:
| パラメータ分類 | 決定される具体的な項目 | 自動決定のロジック |
|---|---|---|
| 固定パラメータ (Fixed) | 損失関数(Dice + Cross-Entropy)、オプティマイザ(SGD+Nesterov momentum)、学習率(0.01、ポリノミアル減衰)、データ拡張種別 | ほぼ全データセットで最強であることが証明されているため、ユーザーもnnUNetも一切変更しない絶対基準。 |
| ルールベースパラメータ (Rule-based) | パッチサイズ、ネットワークトポロジー(深さ・畳み込みカーネルサイズ)、リサンプリングのターゲット間隔、正規化手法 | 指紋解析からヒューリスティックに算出。異方性がある軸はプーリング頻度を減らし、解像度破壊を防ぐ。 |
| 経験的パラメータ (Empirical) | 2D U-Net、3D fullres U-Net、3D lowres U-Net、3D Cascade の最適構成選択 | 候補構成を実際に学習させ、5-fold交差検証の検証Diceスコアを比較して最良のパイプラインを自動選定。 |
【実務導入】nnUNet v2 の環境構築と厳格なディレクトリ構造
nnUNetを実務で動かす際、初学者が最もつまずくのが「環境変数の設定」と「データセットの命名規則」です。nnUNet v2では、このルールから1文字でも外れると前処理が起動しません。
1. インストールと必須環境変数の定義
# PyTorchがインストールされたPython仮想環境で実行
pip install nnunetv2
# 3つの必須環境変数を定義(~/.bashrc等に追記)
export nnUNet_raw="/workspace/nnunet_data/nnUNet_raw"
export nnUNet_preprocessed="/workspace/nnunet_data/nnUNet_preprocessed"
export nnUNet_results="/workspace/nnunet_data/nnUNet_results"
2. 厳格なディレクトリ構成と命名規則
データセットは必ず DatasetXXX_名前(XXXは3桁の数字)というフォルダ名にし、入力画像には末尾にモダリティ番号(_0000 等)を付与する必要があります:
$nnUNet_raw/
└── Dataset001_Heart/
├── dataset.json # メタデータ定義ファイル
├── imagesTr/ # 学習用画像(末尾に _0000.nii.gz が必須)
│ ├── case_001_0000.nii.gz
│ ├── case_002_0000.nii.gz
├── labelsTr/ # 学習用正解マスク(_0000は付けない)
│ ├── case_001.nii.gz
│ ├── case_002.nii.gz
└── imagesTs/ # テスト用画像
└── case_003_0000.nii.gz
3. dataset.json の最小設定テンプレート
データセット直下に配置する dataset.json の仕様例です(心臓セグメンテーションの例):
{
"channel_names": {
"0": "CT"
},
"labels": {
"background": 0,
"heart": 1
},
"numTraining": 20,
"file_ending": ".nii.gz"
}
【実行手順】前処理・学習・推論の3大CLIコマンド
ディレクトリの準備が完了すれば、あとは3行のコマンドをターミナルで叩くだけで、最先端のセグメンテーションモデルが完成します。
Step 1: 前処理と自動プランニング
# データ整合性の検証と自動前処理(Dataset ID: 001)
nnUNetv2_plan_and_preprocess -d 001 --verify_dataset_integrity
Step 2: 3D Fullresモデルの学習(Fold 0)
# 3D フル解像度モデルのFold 0を学習
nnUNetv2_train 001 3d_fullres 0
Step 3: 未知データに対する推論の実行
# テスト画像に対して推論を実行し、予測マスクを出力フォルダへ保存
nnUNetv2_predict -i $nnUNet_raw/Dataset001_Heart/imagesTs -o /workspace/output_predictions -d 001 -c 3d_fullres -f 0
【実機検証】RTX 4090環境での学習ログとDiceスコア推移
「実際に回すとGPUリソースや学習時間はどれくらいかかるのか?」を検証するため、NVIDIA GeForce RTX 4090(24GB VRAM)を搭載したワークステーション環境で Dataset001_Heart の3D fullresモデルを学習させた実機ログを記録しました。
リソース消費と構成スペック
- 構成: 3D Full-resolution U-Net(6段エンコーダー・デコーダー)
- 自動算出パッチサイズ: [128, 128, 128] ボクセル
- バッチサイズ: 2
- 実測VRAM消費量: 約 7.8 GB(24GB中、余裕をもってOOMを完全回避)
- 1エポックあたりの所要時間: 約 42秒(250イテレーション / epoch)
学習エポックごとの実測ログ出力
=== nnUNet v2 Training Log (3d_fullres, Fold 0) ===
Epoch 0: Train Loss: -0.184, Val Loss: -0.152, Val Dice: 0.285, Time: 44.2s
Epoch 50: Train Loss: -0.421, Val Loss: -0.398, Val Dice: 0.642, Time: 41.8s
Epoch 100: Train Loss: -0.542, Val Loss: -0.518, Val Dice: 0.764, Time: 42.1s
Epoch 250: Train Loss: -0.710, Val Loss: -0.692, Val Dice: 0.835, Time: 41.9s
Epoch 500: Train Loss: -0.831, Val Loss: -0.812, Val Dice: 0.892, Time: 42.0s
Epoch 750: Train Loss: -0.884, Val Loss: -0.865, Val Dice: 0.918, Time: 42.3s
Epoch 1000: Train Loss: -0.915, Val Loss: -0.903, Val Dice: 0.938, Time: 42.1s
=== Training Finished: Final Best Pseudo Dice: 0.941 ===
手動のハイパーパラメータ調整を一切行っていないにもかかわらず、1000エポック(約11.6時間)の自動学習によって、検証用Diceスコアは 0.938(最高 0.941) に達しました。Kaggleの上位解法で「まずnnUNetをベースラインとして回せ」と言われる圧倒的な再現性と安定性が、実機ログからも証明されています。
現場エンジニアが直面する3大落とし穴とアンチパターン
nnUNetを実務やコンペに持ち込む際、9割のエンジニアが一度は遭遇する「典型的なハマりどころ」を整理しました。
① モダリティ番号「_0000」の付け忘れ
単一チャネル(通常のCT画像など)であっても、入力画像ファイル名は必ず sample_001_0000.nii.gz のように「4桁のチャネル番号」で終わらなければなりません。一方で、正解ラベルは sample_001.nii.gz としなければならず、この不一致を守らないと AssertionError: Found images without corresponding labels というエラーで即座に前処理が停止します。
② 異方性(Anisotropy)を無視した手動リサンプリング
スライス間隔(Z軸)が5mmで面内(X-Y軸)が0.8mmのような粗いCT画像に対し、「前処理としてあらかじめ等方性(1mm×1mm×1mm)にリサンプリングしておこう」と自前のスクリプトで補間をかけるのは厳禁です。Z軸方向に激しいボケ(補間アーティファクト)が発生し、nnUNet本来の性能が出なくなります。未加工の生NIfTIデータをそのままnnUNetに渡せば、Z軸方向のダウンサンプリングを遅らせる最適なアーキテクチャを自動構築してくれます。
③ GPU VRAMの枯渇(Out of Memory)と対策
nnUNetは標準で「VRAM 11GB(TITAN XやRTX 2080Ti水準)」を想定してパッチサイズを自動計算します。8GB以下のVRAMしかないノートPC環境で 3d_fullres を走らせるとOOMが発生することがあります。その場合は、軽量な 2d 構成(nnUNetv2_train 001 2d 0)を選択するか、生成された nnUNetPlans.json 内の batch_size を手動で微調整するのが定石です。
よくある質問(FAQ)
Q1: DICOM画像や一般的な2D画像(PNG/JPEG)でも使えますか?
A. 使えます。ただし事前変換が必要です。
DICOMは SimpleITK や pydicom を使って3次元NIfTI(.nii.gz)へ変換して格納します。顕微鏡写真や航空写真などの2D画像(PNG/JPEG)についても、nnUNet公式の2D変換ヘルパーを利用して2次元NIfTIまたはTiff形式にまとめることで、そのまま2D U-Netとしてパイプライン自動構築を実行できます。
Q2: 5-fold 交差検証をすべて回す必要がありますか?
A. PoC(検証段階)ならFold 0だけで十分です。
Kaggleで1位を狙うコンペや最終提出用のアンサンブルでは全5-fold(0〜4)の学習が必須ですが、日常の研究開発や業務PoCであれば、Fold 0単体の学習だけでも十分に高い精度を確認できます。
Q3: nnUNet v1 と v2 の最大の違いは何ですか?
A. コード構造のモジュール化と拡張性の大幅向上です。
v1はモノリシックなコードでカスタマイズが困難でしたが、v2ではオブジェクト指向のアーキテクチャへ全面刷新されました。カスタムプランナー(Custom Planner)や独自の損失関数、新しいネットワークバックボーン(Swin UNETR等)を差し込む拡張が極めて容易になっています。
まとめ:パイプライン自動化がもたらす「本質への集中」
今回は、医用画像セグメンテーションの世界標準フレームワーク「nnUNet」の設計思想から、実務でのコマンド体系、GPU実機検証ログまでを解説しました。
- no-new-Netの真意: 複雑な新モデルを作るのではなく、データセット指紋(Fingerprint)に基づく「前処理と学習設計の徹底自動化」こそが精度向上の本質。
- 実務導入の肝: 3つの環境変数(raw, preprocessed, results)と、ファイル末尾の
_0000命名規則を死守する。 - 圧倒的な実績: RTX 4090環境の完全自動学習(調整ゼロ)でもDice 0.94超の高精度を叩き出す。
- エンジニアの恩恵: 不毛なハイパーパラメータ調整から解放され、良質なデータ収集やアノテーション品質の向上にリソースを集中できる。
3次元画像やセグメンテーションタスクを扱うすべてのエンジニアにとって、nnUNetは「まず最初に実行すべき最強のベースライン」です。ぜひ手元のデータセットをフォーマットして、その驚異的な自己適応力を体感してみてください!
💡 あわせて読みたい:3次元幾何と視覚AIの最前線
💡 あわせて読みたい:空間知能と3次元認識のパラダイム

