医学深度学习毕设没思路?ResNet+UNet+DeepLabV3++YOLOv5多任务实战,PyTorch完整复现!
每年毕业季,都会有一批做医学图像方向的本科生、研究生卡在同一个问题上:开题时兴致勃勃,真正动手却发现——数据不会处理,模型跑不起来,复现论文像拆盲盒,好不容易训练完还不知道怎么评估。尤其医学影像数据集普遍偏小、标注成本高、类别不平衡严重,更让初学者手足无措。
如果你现在正处于“毕设没思路”的状态,我的第一个建议是:不要一味追最新模型,先把经典模型用扎实。ResNet、UNet、DeepLabV3+、YOLOv5 这四个模型,分别覆盖了医学图像分析中最核心的分类、分割、检测三大任务。把这条主线打通,你不仅能跑通实验,还能在论文里讲出一个逻辑自洽的故事。
这篇文章会用 PyTorch 把这四个模型串起来,讲清楚每个模型解决什么问题、代码怎么写、训练时有哪些坑,以及如何把它们组合成一个完整的医学图像多任务分析流程。读完你至少能完成两件事:一是理解医学图像深度学习的常见建模套路,二是照着一套可复现的代码路径,完成自己的毕设实验框架。
1. 这篇文章真正要解决的问题
很多同学拿到医学影像课题后,第一反应是去 GitHub 找现成代码。但医学图像方向和自然图像方向有个很大的差异:数据质量、数据分布和标注方式对结果的影响,往往大于模型结构本身。
你可能遇到的情况是:
- 导师给了一个 CT / MRI / 病理切片数据集,说明是“分类任务”,但数据量只有几百张;
- 既要做病灶分割,又要做异常检测,不知道这些任务怎么组织成一个系统;
- 代码能跑,但训练 loss 不下降,或者分割结果完全没有边界;
- 不会设计实验对比,论文里只有一组结果,答辨时无从解释。
这些问题不是单独靠某个模型能解决的。你需要先建立一个整体判断:医学图像深度学习不是“选一个模型跑起来”,而是“围绕任务形式,组合模型完成分析链路”。
基于这个判断,本文规划了一条主线:
- 用ResNet做医学图像分类(例如病灶良恶性分类);
- 用UNet和DeepLabV3+做医学图像分割(例如病灶区域提取);
- 用YOLOv5做医学图像目标检测(例如细胞、器官、病灶定位);
- 把三者串联成一个多任务流程,并设计可对比的实验方案。
这条主线的好处在于:每个模型都是经过大量论文验证的经典结构,网上资料多、PyTorch 实现成熟、复现难度适中没有脱离实际;更重要的是,它们恰好能对应医学图像分析里最常用的三种问题定义方式。无论你的具体题目是肺结节、皮肤镜图像、眼底图像还是病理切片,都可以迁移这套框架。
2. 四个经典模型,分别解决什么问题
在写代码之前,先建立一个模型选型的基本认知。很多初学者把模型当成黑盒,只看精度指标,这是不够的。每个模型的结构设计,对应了它擅长的任务类型。
2.1 ResNet:图像分类的骨干网络
ResNet(残差网络)解决的核心问题是深层网络难以训练。网络层数加深后,梯度消失和退化问题会导致准确率不升反降。ResNet 通过跳跃连接(skip connection)让梯度可以跨层传播,使得几十层甚至上百层的网络也能稳定训练。
用公式表示,残差块的学习目标从拟合原始映射 H(x) 变为拟合残差 F(x)=H(x)-x。这个设计看似简单,但极大降低了深层网络的优化难度。在医学图像领域,ResNet 通常不直接单独使用,而是作为特征提取骨干网络,加载 ImageNet 预训练权重后,替换最后的全连接层来适配自己的分类任务。
对于医学毕设,ResNet 最常用的两种方式是:
- 直接用 ResNet 做二分类或多分类任务;
- 作为 UNet 的编码器、DeepLabV3+ 的骨干网络。
2.2 UNet:小样本医学分割的默认选择
UNet 是医学图像分割领域最有影响力的模型之一。它的结构是典型的编码器-解码器对称结构,左侧编码器逐层提取特征并缩小空间分辨率,右侧解码器逐步恢复分辨率,中间通过跳跃连接把同尺度的低级特征和高级语义特征拼接在一起。
这种设计对医学图像极其友好,原因有两个。第一,医学图像数据集通常很小,UNet 参数量适中,配合数据增强就能训练;第二,跳跃连接保留了边缘、纹理等细节信息,对病灶边界的分割更精确。
所以,当你面对 CT、MRI 或病理图像的分割任务时,UNet 是首选的 baseline 模型。
2.3 DeepLabV3+:基于空洞卷积的语义分割
DeepLabV3+ 与 UNet 的出发点不同。它使用空洞卷积(dilated convolution)在保持特征图分辨率的同时扩大感受野,并通过 ASPP(Atrous Spatial Pyramid Pooling)模块用不同空洞率的卷积并行提取多尺度上下文信息,最后用编码器-解码器结构恢复细节。
和 UNet 对比,DeepLabV3+ 的优势在于多尺度上下文建模能力更强。如果你的分割目标大小差异很大,或者在复杂背景下需要更强的语义信息,DeepLabV3+ 通常会优于基础版 UNet。它的劣势也一样明显:结构更复杂,对显存要求更高,在小数据集上不一定比 UNet 更容易训练。
在毕设中,更合适的做法是把 UNet 和 DeepLabV3+ 作为两条对比路线,证明你针对自己的数据特点做了模型选择的思考,而不是只跑一个模型就草草收场。
2.4 YOLOv5:单阶段目标检测的工程化标杆
YOLOv5 是目前工程落地最广泛的目标检测模型之一。它把目标检测看成回归问题,直接在图像上预测边界框和类别,不需要两阶段检测器那样生成候选区域,速度优势非常明显。
YOLOv5 在医学场景中解决的任务通常是:在一张完整切片或内窥镜图像中定位多个目标区域,例如检测细胞、息肉、器官区域。它和分割的区别在于,检测只给边界框,不给像素级掩膜;但检测速度更快,也更适合视频或实时场景。
从毕设角度来说,YOLOv5 最大的价值是工程链成熟。官方仓库提供了完整的数据准备、训练、验证、推理和导出流程,你可以把注意力集中到数据处理和实验设计上,不需要从零实现检测器。
2.5 四个模型协同工作的总体框架
可以把这四个模型的关系理解为不同分析粒度:
| 任务类型 | 代表模型 | 输出形式 | 医学典型应用 |
|---|---|---|---|
| 图像分类 | ResNet | 整图类别 | 良恶性分类、疾病分级 |
| 语义分割 | UNet / DeepLabV3+ | 每个像素的类别 | 病灶区域提取、器官分割 |
| 目标检测 | YOLOv5 | 边界框 + 类别 | 细胞检测、多病灶定位 |
| 特征提取骨干 | ResNet | 特征图 | 为分割/检测模型提供预训练权重 |
3. PyTorch 环境搭建与前置准备
不管后续代码怎么写,第一步一定是把 PyTorch 环境准备到位。这一步看似基础,但很多人在这里浪费了大量时间。
3.1 安装 Anaconda 并创建虚拟环境
强烈建议使用 Anaconda 管理 Python 环境,避免多个项目依赖互相污染。
conda create -n medical_dl python=3.9 -y conda activate medical_dlPython 版本不要盲目追求最新。PyTorch、CUDA 和 torchvision 等版本之间有对应关系,建议先确认你要安装的 PyTorch 版本所支持的 Python 版本范围,再选择 Python 3.8 或 3.9。这里用 3.9 是相对稳妥的选择。
3.2 安装 PyTorch
PyTorch 的安装方式建议从 PyTorch 官网的获取页面选择,因为 CUDA 版本和安装命令会随版本更新而变化。如果你有 NVIDIA GPU,先执行nvidia-smi查看驱动支持的 CUDA 版本,再选择对应的 PyTorch wheel。
没有 GPU 的读者也不要放弃,下面的代码在 CPU 上也能运行,只是训练时间会长一些。对于小规模医学数据集,CPU 训练一个简化版 UNet 依然是可行的。
# GPU 环境示例(具体命令以官网为准) pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118安装完成后,用下面的代码验证环境:
import torch import torchvision print("PyTorch 版本:", torch.__version__) print("torchvision 版本:", torchvision.__version__) print("CUDA 是否可用:", torch.cuda.is_available()) if torch.cuda.is_available(): print("GPU 名称:", torch.cuda.get_device_name(0))如果torch.cuda.is_available()返回 False,先检查驱动是否正常、PyTorch 的 CUDA 版本和驱动是否匹配。这是最常见的环境问题之一。
3.3 安装辅助库
除 PyTorch 外,还需要一些常用库:
pip install matplotlib numpy opencv-python pillow tqdm tensorboard如果做分割评估,建议安装医学图像领域常用的评估库,例如 monai 或 segmentation-models-pytorch。本文示例中分割模型会直接基于 PyTorch 和 segmentation-models-pytorch 来简化实现。
到这里,环境准备完成。接下来进入数据部分。
4. 医学图像数据组织与预处理
医学图像深度学习的真实瓶颈往往在数据。下面先建立一套通用的数据组织方式,后续所有模型都可以复用。
4.1 分类任务的数据目录
以二分类为例(如“正常”和“病变”),推荐目录结构如下:
data/classify/ train/ normal/ 001.jpg 002.jpg lesion/ 001.jpg val/ normal/ lesion/4.2 使用 torchvision.datasets.ImageFolder
PyTorch 的ImageFolder可以直接读取这种目录结构:
from torchvision import datasets, transforms train_transform = transforms.Compose([ transforms.Resize((256, 256)), transforms.RandomHorizontalFlip(), transforms.RandomRotation(10), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]) train_dataset = datasets.ImageFolder('data/classify/train', transform=train_transform)这里的Normalize参数使用了 ImageNet 的均值和标准差。如果使用预训练模型做迁移学习,这组参数是标准配置。
4.3 医学图像数据增强注意事项
医学图像增强要谨慎。翻转和轻微旋转通常安全,但不要随意使用强烈的颜色抖动,因为医学图像的色彩或灰度信息可能具有诊断意义。例如染色病理图像的颜色分布发生变化,可能改变组织结构的视觉特征。
如果数据集严重不平衡,可以考虑:
- 对少数类做过采样复制;
- 使用加权随机采样器
WeightedRandomSampler; - 在损失函数中设置类别权重。
5. ResNet 医学图像分类实战
分类是最基础的医学图像任务。以 ResNet50 为例,展示从加载预训练模型到训练微调的全过程。
5.1 加载预训练模型并修改分类头
import torch import torch.nn as nn from torchvision import models def create_resnet_model(num_classes, use_pretrained=True): model = models.resnet50(weights=models.ResNet50_Weights.IMAGENET1K_V1 if use_pretrained else None) # 替换最后一层全连接层 in_features = model.fc.in_features model.fc = nn.Linear(in_features, num_classes) return model model = create_resnet_model(num_classes=2)model.fc是 ResNet 最后的全连接层。替换时需要保持前面的特征提取部分不变。这样可以利用 ImageNet 上学习到的通用特征,显著减少医学小数据集上的训练难度。
5.2 冻结与解冻策略
对于小数据集,有一个常用技巧:先冻结骨干网络,只训练新替换的全连接层;训练几个 epoch 后再解冻骨干网络,用更低的学习率微调。
def freeze_backbone(model, freeze=True): for param in model.parameters(): param.requires_grad = not freeze # 最后一层始终可训练 for param in model.fc.parameters(): param.requires_grad = True这种做法的道理是:预训练模型已经学到了通用的边缘、纹理、形状特征,小数据集不足以也不应该大改这些特征,只负责把特征映射到新分类任务上。毕设实验中可以把“全量微调”“只训全连接层”“分阶段微调”做对比,本身就是一个有价值的小实验点。
5.3 训练循环
import torch.optim as optim from torch.utils.data import DataLoader device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') model = model.to(device) criterion = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=1e-4) train_loader = DataLoader(train_dataset, batch_size=16, shuffle=True, num_workers=4) def train_one_epoch(model, loader, criterion, optimizer, device): model.train() total_loss = 0.0 correct = 0 total = 0 for images, labels in loader: images, labels = images.to(device), labels.to(device) optimizer.zero_grad() outputs = model(images) loss = criterion(outputs, labels) loss.backward() optimizer.step() total_loss += loss.item() * images.size(0) _, preds = torch.max(outputs, 1) correct += (preds == labels).sum().item() total += labels.size(0) return total_loss / total, correct / total for epoch in range(10): train_loss, train_acc = train_one_epoch(model, train_loader, criterion, optimizer, device) print(f"Epoch {epoch+1}/10, Loss: {train_loss:.4f}, Acc: {train_acc:.4f}")训练完成后,验证集上评估 accuracy、precision、recall、F1。医学场景样本不平衡时,accuracy 会骗人,F1 和 AUC 更有参考价值。
6. UNet 与 DeepLabV3+ 医学图像分割实战
分割是医学图像中最有辨识度的任务。下面给出 UNet 的最小实现,以及 DeepLabV3+ 的迁移学习用法。
6.1 UNet 核心结构实现
UNet 的基本组成是双卷积块、下采样、上采样和跳跃连接。下面是基于 PyTorch 的简化实现,适合理解结构;实际实验中可以直接使用 segmentation-models-pytorch 等成熟库。
import torch import torch.nn as nn class DoubleConv(nn.Module): def __init__(self, in_ch, out_ch): super().__init__() self.conv = nn.Sequential( nn.Conv2d(in_ch, out_ch, 3, padding=1), nn.BatchNorm2d(out_ch), nn.ReLU(inplace=True), nn.Conv2d(out_ch, out_ch, 3, padding=1), nn.BatchNorm2d(out_ch), nn.ReLU(inplace=True) ) def forward(self, x): return self.conv(x) class UNet(nn.Module): def __init__(self, in_channels=3, num_classes=1, features=[64, 128, 256, 512]): super().__init__() self.downs = nn.ModuleList() self.ups = nn.ModuleList() self.pool = nn.MaxPool2d(2) # 编码器 for f in features: self.downs.append(DoubleConv(in_channels, f)) in_channels = f self.bottleneck = DoubleConv(features[-1], features[-1] * 2) # 解码器 for f in reversed(features): self.ups.append(nn.ConvTranspose2d(f * 2, f, kernel_size=2, stride=2)) self.ups.append(DoubleConv(f * 2, f)) self.final_conv = nn.Conv2d(features[0], num_classes, kernel_size=1) def forward(self, x): skip_connections = [] for down in self.downs: x = down(x) skip_connections.append(x) x = self.pool(x) x = self.bottleneck(x) skip_connections = skip_connections[::-1] for idx in range(0, len(self.ups), 2): x = self.ups[idx](x) skip = skip_connections[idx // 2] if x.shape != skip.shape: x = nn.functional.interpolate(x, size=skip.shape[2:]) x = torch.cat((skip, x), dim=1) x = self.ups[idx + 1](x) return self.final_conv(x)这个实现的核心逻辑是:编码器逐步下采样获取多尺度特征,跳跃连接把每层编码器的输出传给对应解码器,在通道维度拼接后再上采样。如果输入和跳过连接特征图尺寸不匹配,使用interpolate调整尺寸,这是实际训练时常遇到的细节问题。
6.2 分割损失函数选择
医学图像分割中,二分类任务常用 BCEWithLogitsLoss 或 DiceLoss。Dice Loss 对小目标和类别不平衡更友好:
class DiceLoss(nn.Module): def __init__(self, smooth=1.0): super().__init__() self.smooth = smooth def forward(self, pred, target): pred = torch.sigmoid(pred) pred = pred.contiguous().view(-1) target = target.contiguous().view(-1) intersection = (pred * target).sum() dice = (2.0 * intersection + self.smooth) / (pred.sum() + target.sum() + self.smooth) return 1.0 - dice多分类场景则使用 CrossEntropyLoss,但考虑加权重缓解样本不平衡。
6.3 DeepLabV3+ 迁移学习实现
不需要从零实现 DeepLabV3+ 时,可以使用 segmentation-models-pytorch 库,几行代码即可创建:
pip install segmentation-models-pytorchimport segmentation_models_pytorch as smp model = smp.DeepLabV3Plus( encoder_name="resnet50", encoder_weights="imagenet", in_channels=3, classes=1, )这里encoder_name指定骨干网络,encoder_weights加载 ImageNet 预训练权重,classes是分割类别数。这种方式把 DeepLabV3+ 的工程复杂度降到了很低,你可以把精力放在数据处理和训练调参上。
6.4 分割训练的数据加载
分割任务需要图像和掩膜一一对应。建议自定义 Dataset:
from torch.utils.data import Dataset from PIL import Image import numpy as np import os class SegDataset(Dataset): def __init__(self, image_dir, mask_dir, image_size=(256, 256)): self.image_paths = sorted([os.path.join(image_dir, f) for f in os.listdir(image_dir)]) self.mask_paths = sorted([os.path.join(mask_dir, f) for f in os.listdir(mask_dir)]) self.image_size = image_size def __len__(self): return len(self.image_paths) def __getitem__(self, idx): image = Image.open(self.image_paths[idx]).convert("RGB").resize(self.image_size) mask = Image.open(self.mask_paths[idx]).convert("L").resize(self.image_size) image = np.array(image) / 255.0 mask = np.array(mask) / 255.0 mask = (mask > 0.5).astype(np.float32) image = torch.tensor(image, dtype=torch.float32).permute(2, 0, 1) mask = torch.tensor(mask, dtype=torch.float32).unsqueeze(0) return image, mask注意:需要确保 image 和 mask 的文件名在同一语义顺序上对应,这是分割任务最容易出错的地方。训练前最好打印几个样本,可视化核对 mask 是否与图像对齐。
6.5 分割评估指标
医学分割论文最常用的指标是 Dice 系数和 IoU。计算方式建议从验证集所有样本的累计混淆矩阵计算,而不是逐图平均,这样更接近实际效果。
7. YOLOv5 医学图像检测实战
检测任务在医学图像中同样常见。使用 YOLOv5 官方仓库是最快捷的方式。
7.1 克隆仓库并安装依赖
git clone https://github.com/ultralytics/yolov5 cd yolov5 pip install -r requirements.txt这里需要注意:YOLOv5 官方仓库更新迭代较快,建议在做毕设时固定一个 release 版本,方便复现。
7.2 数据集格式准备
YOLOv5 使用 LabelImg 或 Roboflow 等工具标注后,会生成 txt 格式的标签文件。每一行表示一个目标:
class_id x_center y_center width height其中坐标都是相对图像宽高的归一化值。
数据集目录结构:
data/yolo_dataset/ images/ train/ img001.jpg val/ img002.jpg labels/ train/ img001.txt val/ img002.txt7.3 编写数据集配置 yaml
# data/medical.yaml train: data/yolo_dataset/images/train val: data/yolo_dataset/images/val nc: 2 names: ['normal_region', 'lesion_region']nc是类别数量,names是类别名称,顺序不能乱。
7.4 训练模型
python train.py --data data/medical.yaml --weights yolov5s.pt --img 640 --batch-size 16 --epochs 100 --device 0常用参数说明:
| 参数 | 含义 |
|---|---|
--weights | 预训练权重,yolov5s 是轻量版本 |
--img | 训练输入尺寸,一般取 640 |
--batch-size | 批大小,根据显存调整 |
--epochs | 训练轮数 |
--device | GPU 编号,CPU 可设为 cpu |
如果医学图像分辨率很高(例如病理切片),不建议盲目降低到 640 以下的尺寸,否则小目标容易丢失。但也要考虑显存和训练时间,可以用 640 起步做 baseline,再尝试更大尺寸。
7.5 推理与结果可视化
python detect.py --weights runs/train/exp/weights/best.pt --source data/yolo_dataset/images/val --save-txt --save-conf--save-txt保存检测框坐标,--save-conf保存置信度。可视化结果会保存在runs/detect/exp目录下。
8. 多任务串联:构建一个完整的医学图像分析流程
把分类、分割、检测三个模型串联起来,是毕设中体现系统性的关键。
一个常见的串联思路是:
- 输入一张完整医学图像;
- 用YOLOv5定位图像中的候选目标区域;
- 对每个目标区域裁剪后,用UNet / DeepLabV3+进行像素级分割,提取精确病灶边界;
- 对分割区域提取特征后,用ResNet判断病灶性质。
这种流程的设计逻辑是:检测负责“在哪里”,分割负责“边界有多准”,分类负责“这是什么”。三个模型各司其职,形成分析链路。虽然你也可以把检测和分类合并为检测模型的分类分支,但在毕设论文中拆分开来,更能体现不同方法的互补性。
多任务设计的另一个价值是可以做消融实验。论文中你可以这样设计对比:
| 方案 | 任务组合 | 预期效果 |
|---|---|---|
| A | 仅分类 | 分类准确率基线 |
| B | 检测 + 分类 | 端到端目标定位 + 分类 |
| C | 检测 + 分割 + 分类 | 完整分析链路 |
每个模型的实验结果都要记录核心指标,不仅是最终分数,还包括训练曲线、样本可视化结果和失败案例分析。
9. 常见问题与排查方法
以下表格总结了医学图像 PyTorch 实战中最常见的几类问题:
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| CUDA 不可用 | 驱动版本过低或 PyTorch CUDA 版本不匹配 | 运行 nvidia-smi,检查驱动;查看 torch.version.cuda | 根据驱动版本重装匹配的 PyTorch |
| 训练 loss 一直不下降 | 学习率过高,或数据预处理错误 | 先训练少量样本过拟合,观察 loss;检查标签是否有误 | 降低学习率,检查数据归一化与标签对齐 |
| 分割结果全黑或全白 | 损失函数不适合、mask 归一化错误 | 可视化少量预测输出,检查 sigmoid 或 softmax 是否缺失 | 统一损失函数与输出激活方式 |
| 加载预训练权重报错 | 分类头维度与新任务不一致 | 打印 model 结构,检查 fc 层输入输出 | 精确匹配 state_dict 并允许缺失或多余键 |
| 显存不足 | batch size 过大或输入尺寸过大 | 观察报错时使用的 batch 和图像尺寸 | 降低 batch size,或使用梯度累积 |
| 数据集太小导致过拟合 | 数据量不足、增强不够 | 对比训练集和验证集准确率差距 | 增加数据增强,使用迁移学习,引入 Dropout |
| 样本严重不平衡 | 少数类样本太少 | 统计类别分布 | 使用加权损失函数或过采样 |
10. 毕设实验设计与最佳实践
10.1 实验记录
从第一天开始就建立实验记录表。每跑完一组实验,记录日期、数据版本、模型、超参数、指标、备注。毕业设计后期你一定会庆幸自己有这个习惯。
推荐一个轻量级记录格式:
实验编号:exp012 时间:2025-xx-xx 模型:UNet 数据:肺结节数据集 v2(裁剪到 256x256) 预处理:只做了归一化,未做增强 超参数:lr=1e-4, batch=16, epoch=100, optimizer=Adam 结果:Dice=0.87, IoU=0.78 备注:对边缘小目标分割效果差,尝试加强旋转增强10.2 代码工程化建议
- 训练、验证、预测的三个脚本要分开,例如
train.py、val.py、infer.py; - 统一使用
argparse或 yaml 管理超参数; - 固定随机种子,确保实验可复现;
- 每个 epoch 保存 checkpoint,包含模型权重、优化器状态、epoch 数;
- 使用 TensorBoard 记录训练曲线,不用只靠 print。
10.3 数据集与合规提醒
医学图像数据涉及患者隐私,毕设中使用的数据必须确保来源合法,去除可识别患者身份的信息。使用公开数据集时,要确认数据的使用许可协议,并在论文中正确引用来源。千万不能使用未授权爬取的数据。
10.4“能跑通”和“能答辩”之间的差距
如果你只想让代码跑起来,跟着上面示例几个小时就能做到。但毕业设计真正考察的是:你能不能解释为什么选择这些模型、数据是怎么处理的、实验是怎么对照的、最终结果有什么不足以及后续怎么改进。
所以,建议你至少完成以下三步:
- 用最小数据集跑通分类、分割、检测三个基础 baseline;
- 对你的真实数据做预处理和统计,分析数据分布和难点;
- 设计至少两组对比实验,记录训练曲线和评估指标,而不是只跑出一组结果就结束。
10.5 超参数调整的一些通用经验
医学图像小数据集上,有几个经验可以参考:
- 学习率从 1e-4 起步相对稳定,比常用的 1e-3 更适合医学小数据;
- 输入分辨率比模型深度更重要,在显存允许的情况下优先保证分辨率;
- 迁移学习基本是必选项,没有预训练权重时小数据集训练效果很难保证;
- 分割任务中,Dice Loss 往往比纯 BCE Loss 更容易收敛;
- 早停(early stopping)是防止过拟合的有效手段,不要盲目把 epoch 拉到很大。
写在最后
回头再看本文开头的问题:医学深度学习毕设没思路怎么办?答案是不要把思路寄托在某一个“更好的模型”上,而是把经典模型组合成一条可解释、可验证的技术链路。ResNet、UNet、DeepLabV3+、YOLOv5 这四个模型,分别对应分类、分割、检测三大医学影像基本任务,用 PyTorch 复现并不需要多高深的技术,真正体现工作量的是数据组织、实验设计和结果分析。
下一步建议很简单:照着本文第 5、6、7 章的代码,先在自己的机器上把三个 baseline 分别跑通;然后拿出你的真实数据,完成预处理和人工标注检查;最后设计好对比实验,开始正式训练。遇到报错时,回到第 9 节的排查表逐项对照,大多数问题都可以在半小时内解决。
祝你的毕设实验顺利,答辩时能自信地讲出每个环节的设计逻辑和工程细节。