【Windows10实战】PyTorch版DeepLabV3+:从零构建自定义数据集训练全流程
1. 环境准备与工具安装在Windows10系统上搭建PyTorch开发环境其实比想象中简单。我推荐使用PyCharm作为IDE它的项目管理功能对深度学习项目特别友好。首先需要安装Python3.7或更高版本实测3.8也能完美兼容建议通过Anaconda来管理环境这样可以避免包冲突问题。安装完基础环境后关键的一步是配置GPU支持。我的GTX 2070显卡搭配CUDA 10.2和cuDNN 7.6.5运行良好。这里有个小技巧可以先通过以下命令检查PyTorch是否识别到了GPUimport torch print(torch.cuda.is_available())如果显示True说明环境配置正确。安装依赖包时常见的问题是版本冲突我建议先安装torch和torchvision的官方预编译版本pip install torch1.8.1cu102 torchvision0.9.1cu102 -f https://download.pytorch.org/whl/torch_stable.html对于DeepLabV3项目还需要额外安装opencv-python、pillow、matplotlib等常用视觉库。有个容易踩的坑是labelme的安装记得要用conda install pyqt5 pip install labelme这样能避免界面库的兼容性问题。最后建议安装一个GPU监控工具如GPU-Z训练时可以实时观察显存占用情况。2. 制作VOC格式数据集制作自定义数据集是语义分割项目最耗时的环节。我以发票识别为例详细说明整个流程。首先用labelme标注时要注意每个对象的轮廓必须闭合标注完成后会生成json文件。转换时建议使用批量处理脚本import os import json import numpy as np from PIL import Image for filename in os.listdir(annotations): if filename.endswith(.json): data json.load(open(os.path.join(annotations,filename))) mask np.zeros((data[imageHeight], data[imageWidth]), dtypenp.uint8) for shape in data[shapes]: points np.array(shape[points], dtypenp.int32) cv2.fillPoly(mask, [points], color1) # 不同类别用不同数值 Image.fromarray(mask).save(fmasks/{filename.replace(.json,.png)})VOC格式的目录结构需要特别注意JPEGImages存放原始图片(建议用jpg格式)SegmentationClass存放生成的mask图片ImageSets/Segmentation下的train.txt等文件需要手动划分数据集我通常按照7:2:1的比例划分训练集、验证集和测试集。有个实用技巧可以用shuffle后切片的方式快速生成这些文件import os import random names [f.split(.)[0] for f in os.listdir(JPEGImages)] random.shuffle(names) open(ImageSets/Segmentation/train.txt,w).write(\n.join(names[:int(0.7*len(names))]))3. 代码适配与配置修改拿到开源代码后需要进行几个关键修改。首先是mypath.py文件需要添加自定义数据集的路径class MyPath(object): staticmethod def db_root_dir(database): if database invoice: return H:/VOCdevkit/invoice # 你的数据集路径 elif database pascal: return /path/to/VOC2012 # 保持原有配置 else: raise NotImplementedError接下来是最关键的类别配置。在dataloaders/datasets/invoice.py中需要新建要修改几个核心参数class InvoiceSegmentation(data.Dataset): NUM_CLASS 2 # 背景目标类别 def __init__(self, ...): self.class_names [background, invoice] # 你的类别名称 self.mean (0.485, 0.456, 0.406) # 可能需要根据数据集调整 self.std (0.229, 0.224, 0.225)颜色映射也需要在utils.py中定义def get_invoice_labels(): return np.array([ [0, 0, 0], # 背景(黑色) [128, 0, 0] # 目标(红色) ])最后别忘了在__init__.py中注册新数据集from .datasets import pascal, invoice # 新增invoice def make_data_loader(args, **kwargs): if args.dataset pascal: ... elif args.dataset invoice: train_set invoice.InvoiceSegmentation(...) val_set invoice.InvoiceSegmentation(...)4. 模型训练与调参技巧开始训练前有几个关键参数需要特别注意。首先是backbone选择mobilenet轻量级适合快速验证(显存占用约4GB)resnet50平衡选择(显存占用约8GB)xception高精度但需要大显存(12GB)我的训练命令是这样的python train.py --dataset invoice --backbone mobilenet --lr 0.007 --workers 4 --epochs 100 --batch-size 8 --gpu-ids 0 --checkname deeplab-invoice --ft # 启用微调模式几个实用技巧学习率设置初始设为0.007每20epoch衰减0.1倍数据增强默认配置已经包含随机缩放和翻转对小数据集特别有用早停机制可以修改train.py在验证mIOU不再提升时停止训练混合精度训练添加--use-amp参数可以节省30%显存训练过程中要重点监控两个指标训练损失(train_loss)应该平稳下降mIOU(平均交并比)反映分割精度如果发现过拟合可以尝试增加数据增强添加L2正则化减小模型复杂度5. 模型测试与部署训练完成后我们需要测试模型效果。除了作者提供的验证脚本我建议自己编写可视化测试代码def visualize_prediction(image_path, model): image Image.open(image_path).convert(RGB) transform transforms.Compose([ transforms.ToTensor(), transforms.Normalize(mean(0.485, 0.456, 0.406), std(0.229, 0.224, 0.225)) ]) input_tensor transform(image).unsqueeze(0).cuda() with torch.no_grad(): output model(input_tensor) pred torch.argmax(output, 1).squeeze().cpu().numpy() # 创建彩色mask color_mask np.zeros((pred.shape[0], pred.shape[1], 3), dtypenp.uint8) color_mask[pred 1] [128, 0, 0] # 目标类别红色 # 混合显示 plt.figure(figsize(12,6)) plt.subplot(1,2,1) plt.imshow(image) plt.title(Original) plt.subplot(1,2,2) plt.imshow(color_mask) plt.title(Prediction) plt.show()对于实际部署建议将模型转换为TorchScript格式model DeepLab(num_classes2, backbonemobilenet) checkpoint torch.load(best_model.pth) model.load_state_dict(checkpoint[state_dict]) model.eval() example torch.rand(1, 3, 513, 513).cuda() traced_script torch.jit.trace(model, example) traced_script.save(deploy_model.pt)这样可以在生产环境中直接加载无需原始代码依赖。在性能较差的设备上还可以尝试模型量化quantized_model torch.quantization.quantize_dynamic( model, {torch.nn.Linear}, dtypetorch.qint8 )6. 常见问题解决在Windows平台下训练时可能会遇到几个典型问题问题1Dataloader多进程报错解决方法设置--workers 0或者添加以下代码到主程序if __name__ __main__: import multiprocessing multiprocessing.freeze_support()问题2CUDA内存不足尝试以下方案减小batch size使用更小的backbone启用梯度累积for i, (images, labels) in enumerate(train_loader): outputs model(images) loss criterion(outputs, labels) loss loss / 4 # 假设累积4次 loss.backward() if (i1) % 4 0: optimizer.step() optimizer.zero_grad()问题3标签不匹配错误检查以下几点mask图片必须是单通道PNG像素值必须从0开始连续编号0背景1类别1...确保mypath.py中的路径正确问题4训练指标波动大可能原因和解决方案学习率过高尝试减小lr并启用lr_scheduler数据分布不均检查各类别像素比例必要时添加类别权重数据增强太激进减少随机变换的强度7. 进阶优化方向当基础模型跑通后可以考虑以下几个优化方向数据层面添加难例挖掘(hard example mining)尝试半监督学习利用未标注数据使用风格迁移增强数据多样性模型层面替换更先进的backbone如EfficientNet添加注意力机制尝试不同的解码器结构训练技巧使用标签平滑(Label Smoothing)尝试不同的损失函数组合(如DiceCE)实施模型蒸馏一个实用的学习率预热实现from torch.optim.lr_scheduler import _LRScheduler class WarmupLR(_LRScheduler): def __init__(self, optimizer, warmup_steps, last_epoch-1): self.warmup_steps warmup_steps super().__init__(optimizer, last_epoch) def get_lr(self): if self.last_epoch self.warmup_steps: return [base_lr * (self.last_epoch1)/self.warmup_steps for base_lr in self.base_lrs] return self.base_lrs对于工业级应用建议添加TensorBoard日志记录from torch.utils.tensorboard import SummaryWriter writer SummaryWriter() for epoch in range(epochs): # ...训练代码... writer.add_scalar(Loss/train, loss.item(), epoch) writer.add_scalar(mIOU/val, miou, epoch) # 记录图像示例 if epoch % 10 0: writer.add_image(Prediction, color_mask, epoch, dataformatsHWC)
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2514045.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!