MONAI(Medical Open Network for AI)是专为医学影像分析设计的开源深度学习框架,基于 PyTorch 构建,提供医疗影像专用的数据预处理、网络模块、损失函数和评估工具。以下是快速掌握 MONAI 的完整教程。
目录
安装与环境配置
# 使用 pip 安装
pip install monai
# 安装最新开发版
pip install git+https://github.com/Project-MONAI/MONAI
# 安装 CUDA 支持
pip install monai[cuda]
推荐环境
Python >= 3.7
PyTorch >= 1.8
CUDA 11.x (用于GPU加速)
NVIDIA驱动 >= 450.xx
核心设计理念
| 特性 | 说明 |
|---|---|
| 医疗影像专用 | 3D/4D影像支持、医学坐标系统 |
| 模块化架构 | 可组合的 transforms 和网络模块 |
| 分布式训练支持 | 多GPU/TPU 训练 |
| 与 ITK/ANTs 兼容 | 支持医学影像标准格式 |
| 可解释性工具 | Grad-CAM、可视化等 |
数据加载与预处理
1. 数据集定义(NIfTI 文件示例)
from monai.data import Dataset, DataLoader
from monai.transforms import LoadImaged, EnsureChannelFirstd, ScaleIntensityRanged
data = [
{"image": "path/to/image.nii.gz", "label": "path/to/label.nii.gz"}
for _ in range(10)
]
transforms = Compose([
LoadImaged(keys=["image", "label"]),
EnsureChannelFirstd(keys=["image", "label"]),
ScaleIntensityRanged(
keys=["image"],
a_min=-500,
a_max=1000,
b_min=0.0,
b_max=1.0,
clip=True
)
])
dataset = Dataset(data=data, transform=transforms)
loader = DataLoader(dataset, batch_size=2, num_workers=4)
2. 医学影像专用变换
from monai.transforms import (
Spacingd,
Orientationd,
CropForegroundd,
RandCropByPosNegLabeld
)
transforms = Compose([
LoadImaged(keys=["image", "label"]),
EnsureChannelFirstd(keys=["image", "label"]),
Spacingd( # 重采样
keys=["image", "label"],
pixdim=(1.5, 1.5, 2.0),
mode=("bilinear", "nearest")
),
Orientationd( # 标准化方向
keys=["image", "label"],
axcodes="RAS"
),
CropForegroundd( # 裁剪背景
keys=["image", "label"],
source_key="image"
)
])
网络模型构建
1. 使用内置模型
from monai.networks.nets import UNet, DenseNet121
# 3D U-Net
model = UNet(
spatial_dims=3,
in_channels=1,
out_channels=2,
channels=(16, 32, 64, 128, 256),
strides=(2, 2, 2, 2)
).to(device)
# 分类网络
model = DenseNet121(
spatial_dims=3,
in_channels=1,
out_channels=2
)
2. 自定义网络
import torch.nn as nn
from monai.networks.blocks import Convolution
class CustomModel(nn.Module):
def __init__(self):
super().__init__()
self.block = Convolution(
spatial_dims=3,
in_channels=1,
out_channels=16,
kernel_size=3,
act="RELU"
)
def forward(self, x):
return self.block(x)
训练与验证流程
1. 标准训练循环
from monai.losses import DiceLoss
from monai.metrics import DiceMetric
from monai.engines import SupervisedTrainer
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
loss_function = DiceLoss(to_onehot_y=True, softmax=True)
optimizer = torch.optim.Adam(model.parameters(), 1e-4)
metric = DiceMetric(include_background=False, reduction="mean")
trainer = SupervisedTrainer(
device=device,
max_epochs=10,
train_data_loader=loader,
network=model,
optimizer=optimizer,
loss_function=loss_function
)
2. 可视化监控(TensorBoard)
from monai.handlers import TensorBoardStatsHandler
stats_handler = TensorBoardStatsHandler(
log_dir="./runs",
writer=None,
flush_freq=10
)
trainer.handlers.append(stats_handler)
医学影像专用功能
1. 医学坐标系统
from monai.data.meta_tensor import MetaTensor
from monai.transforms.utils import create_grid
# 保留空间元数据
image_tensor = MetaTensor(image_array, affine=affine_matrix)
# 坐标转换
from monai.transforms import Orientation
transform = Orientation(axcodes="RAS")
transformed_image = transform(image_tensor)
2. 3D 可视化
from monai.visualize import plot_2d_or_3d_image
plot_2d_or_3d_image(
data=sample["image"],
step=0,
writer=None,
frame_dim=-1,
tag="input_image"
)
实战案例
1. 3D 医学图像分割
# 数据加载
from monai.data import DecathlonDataset
dataset = DecathlonDataset(
root_dir="/path/to/BraTS2021",
task="Task01_BrainTumour"
)
# 模型定义
from monai.networks.nets import UNet
model = UNet(
spatial_dims=3,
in_channels=4,
out_channels=3,
channels=(16, 32, 64, 128, 256),
strides=(2, 2, 2, 2)
)
# 损失函数
loss_function = DiceLoss(to_onehot_y=True, softmax=True)
2. 多模态分类
from monai.networks.nets import TwoStreamFusionNet
model = TwoStreamFusionNet(
modality1="MRI",
modality2="PET",
backbone="resnet18",
num_classes=2
)
注意事项
- 医学影像格式:
- 优先使用 NIfTI (.nii.gz) 或 ITK 格式
- 使用
nibabel或SimpleITK验证数据
- 内存优化:
from monai.data import CacheDataset
dataset = CacheDataset(data, transforms, cache_num=20) # 预加载缓存
- 切片方向问题:
from monai.transforms import Flip
transform = Flip(spatial_axis=2) # 根据医学坐标轴调整
- 类别不平衡处理:
loss_function = DiceLoss(
to_onehot_y=True,
softmax=True,
include_background=False
)
- 调试技巧:
- 使用
monai.utils.print_debug_info()检查环境 - 使用
torchvision.utils.make_grid()可视化中间特征
- 使用
扩展与优化
1. 分布式训练
# 启动多进程训练
torchrun --nproc_per_node=4 train.py
from monai.engines import SupervisedTrainer
from torch.nn.parallel import DistributedDataParallel
model = DistributedDataParallel(model)
2. 模型导出
from monai.export import export_onnx
export_onnx(
model=model,
inputs=[torch.randn(1, 1, 128, 128, 128)],
filename="model.onnx",
dynamic_axes={"input": {0: "batch_size"}, "output": {0: "batch_size"}}
)
总结
MONAI 的核心优势在于:
- 医学影像专用:原生支持 3D/4D 数据、医学坐标系统
- 模块化设计:可灵活组合 transforms、模型、损失函数
- 生产就绪:支持分布式训练、ONNX 导出、TensorRT 加速
- 社区支持:活跃的开源社区,持续更新医学影像最新算法
进一步学习: