
简介目标检测是计算机视觉的核心任务之一旨在识别图像中的物体并定位其位置。其原理通常基于深度学习模型通过卷积神经网络提取特征并利用回归或分类头输出边界框和类别。这项技术在自动驾驶、安防监控和工业质检等领域具有重要价值。然而在特定应用场景如水下环境中图像常面临色彩失真、低对比度和光照不均等退化问题直接应用通用模型往往效果不佳。针对水下视觉的独特挑战需要结合图像预处理、领域自适应数据增强和模型微调等技术。本文以YOLO模型为例详细阐述了如何构建一个完整的水下目标检测系统涵盖了从环境配置、数据探索、算法对比到训练调优的全过程为相关领域的课程设计、项目开发或竞赛提供了可复现的实战指南。1. 项目缘起从竞赛到实战一个水下目标检测项目的完整闭环去年我参与指导了一个大学生创新项目核心任务是从零开始构建一套水下目标检测系统。团队最初的目标很明确参加一个知名的水下机器人视觉挑战赛。但很快我们就发现市面上大多数教程和开源项目都聚焦于清晰的陆地或通用场景一旦把模型“扔”进浑浊、低光照、色彩失真的水下环境性能就会断崖式下跌。这不仅仅是调参的问题而是从数据准备、模型选型到后处理整个流程都需要针对水下特性进行重塑。最终我们不仅完成了比赛还将整个项目沉淀为了一套包含完整源码、开发文档和算法解析的“交钥匙工程”。今天我就把这个从竞赛需求演变为可复现课程设计或项目开发的完整过程拆解开来聊聊基于Python和Jupyter Notebook如何一步步实现一个真正能用的水下目标检测算法。这个项目特别适合几类朋友一是正在寻找有挑战性课程设计或毕业设计题目的同学二是希望从经典目标检测如YOLO、SSD过渡到特定领域实战的开发者三是参加类似水下机器人、海洋观测相关竞赛急需一套可快速上手的基线系统的团队。整个过程我们将完全在Jupyter Notebook中完成从环境配置、数据探索、模型训练到可视化分析所有代码和思考过程都透明可见确保你能跟着做、跟着想最终得到属于你自己的可运行系统。2. 水下视觉的独特挑战与核心应对思路在开始写第一行代码之前我们必须先搞清楚对手是谁。水下图像检测之所以难是因为它同时受到多种物理因素的严重干扰直接套用COCO数据集上训练好的模型效果往往惨不忍睹。核心挑战主要来自三个方面。2.1 水下图像退化机理剖析首先是最棘手的色彩失真与衰减。水对光线的吸收不是均匀的红光波长最长衰减最快在几米深的水下红色通道的信息就可能几乎丢失殆尽导致图像整体偏蓝绿色。这不仅仅是颜色“不好看”的问题它直接破坏了目标物体比如红色的海星、黄色的鱼类与背景的颜色对比度特征而这些特征正是许多检测模型赖以生存的基础。其次是低对比度与模糊。水中悬浮的颗粒浮游生物、泥沙会造成严重的散射效应导致光线传播路径紊乱。这带来的直接后果是图像像蒙上了一层雾细节模糊边缘不清。对于依赖边缘和纹理信息的目标检测算法来说这无疑是致命的。最后是光照不均与伪影。水下光源如潜水灯通常是点光源会造成严重的非均匀光照画面中心亮四周暗同时容易产生光斑、镜头耀斑等伪影。这些伪影很可能被模型误检为“目标”。2.2 我们的技术路线选择预处理数据增强域适应模型面对这些挑战一个鲁棒的水下目标检测流程不能只依赖一个“更强”的检测模型。我们设计的技术路线是一个组合拳图像预处理前处理在图像送入模型之前先进行“美颜”和“去雾”。目标是部分恢复色彩、提升对比度、减少模糊。我们会重点尝试基于物理模型的方法如暗通道先验去雾在水下的变种和基于深度学习的方法如Water-Net, UIE并在Jupyter中直观对比效果。针对性的数据增强仅仅使用标准的翻转、裁剪是不够的。我们需要模拟水下环境来“制造”更多样化的训练数据。例如随机调整图像的色偏向蓝绿色偏移、添加模拟散射的模糊、合成非均匀光照效果等。这能极大地提升模型对水下退化的鲁棒性。选择合适的检测模型并进行域适应我们不会从头发明一个模型而是在成熟的检测框架如YOLOv5/v8, Faster R-CNN基础上进行微调。关键在于如何让这些在自然图像上预训练的模型“忘记”陆地的特征“记住”水下的特征。这里涉及到是否使用以及如何使用水下特定数据集进行预训练、如何设计损失函数来关注水下难样本等问题。在Jupyter Notebook中我们将把这三个环节串联起来形成一个可配置的Pipeline。你可以自由切换不同的预处理算法、增强策略和模型骨干像做实验一样对比它们对最终mAP平均精度的影响。3. 开发环境搭建与项目管理规范工欲善其事必先利其器。一个清晰、可复现的环境是项目成功的基石。我们选择Anaconda Jupyter Lab作为开发环境而不是简单的Jupyter Notebook因为Lab提供了更强大的文件管理、多标签页和扩展功能更适合中型项目。3.1 使用Conda创建隔离的Python环境在终端中执行以下命令创建一个名为underwater_detection的独立环境并指定Python版本为3.8这是一个在深度学习库中兼容性较好的版本conda create -n underwater_detection python3.8 conda activate underwater_detection接下来安装核心的科学计算和深度学习库。我们使用pip安装并利用清华镜像源加速。建议将以下内容保存为一个requirements.txt文件然后一键安装。# requirements.txt torch1.9.0 torchvision0.10.0 opencv-python4.5.3 numpy1.19.5 pandas1.3.0 matplotlib3.3.4 seaborn0.11.2 jupyterlab3.2.0 scikit-learn0.24.2 tqdm4.62.0 albumentations1.0.3 # 一个强大的数据增强库 pycocotools2.0.2 # 用于评估指标如果你的数据集是COCO格式安装命令pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple注意PyTorch的安装需要根据你的CUDA版本到官网获取对应命令。如果没有GPU使用pip install torch torchvision安装CPU版本。环境隔离能避免不同项目间的包版本冲突这是血泪教训。3.2 Jupyter Lab项目目录结构规划在Jupyter Lab中一个清晰的项目结构至关重要。我建议创建如下目录underwater_detection_project/ │ ├── data/ # 数据目录 │ ├── raw/ # 原始水下图像和标注文件如VOC格式XML │ ├── processed/ # 预处理后的图像 │ └── augmented/ # 增强后用于训练的图像 │ ├── notebooks/ # 所有的Jupyter Notebook文件 │ ├── 01_data_exploration.ipynb # 数据探索与可视化 │ ├── 02_preprocessing_experiment.ipynb # 预处理算法对比实验 │ ├── 03_augmentation_pipeline.ipynb # 数据增强流程构建 │ ├── 04_model_training_yolov5.ipynb # 模型训练以YOLOv5为例 │ └── 05_evaluation_visualization.ipynb # 评估与结果可视化 │ ├── src/ # 源代码目录可导入的Python模块 │ ├── preprocess/ # 预处理算法实现 │ ├── augmentation/ # 自定义数据增强 │ ├── models/ # 模型定义与工具函数 │ └── utils/ # 通用工具如数据加载、指标计算 │ ├── weights/ # 保存训练好的模型权重 ├── results/ # 保存训练日志、评估图表、预测结果图 └── docs/ # 项目开发文档用Markdown编写在Jupyter Lab中你可以直接在左侧文件浏览器中导航这个结构。通过将核心代码模块化在src目录下并在Notebook中使用import sys; sys.path.append(‘../src’)来导入既能保持Notebook的简洁性又能实现代码复用方便后期将项目转化为可部署的Python包。4. 水下数据获取、分析与预处理实战没有数据一切算法都是空中楼阁。水下目标检测的公开数据集相对较少常见的有URPC水下机器人抓取比赛数据集、SUIM水下场景理解数据集等。我们以URPC数据集为例它包含海参、海胆、扇贝、海星四类目标图像具有典型的水下退化特征。4.1 数据加载与缺陷可视化首先在01_data_exploration.ipynb中我们需要直观地感受数据。使用OpenCV和Matplotlib加载并显示一些样本。import cv2 import matplotlib.pyplot as plt import xml.etree.ElementTree as ET # 用于解析VOC格式标注 from pathlib import Path def plot_image_with_boxes(img_path, anno_path): img cv2.imread(str(img_path)) img_rgb cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # OpenCV默认BGR需转RGB显示 tree ET.parse(str(anno_path)) root tree.getroot() fig, ax plt.subplots(1, figsize(12, 8)) ax.imshow(img_rgb) for obj in root.findall(object): cls_name obj.find(name).text bbox obj.find(bndbox) xmin int(bbox.find(xmin).text) ymin int(bbox.find(ymin).text) xmax int(bbox.find(xmax).text) ymax int(bbox.find(ymax).text) # 绘制矩形框 rect plt.Rectangle((xmin, ymin), xmax-xmin, ymax-ymin, linewidth2, edgecolorr, facecolornone) ax.add_patch(rect) ax.text(xmin, ymin-5, cls_name, colorred, fontsize12, weightbold) plt.axis(off) plt.show() # 调用示例 sample_img Path(./data/raw/images/000001.jpg) sample_anno Path(./data/raw/annotations/000001.xml) plot_image_with_boxes(sample_img, sample_anno)通过浏览几十张图片你就能深刻体会到之前提到的色彩偏蓝绿、对比度低、模糊等问题。同时也要统计目标尺寸的分布小目标居多、类别是否均衡这些都将影响后续模型和损失函数的选择。4.2 水下图像预处理算法实现与对比在02_preprocessing_experiment.ipynb中我们实现并对比几种经典的预处理方法。这里以**直方图均衡化CLAHE和基于暗通道先验的水下图像复原UDCP**为例。CLAHE限制对比度自适应直方图均衡化它对图像分块进行直方图均衡并限制对比度能有效增强局部对比度对提升边缘清晰度有帮助但对颜色失真纠正有限。def apply_clahe(img_bgr, clip_limit2.0, tile_grid_size(8,8)): lab cv2.cvtColor(img_bgr, cv2.COLOR_BGR2LAB) l, a, b cv2.split(lab) clahe cv2.createCLAHE(clipLimitclip_limit, tileGridSizetile_grid_size) cl clahe.apply(l) merged cv2.merge((cl, a, b)) result cv2.cvtColor(merged, cv2.COLOR_LAB2BGR) return resultUDCP水下暗通道先验这是暗通道先验去雾算法在水下的改进。其核心假设是在水下图像中至少有一个颜色通道通常是红色通道在某些局部区域的强度非常低暗通道。通过估计背景光和透射率可以反演出复原图像。代码实现相对复杂涉及暗通道计算、背景光估计和软抠图等步骤。网上有开源实现我们可以将其封装在src/preprocess/udcp.py中然后在Notebook中调用。关键步骤是在同一张退化严重的图片上并行运行几种预处理算法并排显示结果。raw_img cv2.imread(‘degraded_image.jpg’) img_clahe apply_clahe(raw_img) img_udcp apply_udcp(raw_img) # 假设已实现 fig, axes plt.subplots(1, 3, figsize(18, 6)) axes[0].imshow(cv2.cvtColor(raw_img, cv2.COLOR_BGR2RGB)) axes[0].set_title(‘原始图像’) axes[1].imshow(cv2.cvtColor(img_clahe, cv2.COLOR_BGR2RGB)) axes[1].set_title(‘CLAHE处理后’) axes[2].imshow(cv2.cvtColor(img_udcp, cv2.COLOR_BGR2RGB)) axes[2].set_title(‘UDCP复原后’) for ax in axes: ax.axis(‘off’) plt.show()你需要主观评估哪种方法在颜色恢复和细节增强上更胜一筹并记录下参数。我的经验是UDCP在颜色校正上通常更优但计算量大且容易在无雾区域引入色偏CLAHE速度快能稳定提升对比度。一个实用的策略是将UDCP用于离线生成高质量训练集而将轻量的CLAHE或Gamma校正用于模型推理时的在线预处理。5. 构建面向水下的数据增强流水线经过预处理我们的图像质量有所改善但数据量可能依然有限。我们需要通过数据增强来创造更多样化的训练样本。这里我们使用albumentations库它比TorchVision的增强更丰富且支持边界框同步变换。5.1 设计水下风格的数据增强组合在03_augmentation_pipeline.ipynb中我们定义一个强化的增强流水线。除了常规的随机翻转、旋转、裁剪重点加入模拟水下退化的变换import albumentations as A from albumentations.pytorch import ToTensorV2 def get_underwater_augmentation_pipeline(target_size640): return A.Compose([ # 基础空间变换 A.RandomRotate90(p0.5), A.HorizontalFlip(p0.5), A.VerticalFlip(p0.1), # 水下目标也可能上下颠倒 A.RandomResizedCrop(heighttarget_size, widthtarget_size, scale(0.8, 1.0), p0.5), # 模拟水下色彩失真主要调整色相和饱和度向蓝绿色偏移 A.HueSaturationValue(hue_shift_limit(-20, 10), # 减少红色增加蓝绿色 sat_shift_limit(-30, 20), # 饱和度可能降低 val_shift_limit(-20, 20), p0.7), # 模拟光照不均随机亮度对比度变化并添加径向渐变暗角效果模拟水下灯光 A.RandomBrightnessContrast(brightness_limit0.2, contrast_limit0.2, p0.5), # 注Albumentations没有直接暗角变换可通过自定义或组合实现此处简化 # 模拟水下模糊运动模糊或高斯模糊 A.MotionBlur(blur_limit(3, 7), p0.3), A.GaussianBlur(blur_limit(3, 5), p0.3), # 模拟颗粒噪声水中悬浮物 A.ISONoise(color_shift(0.01, 0.05), intensity(0.1, 0.3), p0.2), # 归一化并转为Tensor A.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]), ToTensorV2(), ], bbox_paramsA.BboxParams(formatpascal_voc, label_fields[class_labels]))这个流水线会以一定的概率对输入图像施加多种水下环境特有的退化迫使模型学习到更本质的特征而不是过拟合于某种特定的清晰度或颜色分布。5.2 增强效果可视化与边界框验证定义好流水线后必须可视化检查增强效果并确保边界框的变换是正确的。transform get_underwater_augmentation_pipeline() # 加载一张图片和其标注框 image cv2.imread(‘sample.jpg’) image_rgb cv2.cvtColor(image, cv2.COLOR_BGR2RGB) bboxes [[50, 100, 200, 250, 0], [300, 150, 400, 300, 1]] # [xmin, ymin, xmax, ymax, class_id] class_labels [‘starfish’, ‘scallop’] transformed transform(imageimage_rgb, bboxesbboxes, class_labelsclass_labels) transformed_image transformed[‘image’] transformed_bboxes transformed[‘bboxes’] # 将Tensor图像转回numpy用于显示 inv_normalize transforms.Normalize(mean[-0.485/0.229, -0.456/0.224, -0.406/0.225], std[1/0.229, 1/0.224, 1/0.225]) img_to_show inv_normalize(transformed_image).permute(1,2,0).numpy() img_to_show np.clip(img_to_show, 0, 1) fig, axes plt.subplots(1, 2, figsize(12, 6)) axes[0].imshow(image_rgb) axes[0].set_title(‘原始图像’) for bbox in bboxes: rect plt.Rectangle((bbox[0], bbox[1]), bbox[2]-bbox[0], bbox[3]-bbox[1], linewidth2, edgecolor‘r’, facecolor‘none’) axes[0].add_patch(rect) axes[1].imshow(img_to_show) axes[1].set_title(‘增强后图像’) for bbox in transformed_bboxes: rect plt.Rectangle((bbox[0], bbox[1]), bbox[2]-bbox[0], bbox[3]-bbox[1], linewidth2, edgecolor‘g’, facecolor‘none’) axes[1].add_patch(rect) plt.show()这里有个坑Albumentations的边界框坐标是归一化(x_min, y_min, x_max, y_max)格式还是绝对像素值取决于BboxParams中的format。我们使用‘pascal_voc’绝对坐标要确保输入输出的框坐标范围与图像尺寸匹配。可视化这一步必不可少我曾因为格式错误导致增强后的框全部错位模型自然无法收敛。6. 模型选择、训练与调优策略有了高质量的数据我们就可以开始训练模型了。考虑到课程设计或项目开发的效率与性能平衡我强烈推荐使用YOLOv5或YOLOv8。它们社区活跃文档齐全从训练到部署的生态完善。这里以YOLOv5为例因为它完全基于PyTorch代码结构清晰易于在Jupyter中拆解和修改。6.1 在Jupyter中集成与管理YOLOv5训练流程通常YOLOv5通过命令行训练但为了更精细的控制和实验记录我们可以将其核心训练脚本集成到Jupyter中。首先克隆YOLOv5官方仓库到项目目录下或直接将其作为子模块。cd src git clone https://github.com/ultralytics/yolov5在04_model_training_yolov5.ipynb中我们并不直接运行train.py而是将其作为模块导入并手动设置参数、启动训练。这样做的好处是所有实验配置、训练曲线都可以在同一个Notebook中管理和可视化。import sys sys.path.append(‘./src/yolov5’) import torch from yolov5.utils.google_utils import attempt_download from yolov5.models.experimental import attempt_load from yolov5.utils.datasets import create_dataloader from yolov5.utils.general import colorstr, check_dataset from yolov5.utils.torch_utils import select_device from yolov5 import train # 导入训练模块 # 1. 准备数据集配置文件data.yaml data_yaml { ‘path’: ‘../data/processed/‘, ‘train’: ‘images/train‘, ‘val’: ‘images/val‘, ‘nc’: 4, # 类别数例如URPC是4类 ‘names’: [‘holothurian’, ‘echinus’, ‘scallop’, ‘starfish’] # 类别名称 } # 将字典保存为yaml文件 import yaml with open(‘../data/processed/data.yaml’, ‘w’) as f: yaml.dump(data_yaml, f) # 2. 设置训练参数模拟命令行参数 class Args: def __init__(self): self.weights ‘yolov5s.pt’ # 预训练权重 self.cfg ‘’ # 使用预训练模型不需要指定cfg self.data ‘../data/processed/data.yaml’ self.hyp ‘./src/yolov5/data/hyps/hyp.scratch-low.yaml’ # 超参数文件 self.epochs 100 self.batch_size 16 self.imgsz 640 self.device ‘0’ if torch.cuda.is_available() else ‘cpu’ self.workers 4 self.project ‘../results/train’ self.name ‘exp1’ self.exist_ok True self.resume False opt Args() # 3. 检查数据集 check_dataset(opt.data) # 4. 开始训练这里实际上调用了train.main(opt) # 为了在Notebook中更好地控制我们可以分步进行但为简洁这里直接运行 train.main(opt)运行后训练日志、模型权重、TensorBoard文件都会保存在../results/train/exp1目录下。我们可以在新的Cell中启动TensorBoard来实时监控损失和指标。%load_ext tensorboard %tensorboard --logdir ../results/train6.2 针对水下场景的关键调优点直接使用默认参数训练往往得不到最佳效果。以下是几个针对水下目标的调优方向调整锚框AnchorYOLO系列使用聚类生成的先验锚框。水下目标如海参、海胆的形状、大小分布与COCO数据集差异巨大。我们可以用自己的训练集重新聚类生成锚框。YOLOv5提供了utils/autoanchor.py脚本可以在训练前运行更新模型配置文件中的锚框尺寸。修改损失函数权重水下图像中小目标居多且边界模糊。可以尝试增加小目标损失的权重在YOLOv5的loss.py中对应box、obj、cls损失的计算或者使用Focal Loss来缓解正负样本不平衡问题。优化数据增强强度之前定义的水下增强流水线强度如模糊程度、色彩偏移范围需要根据验证集性能进行调整。过强的增强可能让模型学习到无意义的噪声过弱则起不到泛化作用。这是一个需要反复实验的过程。多尺度训练在YOLOv5的超参数文件hyp.yaml中可以设置multi_scale_training: True让模型在不同输入尺寸下训练提升对不同大小目标的检测能力这对水下场景非常有效。我的经验是对于水下目标检测数据质量预处理增强的提升往往比模型结构的微调带来的收益更大。优先把80%的精力放在数据工程上。在资源有限的情况下使用较小的模型如YOLOv5s配合强大的数据增强其效果可能优于大型模型如YOLOv5x配合普通增强。7. 模型评估、可视化分析与错误排查训练完成后我们需要客观地评估模型性能并深入分析其错误模式这是迭代改进的关键。7.1 使用标准指标与自定义可视化进行评估YOLOv5在验证时会自动计算mAP0.5、mAP0.5:0.95等指标。但我们还需要更细粒度的分析。在05_evaluation_visualization.ipynb中我们可以进行以下操作生成混淆矩阵查看模型最容易混淆哪些类别。例如是否经常把“海胆”误认为“扇贝”这可能是因为它们在模糊图像中形状相似。绘制PR曲线精确率-召回率曲线分析每个类别在不同置信度阈值下的表现。曲线下的面积就是AP值。可视化预测结果将模型在验证集上的预测框与真实框画在一起直观感受漏检、误检的情况。from yolov5.utils.plots import plot_images, output_to_target from yolov5.utils.metrics import ap_per_class, ConfusionMatrix import matplotlib.pyplot as plt # 假设我们已经有了验证数据加载器val_loader和训练好的模型model model.eval() confusion_matrix ConfusionMatrix(nc4) stats [] for batch_i, (img, targets, paths, shapes) in enumerate(val_loader): img img.to(device) targets targets.to(device) # 推理 with torch.no_grad(): preds, _ model(img) # 后处理将预测转换为与targets相同的格式 [image_id, class_id, x, y, w, h, conf] preds non_max_suppression(preds, conf_thres0.25, iou_thres0.45) for si, (pred, target) in enumerate(zip(preds, targets)): nl, npr target.shape[0], pred.shape[0] stats.append((output_to_target(pred, img.shape[2:]), target)) confusion_matrix.process_batch(pred, target) # 计算mAP stats [np.concatenate(x, 0) for x in zip(*stats)] if len(stats) and stats[0].any(): p, r, ap, f1, ap_class ap_per_class(*stats, namesmodel.names) print(f“mAP0.5: {ap[:, 0].mean():.4f}”) # 打印mAP50 # 绘制混淆矩阵 confusion_matrix.plot(save_dir‘../results/eval/‘, nameslist(data_yaml[‘names’])) plt.show()7.2 典型错误模式分析与解决方案通过可视化你可能会发现一些规律性错误漏检小目标这是水下检测最常见的问题。解决方案a) 在数据增强中减少对小目标的随机裁剪丢弃b) 使用更密集的检测头如YOLOv5的P5模型针对小目标有改进c) 在损失函数中增加小目标的权重。误检背景中的斑块水下的光斑、波纹容易被误检。解决方案a) 在训练集中增加更多包含此类干扰负样本无目标的图像b) 适当提高分类损失的权重让模型更关注类别特征而非纹理。同一目标重复检测由于水体模糊目标边界不清晰可能导致NMS非极大值抑制后仍有多个框。解决方案a) 调整NMS的IoU阈值b) 使用更先进的后处理算法如Soft-NMS或DIoU-NMS。一个实用的排查流程是在验证集上找出mAP最低的几张图片单独进行可视化分析。看看是预处理不到位还是增强过度或者是模型本身的能力瓶颈。这个过程非常像侦探破案是提升模型性能最有效的手段。8. 项目文档撰写、源码组织与扩展思路完成算法开发只是项目的一半良好的文档和代码组织能让你的工作价值倍增也便于后续的课程设计答辩或项目交付。8.1 开发文档README.md的核心要素在项目根目录的README.md文件中你需要清晰地阐述以下内容项目概述用一两句话说明这是什么项目解决了什么问题。环境依赖精确的requirements.txt或environment.yml文件。快速开始数据准备如何下载和放置数据集。数据预处理运行哪个Notebook或脚本。模型训练一行命令或一个单元格启动训练。模型评估与预测如何测试新图片或视频。项目结构用树状图展示目录说明每个文件夹的作用。算法细节简要说明采用的核心预处理方法、数据增强策略、模型架构及调优点。结果展示贴上几张在测试集上的可视化检测效果图并给出关键的评估指标如mAP。参考文献列出你参考的重要论文、代码库和数据集链接。8.2 源码组织与模块化设计回顾我们之前设计的src目录现在应该填充了内容src/preprocess/包含clahe.py,udcp.py,physical_model.py等每个文件是一个独立的预处理函数或类。src/augmentation/包含underwater_aug.py定义了我们的增强流水线。src/utils/包含dataset.py自定义数据集类、visualize.py绘图工具、metrics.py自定义评估指标。src/models/可以放置你对YOLO等模型的修改版本如更换注意力机制、修改Neck结构等。这种结构的好处是你的Jupyter Notebook会变得非常简洁主要调用这些模块并记录实验过程和结果分析。例如在训练Notebook中可能就是这样from src.augmentation.underwater_aug import get_underwater_augmentation_pipeline from src.utils.dataset import UnderwaterDataset train_dataset UnderwaterDataset(…, transformget_underwater_augmentation_pipeline())8.3 项目扩展与深入研究方向如果你希望将这个课程设计提升到一个更高的水平可以考虑以下扩展方向尝试更先进的检测模型将YOLOv5替换为YOLOv8、DETR或Swin Transformer比较它们在水下场景的优劣。探索域自适应Domain Adaptation方法如果你能获取到少量清晰的水下图像目标域和大量自然图像源域可以研究无监督域自适应方法让模型直接迁移知识减少对昂贵水下标注数据的依赖。部署到边缘设备使用ONNX、TensorRT或OpenVINO将训练好的PyTorch模型转换为高效格式部署到Jetson Nano、树莓派等嵌入式设备上实现实时水下目标检测。开发简单的图形界面GUI使用Gradio或Streamlit快速构建一个Web界面允许用户上传图片或视频实时查看检测效果这会极大提升项目的完整度和演示效果。从参加竞赛到完成一个完整的项目开发这个过程最宝贵的收获不是那个最终的mAP数字而是你独立解决一个复杂领域问题的完整方法论——从问题定义、数据分析、方案设计、实验迭代到结果呈现和文档化。这套方法论适用于你未来遇到的任何一个新的AI应用场景。本文还有配套的精品资源点击获取