ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

医学影像分析实战:ResNet、UNet、DeepLabV3+与YOLOv5技术指南

医学影像分析实战:ResNet、UNet、DeepLabV3+与YOLOv5技术指南 毕设选题拿到“医学影像分析”方向老师的建议只有一句话“用深度学习做分类、分割、检测。”但真正动手时发现网上资料要么只讲单个模型要么代码跑不通要么根本不知道 ResNet、UNet、DeepLabV3、YOLOv5 这些模型该用在哪个环节。本文围绕医学深度学习毕设的真实需求完整梳理这套多任务技术栈的概念、环境搭建、原理拆解、PyTorch 复现代码、训练注意事项和排错清单。不管你是刚开始搭环境还是已经跑通一个模型想扩展多任务都能在这篇文章里找到可以直接复用的内容。1. 医学深度学习到底在做什么三类任务和四个模型1.1 医学图像分析的三类经典任务医学影像数据非常特殊一张 CT、一张眼底照片、一张病理切片往往同时存在多种分析需求。最常见的六类任务是分类、分割、检测、配准、生成、检索。但绝大多数本科毕设和硕士课题核心都会落在前三类分类任务回答“这张图有没有病”“属于哪个亚型”。比如判断一张肺部 CT 是否有结节、一张眼底照片是否为糖尿病视网膜病变。输出的是类别标签和概率。分割任务回答“病变区域在哪些像素上”。比如把 CT 中的肺结节、脑肿瘤边缘逐像素区分出来。输出的是和原图同尺寸的掩膜mask每个像素一个类别。检测任务回答“哪里有病灶、病灶有多大”。和分割不同的是检测用边界框——矩形框——来表示目标位置更适合多个离散的小目标比如肺结节、细胞核、骨折点。为什么毕业设计喜欢用这四个模型因为它们分别对应了上面三类任务的标准解法ResNet分类任务最通用、最稳的骨干网络也经常被当作分割和检测模型的 Backbone。UNet医学分割的入门模型也是毕设中使用率最高的分割结构。DeepLabV3标题中的 DeepLabV3更强、更工程化的语义分割模型在 ISIC 皮肤病变、肺部裂片分割等任务上效果优于基础 UNet。YOLOv5检测领域的“成熟方案”训练、部署、可视化文档都非常完善适合做病灶检测。1.2 四个模型的分工与配合你在 LLM 里搜索 ResNet、UNet、DeepLabV3、YOLOv5看到的都是独立教程但在真实毕设里它们通常是配合使用的。一种常见的横向对比方案是同一份医学数据集用 ResNet 做分类用 UNet 和 DeepLabV3 分别做分割并比较结果再用 YOLOv5 做检测。这种“一个题目覆盖多模型对比”的写法评审老师最容易认可既有工作量又有对比实验。另一种是纵向多任务方案用 ResNet 做粗分类判断有没有病灶再用 UNet 或 DeepLabV3 对“有病灶”的样本做精细分割最后用 YOLOv5 把多个病灶实例框出来。三者形成完整的数据处理链路。本文按“先掌握基础再组合实战”的顺序展开最后给出一个可以改造成多任务的共享骨干网络案例。1.3 动手前必须明确的两个概念深度学习框架PyTorch 是目前医学影像领域论文复现率最高的框架不需要额外说明。它动态图机制适合反复修改网络结构医学影像调试模型时非常需要这种灵活性。预训练模型ImageNet 预训练权重可以在医学数据很少的情况下显著提升收敛速度。但不能盲目套用医学图像往往是灰度图、单通道输入形状和自然图像差异很大使用时需要把单通道复制成三通道这一点在后面代码中会体现。2. 环境准备PyTorch 与医学图像工具链2.1 版本选择原则PyTorch 的版本更新非常快不同版本的 API、CUDA 匹配关系、预训练模型接口都有差异。网上搜索时会看到类似“Python 3.10.11 PyTorch 2.8.0 CUDA 12.1 组合包”的说法但这种具体组合只适用于特定机器不能照搬到所有环境。更稳妥的原则是先查看显卡驱动支持的 CUDA 版本使用nvidia-smi查看。优先选择稳定版不要追最新版。毕设项目锁定版本不要中途随意升级。如果只是小数据集验证想法CPU 环境也能跑通一遍流程只是训练很慢。示例查看显卡信息nvidia-smi如果输出显示 NVIDIA-SMI 和 CUDA Version 为 12.x就可以安装支持 CUDA 12.1 或 12.4 的 PyTorch 版本。若不支持 NVIDIA GPU或机器上没有独立显卡则安装 CPU 版本即可本文所有代码的模型结构部分在 CPU 上也能运行。2.2 使用 Conda 创建隔离环境强烈建议不要直接往基础 Python 环境里安装深度学习包。用 Anaconda 创建独立环境避免不同项目间的依赖冲突。conda create -n medical_ai python3.10 -y conda activate medical_ai创建完成后用以下命令安装 PyTorch。以 CUDA 12.1 为例pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121如果只需要 CPU 版本pip install torch torchvision torchaudio这里要提醒一下PyTorch 官方下载源在国外国内网络不稳定时可能下载很慢或失败。可以换用清华源或阿里云源。清华源镜像 PyTorch 时要注意 URL 路径pip install torch torchvision -i https://pypi.tuna.tsinghua.edu.cn/simple不过清华源不一定覆盖cu121这种带 CUDA 后缀的专用索引地址建议优先使用官方--index-url失败时再检查网络或更换国内镜像。安装完成后在 Python 中验证import torch print(torch.__version__) print(torch.cuda.is_available())如果第二行输出True说明 PyTorch 能正常使用 GPU如果输出False说明安装的是 CPU 版本或 CUDA 配置有问题后面第 5 节会给出排查思路。2.3 常用医学图像处理库PyTorch 负责模型和训练但医学图像的读写和预处理还需要额外库。根据你的数据类型选择安装通用图像处理和可视化pip install numpy pandas matplotlib opencv-python pillow scikit-learn tqdm tensorboard医学影像专用格式NIfTI.nii.gz医院和公开数据集最常用nibabelDICOMCT、MRI 原始设备格式pydicom高光谱医学成像部分皮肤、眼底课题spectral等专用库但处理逻辑依赖具体实验这里不多展开。数据增强albumentations它内置了很多适合医学图像增强的函数例如弹性形变、光学畸变、随机亮度对比度。pip install nibabel pydicom albumentations注意nibabel和pydicom的 API 差异较大一个针对 NIfTI 的 3D/4D 数据一个针对 DICOM 的元数据与像素阵。开头先确定数据类型避免装完不知道用哪个。2.4 数据集准备建议医学毕设最怕没有数据。可以参考以下顺序选择公开数据集LUNA16、LIDC-IDRI肺结节、BraTS脑肿瘤、ISIC皮肤镜图像、DRIVE眼底血管、CHASE_DB1眼底血管。这些在论文中有据可查数据集说明可以直接写进毕设文献综述。与合作医院或导师获取脱敏数据此时必须确认数据使用协议切忌将病人隐私数据上传到公开平台。自己采集的小样本数据注意标注成本建议用一些开源标注工具辅助。无论哪种方式都需要按统一规范存放。例如dataset/ ├── images/ │ ├── patient001.png │ └── ... ├── masks/ │ ├── patient001.png │ └── ... ├── labels/ │ ├── patient001.txt │ └── ... └── data_split.csv3. 模型原理速览与最小可运行代码3.1 ResNet残差学习解决网络退化ResNet 论文提出的核心是残差结构。随着网络层数加深传统 CNN 会出现退化问题——训练集准确率反而下降。ResNet 通过跳跃连接让每一层学习残差F(x) H(x) - x理论上网络的表达能力不会低于浅层网络。在医学影像中最常用的 ResNet 版本是 ResNet50。它既可以独立做分类也是 UNet、DeepLabV3 等模型的编码器。分类头通常在最后一层全连接处改为自己的类别数。下面是一个完整的医学二分类模型示例使用 torchvision 自带预训练权重# 文件路径models/resnet_classifier.py import torch import torch.nn as nn from torchvision import models class ResNetClassifier(nn.Module): def __init__(self, num_classes2, use_pretrainedTrue): super().__init__() if use_pretrained: self.backbone models.resnet50( weightsmodels.ResNet50_Weights.IMAGENET1K_V2 ) else: self.backbone models.resnet50(weightsNone) # 把最后的全连接层替换为自定义分类头 in_features self.backbone.fc.in_features self.backbone.fc nn.Sequential( nn.Dropout(p0.3), nn.Linear(in_features, num_classes) ) self.num_classes num_classes def forward(self, x): # x 的 shape: [B, 3, H, W] return self.backbone(x)如果输入是单通道灰度医学图像比如眼底血管造影可以在数据加载时复制成三通道# 文件路径utils/grayscale_to_rgb.py import torch def gray_to_rgb(x): # x: [B, 1, H, W] return x.repeat(1, 3, 1, 1)这样就能复用 ImageNet 预训练参数。3.2 UNet编码器-解码器与跳跃连接UNet 是医学图像分割的“老前辈”结构非常直观左边是不断下采样的编码器提取语义特征右边是逐步上采样的解码器恢复空间分辨率中间用跳跃连接把编码器特征和解码器特征拼接从而保留细粒度边界信息。对于肺部结节分割、眼底血管分割这类任务UNet 依然是很好用的 baseline。下面给出最小可运行的 UNet 实现代码已经按函数拆分# 文件路径models/unet.py import torch import torch.nn as nn class DoubleConv(nn.Module): 连续两次卷积 BN ReLU def __init__(self, in_channels, out_channels): super().__init__() self.conv nn.Sequential( nn.Conv2d(in_channels, out_channels, 3, padding1), nn.BatchNorm2d(out_channels), nn.ReLU(inplaceTrue), nn.Conv2d(out_channels, out_channels, 3, padding1), nn.BatchNorm2d(out_channels), nn.ReLU(inplaceTrue), ) def forward(self, x): return self.conv(x) class Down(nn.Module): 下采样先池化再双卷积 def __init__(self, in_channels, out_channels): super().__init__() self.pool nn.MaxPool2d(2) self.conv DoubleConv(in_channels, out_channels) def forward(self, x): return self.conv(self.pool(x)) class Up(nn.Module): 上采样转置卷积 跳跃连接拼接 双卷积 def __init__(self, in_channels, out_channels): super().__init__() self.up nn.ConvTranspose2d(in_channels, in_channels // 2, kernel_size2, stride2) self.conv DoubleConv(in_channels, out_channels) def forward(self, x1, x2): x1 self.up(x1) # 处理特征图尺寸不一致的边界通常比较大的一边做中心裁剪 diffY x2.size()[2] - x1.size()[2] diffX x2.size()[3] - x1.size()[3] x1 nn.functional.pad(x1, [diffX // 2, diffX - diffX // 2, diffY // 2, diffY - diffY // 2]) x torch.cat([x2, x1], dim1) return self.conv(x) class UNet(nn.Module): def __init__(self, in_channels1, num_classes1): super().__init__() self.inc DoubleConv(in_channels, 64) self.down1 Down(64, 128) self.down2 Down(128, 256) self.down3 Down(256, 512) self.down4 Down(512, 1024) self.up1 Up(1024, 512) self.up2 Up(512, 256) self.up3 Up(256, 128) self.up4 Up(128, 64) self.outc nn.Conv2d(64, num_classes, kernel_size1) def forward(self, x): x1 self.inc(x) x2 self.down1(x1) x3 self.down2(x2) x4 self.down3(x3) x5 self.down4(x4) x self.up1(x5, x4) x self.up2(x, x3) x self.up3(x, x2) x self.up4(x, x1) logits self.outc(x) return logits使用示例if __name__ __main__: model UNet(in_channels1, num_classes1) fake_ct torch.randn(2, 1, 256, 256) mask_logit model(fake_ct) print(mask_logit.shape) # torch.Size([2, 1, 256, 256])这里num_classes1适合二值分割如果是多类别分割比如分割三种组织就需要num_classes4并配合交叉熵损失使用。3.3 DeepLabV3ASPP 与解码器结构DeepLabV3 的核心改进在于ASPPAtrous Spatial Pyramid Pooling用不同膨胀率的空洞卷积并行提取多尺度上下文信息再通过简单的解码器模块恢复边界细节。相对于 UNetDeepLabV3 在语义分割上的感受野更大分类图中的大尺度区域更稳但是参数量也更大。如果使用 torchvision最简单的方式是直接加载官方实现# 文件路径models/deeplab_model.py import torch import torch.nn as nn from torchvision import models def get_deeplab_model(num_classes1, backboneresnet50, pretrainedTrue): if backbone resnet50: weights models.DeepLabV3_ResNet50_Weights.COCO_WITH_VOC_LABELS_V1 if pretrained else None model models.segmentation.deeplabv3_resnet50(weightsweights) elif backbone mobilenet: weights models.DeepLabV3_MobileNet_V3_Large_Weights.COCO_WITH_VOC_LABELS_V1 if pretrained else None model models.segmentation.deeplabv3_mobilenet_v3_large(weightsweights) else: raise ValueError(Unsupported backbone) # 替换分类头 in_channels model.classifier[-1].in_channels model.classifier[-1] nn.Conv2d(in_channels, num_classes, kernel_size1) return model使用示例if __name__ __main__: model get_deeplab_model(num_classes1, backboneresnet50) x torch.randn(2, 3, 512, 512) out model(x)[out] print(out.shape) # torch.Size([2, 1, 512, 512])注意两个细节DeepLabV3 的输入通常要求是三通道 RGB如果是单通道 CT 等需要先复制成三通道。官方的model(x)返回 OrderedDict需要取[out]才是预测分割图这一点和普通分类模型不同新手经常漏掉。3.4 YOLOv5目标检测完整训练流程YOLOv5 的使用方式和前三个模型不太一样它本身是一个完整仓库包括数据加载、数据增强、训练、验证、导出脚本。因此复现时不需要自己手写网络结构而是 clone 官方仓库然后准备数据标注文件即可。基础流程git clone https://github.com/ultralytics/yolov5 cd yolov5 pip install -r requirements.txt使用 YOLOv5 训练自己的医学数据集需要准备每张图像对应的.txt标签文件。格式为class x_center y_center width height坐标都是相对于图像宽高的归一化值。data.yaml配置文件指向训练集、验证集的图片路径、类别数和类别名。下面是一个肺结节检测数据集的data.yaml示例# 文件路径dataset/nodule.yaml train: dataset/images/train val: dataset/images/val nc: 1 names: 0: nodule然后启动训练python train.py --data dataset/nodule.yaml --weights yolov5s.pt --epochs 100 --batch-size 16 --img 640 --device 0训练完成后在runs/train/exp*/weights/best.pt中找到最优权重接下来可以用detect.py对单张图像推理python detect.py --weights runs/train/exp/weights/best.pt --source dataset/images/val/patient001.png --conf-thres 0.25这里值得说明为什么医学检测常用 YOLOv5 而不是 YOLOv8 或 YOLOv6YOLOv5 的发展已经非常成熟网上中文资料多、针对各类自定义数据集的排错经验丰富对毕设来说它更容易“跑通”。4. 多任务医学影像实战以肺部 CT 分类 分割 检测为例4.1 任务定义与数据组织规范假设我们的毕设课题是基于肺部 CT 影像的肺结节辅助诊断系统。需要实现三个子功能分类判断一张 CT 切片是否包含肺结节。分割对包含结节的切片逐像素分割出结节区域。检测在同一张切片中框出每个可疑结节的位置。在这个设定下一张原始 CT 会同时需要类别标签0/1、分割掩膜、检测框标注。数据组织建议如下lung_dataset/ ├── images/ │ ├── patient001_slice100.png │ └── ... ├── masks/ │ ├── patient001_slice100.png │ └── ... ├── detection_labels/ │ ├── patient001_slice100.txt │ └── ... └── classification_labels.csvclassification_labels.csv可以简单写成两列image_name,label patient001_slice100.png,1 patient002_slice050.png,0这样三个任务的数据都对齐在同一张图下便于后续建立统一的数据集类。4.2 多任务共享骨干网络设计与其分别训练三个独立模型更优雅的做法是共享一个 ResNet 编码器后面接三个任务分支。这样做的好处是特征提取层被三个任务共同学习参数量更少在小数据集上更不容易过拟合毕设开题时也能体现“多任务学习”的亮点。下面给出一个简洁的多任务网络# 文件路径models/multitask_net.py import torch import torch.nn as nn from torchvision import models class MultiTaskModel(nn.Module): def __init__(self, num_classes2): super().__init__() # 共享编码器使用预训练 ResNet34 self.backbone models.resnet34(weightsmodels.ResNet34_Weights.IMAGENET1K_V1) last_channels self.backbone.fc.in_features # 删除原始全连接层保留卷积特征输出 self.encoder nn.Sequential( self.backbone.conv1, self.backbone.bn1, self.backbone.relu, self.backbone.maxpool, self.backbone.layer1, self.backbone.layer2, self.backbone.layer3, self.backbone.layer4 ) # 分类分支 self.pool nn.AdaptiveAvgPool2d((1, 1)) self.classifier nn.Linear(last_channels, num_classes) # 分割分支简单解码器 self.seg_decoder nn.Sequential( nn.ConvTranspose2d(last_channels, 128, kernel_size4, stride2, padding1), nn.ReLU(inplaceTrue), nn.ConvTranspose2d(128, 64, kernel_size4, stride2, padding1), ) def forward(self, x): feat self.encoder(x) # 分类输出 pooled self.pool(feat) pooled pooled.flatten(1) cls_out self.classifier(pooled) # 分割输出二分类掩膜 seg_out self.seg_decoder(feat) return cls_out, seg_out这个网络针对性做了一个简化输入图像尺寸为 512×512 时经过 ResNet 下采样后特征图约为 16×16分割分支经过两次转置卷积变成 64×64。如果要输出和原图一样大的掩膜还需要在解码器后加双线性上采样或更多上采样层。4.3 训练脚本与验证逻辑多任务训练的损失函数是分类损失和分割损失的加权和# 文件路径train_multitask.py import torch import torch.nn as nn from torch.utils.data import DataLoader, Dataset from models.multitask_net import MultiTaskModel import torchvision.transforms as T # 自定义数据集这里只展示核心结构 class LungDataset(Dataset): def __init__(self, img_dir, mask_dir, label_csv, transformNone): # 省略详细读取逻辑 self.img_dir img_dir self.mask_dir mask_dir self.label_csv label_csv self.transform transform def __len__(self): return len(self.img_names) def __getitem__(self, idx): img self.load_image(idx) # [3, 512, 512] mask self.load_mask(idx) # [1, 64, 64] 或 [1, 512, 512] label self.load_label(idx) # int if self.transform: img self.transform(img) return img, mask, label # 损失函数组合 def multitask_loss(cls_pred, seg_pred, mask, label, lambda_seg0.5): cls_loss nn.CrossEntropyLoss()(cls_pred, label) # 分割损失如果 mask 是二值使用 BCEWithLogitsLoss seg_loss nn.BCEWithLogitsLoss()(seg_pred, mask) return cls_loss lambda_seg * seg_loss # 训练核心逻辑 model MultiTaskModel(num_classes2) optimizer torch.optim.AdamW(model.parameters(), lr1e-4) for epoch in range(30): for img, mask, label in train_loader: optimizer.zero_grad() cls_pred, seg_pred model(img) loss multitask_loss(cls_pred, seg_pred, mask, label) loss.backward() optimizer.step() print(fepoch {epoch}, loss: {loss.item():.4f})实际训练时需要把分割分支的输出尺寸和 mask 对齐。常用的做法是先把 mask 缩放到分割分支输出的大小或者在分割分支最后加一个双线性上采样使其保持 1/8 或 1/4 分辨率。4.4 常见评价指标解读医学深度学习毕设的评价指标不同任务要用不同指标任务指标说明分类Accuracy、Sensitivity、Specificity、AUC类别不平衡时只看准确率不够更关注灵敏度和 AUC分割Dice、IoUDice 在医学分割论文中使用最多检测mAP0.5、mAP0.5:0.95、RecallYOLO 训练日志会自动输出计算 Dice 系数的最小实现# 文件路径metrics/dice.py def dice_coef(pred_mask, true_mask, smooth1e-5): pred_mask (pred_mask 0).float() true_mask true_mask.float() intersection (pred_mask * true_mask).sum() return (2.0 * intersection smooth) / (pred_mask.sum() true_mask.sum() smooth)注意很多数据集的 mask 类别分布严重不平衡比如背景占 99%结节只占 1%这种情况下 Dice 可能虚高。需要结合阳性预测值和灵敏度一起分析。5. 高频报错与排查清单5.1 环境与显存类问题现象常见原因解决思路torch.cuda.is_available()返回 False安装的是 CPU 版 PyTorch 或 CUDA 驱动不匹配卸载后重装对应 CUDA 版本的 PyTorch检查驱动CUDA out of memory图像尺寸过大、batch 太大减小 batch降低输入尺寸开启混合精度训练训练速度非常慢CPU 推理图像直接加载成 Python List使用 GPU将 Dataset 中预处理改为 Tensor使用num_workers和pin_memorypip 安装时卡住网络问题使用国内镜像或检查代理配置5.2 数据与训练类问题现象常见原因解决思路损失不下降学习率过大/过小、标签错位、输入未归一化先用小 batch 过拟合一个样本检查反向传播再调学习率分割 mask 和原图大小不一致标注尺寸与输入尺寸不统一在 Dataset 中统一 Resize 或 Padding不要每个样本单独变形检测训练时提示标签为空标注 txt 文件格式错误检查是否使用归一化坐标类别索引是否从 0 开始输出全是背景正负样本严重不均衡改用加权损失、Focal Loss或做类别平衡采样过拟合严重样本太少加大数据增强使用预训练权重减小模型复杂度5.3 模型导出类问题现象常见原因解决思路onnx 导出报错PyTorch opset 版本太旧在torch.onnx.export中设置opset_version12或更高DeepLabV3 输入尺寸无法被 8 整除ASPP 下采样要求输入为 8 的倍数修改输入尺寸或在 transform 中统一缩放模型测试时大小和训练不一致测试时 Resize 尺寸和训练不一致训练、验证、测试统一使用同一 transform这些问题的共性规律是先检查数据再检查模型最后再怀疑框架。新手容易一陷入 loss 不降就开始改网络结构实际上大部分问题都出在数据读取或者归一化上。6. 医学深度学习工程化最佳实践6.1 数据安全与合规医学数据是高敏感数据相关实践越早做越省心如果是公开数据集记录完整的数据集名称、引用出处、版本号。如果是医院提供的脱敏数据确保不含病人姓名、身份证、住院号等个人信息。不要在公有云盘或公开 GitHub 仓库中上传未脱敏的影像数据。数据标注文件与原始影像分开存放便于管理。6.2 训练稳定性建议强烈建议训练时固定随机种子保证实验可复现import random import numpy as np import torch def set_seed(seed42): random.seed(seed) np.random.seed(seed) torch.manual_seed(seed) torch.cuda.manual_seed_all(seed)此外医学影像数据增强不要照搬自然图像的那一套。比如对肺结节检测做随机裁剪是可以的但不要过度旋转避免改变解剖结构的自然方向血管分割中平移和弹性形变更实用而随机颜色变换的意义不大。6.3 模型保存与实验管理建议保存完整权重而非只保存网络结构方便后续继续训练# 保存 checkpoint torch.save({ epoch: epoch, model_state_dict: model.state_dict(), optimizer_state_dict: optimizer.state_dict(), loss: loss.item(), }, best_checkpoint.pth) # 加载 checkpoint checkpoint torch.load(best_checkpoint.pth) model.load_state_dict(checkpoint[model_state_dict]) optimizer.load_state_dict(checkpoint[optimizer_state_dict])实验管理建议使用 TensorBoardfrom torch.utils.tensorboard import SummaryWriter writer SummaryWriter(runs/exp1) writer.add_scalar(Loss/train, loss.item(), epoch) writer.add_images(Prediction, seg_pred.detach().cpu(), epoch)在医学影像项目中可视化预测结果比只记录 loss 更有意义——评审老师更关心你的模型到底把哪里分割对了、哪里漏检了。7. 总结与下一步学习路线医学深度学习毕设的核心不在“堆多新的模型”而是把数据组织好、把任务定义清楚、把 baseline 跑通再做对比与改进。ResNet、UNet、DeepLabV3、YOLOv5 这套组合能够覆盖分类、分割、检测三大任务已经足够撑起一个完整且有说服力的毕设工作。拿到这篇文章下一步可以按这个顺序推进先搭好 PyTorch 环境跑通 ResNet 分类代码掌握数据加载与训练循环。用 UNet 跑通分割流程理解 mask 的读取与损失函数。对照 DeepLabV3 和 UNet 的结果差异形成模型对比章节。最后用 YOLOv5 做检测补齐目标定位能力。当每个模型都能独立工作时再多看一眼多任务共享骨干网络方案把它作为“系统设计”的亮点写进论文整个毕设的框架就很扎实了。训练和实践过程中遇到问题优先检查数据维度、标签格式和环境配置。模型结构改不出效果时回头检查损失函数和评价指标是否选对往往比继续堆结构更有效。
返回列表