mmdetection框架下使用yolov3训练Seaships数据集

之前复现的yolov3算法采用的是传统的coco数据集,这里我需要在新的数据集上跑,也就是船舶检测方向的SeaShips数据集,这里给出教程。

Seaships论文链接:https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=8438999

一、数据集下载

可以去官网下载或者直接点击链接下载:

Seaships官网:https://github.com/jiaming-wang/SeaShips

下载链接:http://www.lmars.whu.edu.cn/prof_web/shaozhenfeng/datasets/SeaShips(7000).zip

Seaships原数据集有3万+张图像,但给出的数据集一共只有7000张,应该是经过筛选后的高质量图像。

这是论文给出的数据集中各类型的船只图像数量。

这是论文《AnenhancedCNN-enabledlearningmethodforpromotingshipdetectionin maritimesurveillance system》采用Seaships数据集进行实验的图像数量,一共是7000张。

下载完后的数据集文件夹结构应该是这样的:

一共是三个文件夹,JPEGImages里面保存的是7000张图像文件

ImageSets保存的是四个txt文件

里面分别是四种集的图像编号,如test.txt文件内容如下(部分):

Annotations里面存放的是7000张图像的标注文件:

二、数据集格式转换

YOLO系列算法采用的是coco数据集,coco数据集的标注文件格式如下:

我们可以使用下面的代码直接将Seaships数据集转换成coco数据集文件夹架构的文件:

import os
import cv2
import json
import shutil
import xml.etree.ElementTree as ET
from tqdm import tqdm# Seaships 数据集的类别
SEASHIPS_CLASSES = ('ship', 'ore carrier', 'bulk cargo carrier', 'general cargo ship', 'container ship', 'fishing boat'
)# 将类别名称映射为 COCO 格式的 category_id
label_ids = {name: i + 1 for i, name in enumerate(SEASHIPS_CLASSES)}def parse_xml(xml_path):"""解析 XML 文件,提取标注信息。"""tree = ET.parse(xml_path)root = tree.getroot()objects = []for obj in root.findall('object'):# 解析类别名称name = obj.find('name').textif name not in label_ids:print(f"警告: 未知类别 '{name}',跳过该对象。")continue# 解析 difficult 标签difficult_tag = obj.find('difficult')difficult = int(difficult_tag.text) if difficult_tag is not None else 0# 解析边界框bnd_box = obj.find('bndbox')if bnd_box is not None:bbox = [int(bnd_box.find('xmin').text),int(bnd_box.find('ymin').text),int(bnd_box.find('xmax').text),int(bnd_box.find('ymax').text)]else:print(f"警告: 在文件 {xml_path} 中未找到 <bndbox> 标签,跳过该对象。")continue# 添加到对象列表objects.append({'name': name,'label_id': label_ids[name],'difficult': difficult,'bbox': bbox})return objectsdef load_split_files(split_dir):"""加载划分文件(train.txt, val.txt, test.txt)。"""split_files = {}for split_name in ['train', 'val', 'test']:split_path = os.path.join(split_dir, f'{split_name}.txt')if os.path.exists(split_path):with open(split_path, 'r') as f:split_files[split_name] = [line.strip() for line in f.readlines()]else:print(f"警告: 未找到 {split_name}.txt 文件,跳过该划分。")split_files[split_name] = []return split_filesdef convert_to_coco(image_dir, xml_dir, split_dir, output_dir):"""将 Seaships 数据集转换为 COCO 格式,并根据划分文件划分数据集。"""# 创建输出目录os.makedirs(os.path.join(output_dir, 'annotations'), exist_ok=True)os.makedirs(os.path.join(output_dir, 'train'), exist_ok=True)os.makedirs(os.path.join(output_dir, 'val'), exist_ok=True)os.makedirs(os.path.join(output_dir, 'test'), exist_ok=True)# 加载划分文件split_files = load_split_files(split_dir)# 定义 COCO 格式的基本结构def create_coco_structure():return {"info": {"description": "Seaships Dataset","version": "1.0","year": 2023,"contributor": "Your Name","date_created": "2023-10-01"},"licenses": [],"images": [],"annotations": [],"categories": [{"id": i + 1, "name": name, "supercategory": "none"}for i, name in enumerate(SEASHIPS_CLASSES)]}# 处理每个数据集for split_name, file_names in split_files.items():coco_data = create_coco_structure()annotation_id = 1for file_name in tqdm(file_names, desc=f"处理 {split_name} 数据集"):xml_file = os.path.join(xml_dir, f'{file_name}.xml')image_name = f'{file_name}.jpg'image_path = os.path.join(image_dir, image_name)# 检查图像文件和 XML 文件是否存在if not os.path.exists(image_path):print(f"警告: 图像文件 {image_name} 不存在,跳过该标注文件。")continueif not os.path.exists(xml_file):print(f"警告: 标注文件 {xml_file} 不存在,跳过该图像文件。")continue# 读取图像尺寸image = cv2.imread(image_path)height, width, _ = image.shape# 添加图像信息image_id = len(coco_data['images']) + 1coco_data['images'].append({"id": image_id,"file_name": image_name,"width": width,"height": height})# 解析 XML 文件objects = parse_xml(xml_file)for obj in objects:xmin, ymin, xmax, ymax = obj['bbox']bbox = [xmin, ymin, xmax - xmin, ymax - ymin]  # COCO 格式的 bbox 是 [x, y, width, height]area = (xmax - xmin) * (ymax - ymin)coco_data['annotations'].append({"id": annotation_id,"image_id": image_id,"category_id": obj['label_id'],"bbox": bbox,"area": area,"iscrowd": 0,"difficult": obj['difficult']})annotation_id += 1# 复制图像文件到对应的文件夹shutil.copy(image_path, os.path.join(output_dir, split_name, image_name))# 保存 COCO 格式的标注文件with open(os.path.join(output_dir, 'annotations', f'instances_{split_name}.json'), 'w') as f:json.dump(coco_data, f, indent=4)print(f"转换完成,结果已保存到 {output_dir}")# 设置路径
image_dir = "your path to images"  # 图像文件目录
xml_dir = "your path to annotations"  # XML 标注文件目录
split_dir = "your path to txt directory"  # 划分文件目录(包含 train.txt, val.txt, test.txt)
output_dir = "your path to output directory"  # 输出的 COCO 格式文件夹# 执行转换
convert_to_coco(image_dir, xml_dir, split_dir, output_dir)

将代码保存为Seaships_to_coco.py文件。

运行以下代码进行转换:

python seaships_to_coco.py

运行完成以后生成Seaships_coco文件夹,下面包含和coco数据集相同格式的文件:

这样我们就得到了coco格式的Seaships数据集了。

三、修改配置文件

3.1 修改coco.py

将classes修改为Seaships数据集的类:

Seaships类如下六种:

'ship', 'ore carrier', 'bulk cargo carrier', 'general cargo ship', 'container ship', 'fishing boat'

3.2 修改class_names.py

同样将coco_class修改为seaships的类别:

3.3 修改需要运行的配置的文件

比如我跑的这个py文件,需要把里面所有的路径都修改成自己coco格式的seaships数据集。

把所有coco的路径都改成自己seaships数据集的路径,包括测试集、训练集等。

完整代码如下:

auto_scale_lr = dict(base_batch_size=64, enable=False)
backend_args = None
data_preprocessor = dict(bgr_to_rgb=True,mean=[0,0,0,],pad_size_divisor=32,std=[255.0,255.0,255.0,],type='DetDataPreprocessor')
data_root = 'data/SeaShips_coco/'
dataset_type = 'CocoDataset'
default_hooks = dict(checkpoint=dict(interval=7, type='CheckpointHook'),logger=dict(interval=50, type='LoggerHook'),param_scheduler=dict(type='ParamSchedulerHook'),sampler_seed=dict(type='DistSamplerSeedHook'),timer=dict(type='IterTimerHook'),visualization=dict(type='DetVisualizationHook'))
default_scope = 'mmdet'
env_cfg = dict(cudnn_benchmark=False,dist_cfg=dict(backend='nccl'),mp_cfg=dict(mp_start_method='fork', opencv_num_threads=0))
input_size = (320,320,
)
launcher = 'none'
load_from = None
log_level = 'INFO'
log_processor = dict(by_epoch=True, type='LogProcessor', window_size=50)
model = dict(backbone=dict(depth=53,init_cfg=dict(checkpoint='open-mmlab://darknet53', type='Pretrained'),out_indices=(3,4,5,),type='Darknet'),bbox_head=dict(anchor_generator=dict(base_sizes=[[(116,90,),(156,198,),(373,326,),],[(30,61,),(62,45,),(59,119,),],[(10,13,),(16,30,),(33,23,),],],strides=[32,16,8,],type='YOLOAnchorGenerator'),bbox_coder=dict(type='YOLOBBoxCoder'),featmap_strides=[32,16,8,],in_channels=[512,256,128,],loss_cls=dict(loss_weight=1.0,reduction='sum',type='CrossEntropyLoss',use_sigmoid=True),loss_conf=dict(loss_weight=1.0,reduction='sum',type='CrossEntropyLoss',use_sigmoid=True),loss_wh=dict(loss_weight=2.0, reduction='sum', type='MSELoss'),loss_xy=dict(loss_weight=2.0,reduction='sum',type='CrossEntropyLoss',use_sigmoid=True),num_classes=80,out_channels=[1024,512,256,],type='YOLOV3Head'),data_preprocessor=dict(bgr_to_rgb=True,mean=[0,0,0,],pad_size_divisor=32,std=[255.0,255.0,255.0,],type='DetDataPreprocessor'),neck=dict(in_channels=[1024,512,256,],num_scales=3,out_channels=[512,256,128,],type='YOLOV3Neck'),test_cfg=dict(conf_thr=0.005,max_per_img=100,min_bbox_size=0,nms=dict(iou_threshold=0.45, type='nms'),nms_pre=1000,score_thr=0.05),train_cfg=dict(assigner=dict(min_pos_iou=0,neg_iou_thr=0.5,pos_iou_thr=0.5,type='GridAssigner')),type='YOLOV3')
optim_wrapper = dict(clip_grad=dict(max_norm=35, norm_type=2),optimizer=dict(lr=0.001, momentum=0.9, type='SGD', weight_decay=0.0005),type='OptimWrapper')
param_scheduler = [dict(begin=0, by_epoch=False, end=2000, start_factor=0.1, type='LinearLR'),dict(by_epoch=True, gamma=0.1, milestones=[218,246,], type='MultiStepLR'),
]
resume = False
test_cfg = dict(type='TestLoop')
test_dataloader = dict(batch_size=1,dataset=dict(ann_file='annotations/instances_test.json',backend_args=None,data_prefix=dict(img='test/'),data_root='data/SeaShips_coco/',pipeline=[dict(backend_args=None, type='LoadImageFromFile'),dict(keep_ratio=True, scale=(320,320,), type='Resize'),dict(type='LoadAnnotations', with_bbox=True),dict(meta_keys=('img_id','img_path','ori_shape','img_shape','scale_factor',),type='PackDetInputs'),],test_mode=True,type='CocoDataset'),drop_last=False,num_workers=2,persistent_workers=True,sampler=dict(shuffle=False, type='DefaultSampler'))
test_evaluator = dict(ann_file='data/SeaShips_coco/annotations/instances_test.json',backend_args=None,metric='bbox',type='CocoMetric')
test_pipeline = [dict(backend_args=None, type='LoadImageFromFile'),dict(keep_ratio=True, scale=(320,320,), type='Resize'),dict(type='LoadAnnotations', with_bbox=True),dict(meta_keys=('img_id','img_path','ori_shape','img_shape','scale_factor',),type='PackDetInputs'),
]
train_cfg = dict(max_epochs=273, type='EpochBasedTrainLoop', val_interval=7)
train_dataloader = dict(batch_sampler=dict(type='AspectRatioBatchSampler'),batch_size=8,dataset=dict(ann_file='annotations/instances_train.json',backend_args=None,data_prefix=dict(img='train/'),data_root='data/SeaShips_coco/',filter_cfg=dict(filter_empty_gt=True, min_size=32),pipeline=[dict(backend_args=None, type='LoadImageFromFile'),dict(type='LoadAnnotations', with_bbox=True),dict(mean=[0,0,0,],ratio_range=(1,2,),to_rgb=True,type='Expand'),dict(min_crop_size=0.3,min_ious=(0.4,0.5,0.6,0.7,0.8,0.9,),type='MinIoURandomCrop'),dict(keep_ratio=True, scale=(320,320,), type='Resize'),dict(prob=0.5, type='RandomFlip'),dict(type='PhotoMetricDistortion'),dict(type='PackDetInputs'),],type='CocoDataset'),num_workers=4,persistent_workers=True,sampler=dict(shuffle=True, type='DefaultSampler'))
train_pipeline = [dict(backend_args=None, type='LoadImageFromFile'),dict(type='LoadAnnotations', with_bbox=True),dict(mean=[0,0,0,], ratio_range=(1,2,), to_rgb=True, type='Expand'),dict(min_crop_size=0.3,min_ious=(0.4,0.5,0.6,0.7,0.8,0.9,),type='MinIoURandomCrop'),dict(keep_ratio=True, scale=(320,320,), type='Resize'),dict(prob=0.5, type='RandomFlip'),dict(type='PhotoMetricDistortion'),dict(type='PackDetInputs'),
]
val_cfg = dict(type='ValLoop')
val_dataloader = dict(batch_size=1,dataset=dict(ann_file='annotations/instances_val.json',backend_args=None,data_prefix=dict(img='val/'),data_root='data/SeaShips_coco/',pipeline=[dict(backend_args=None, type='LoadImageFromFile'),dict(keep_ratio=True, scale=(320,320,), type='Resize'),dict(type='LoadAnnotations', with_bbox=True),dict(meta_keys=('img_id','img_path','ori_shape','img_shape','scale_factor',),type='PackDetInputs'),],test_mode=True,type='CocoDataset'),drop_last=False,num_workers=2,persistent_workers=True,sampler=dict(shuffle=False, type='DefaultSampler'))
val_evaluator = dict(ann_file='data/SeaShips_coco/annotations/instances_val.json',backend_args=None,metric='bbox',type='CocoMetric')
vis_backends = [dict(type='LocalVisBackend'),
]
visualizer = dict(name='visualizer',type='DetLocalVisualizer',vis_backends=[dict(type='LocalVisBackend'),])
work_dir = '/home/21021110287/wxz/mmdetection/work_dirs/yolo_seaships'

路径里面包含seaships的就是我自己修改过后的,大家在用的时候记得改成自己的路径即可。将该文件保存为 yolov3_seaships.py。

运行以下代码开始训练算法(验证集上跑):

python <the path to train.py> <the path to yolov3_seaships.py> --work-dir <the path to your output dirctory>

第一个路径是train.py文件的路径 第二个是刚刚保存的运行配置文件的路径,最后一个路径是自定义的输出日志保存结果的路径,如果不设置则会自动生成work_dir文件夹保存结果,命令如下:

python <the path to train.py> <the path to yolov3_seaships.py>

如果需要在测试集上跑的话还需要添加检查点文件路径:

python <the path to your test.py> <the path to yolov3_seaships.py> <the path to your pth file> --work-dir <the path to the output dirctory>

四、运行结果

运行上述命令后 我们的算法就开始跑起来了:

最终运行结果的日志文件如下:

五、Faster-RCNN

如果还想在faster-rcnn或者ssd上运行,直接选择configs文件夹下不同的配置文件修改运行命令即可

faster-rcnn可能会出现service not available的错误,则需要把运行配置文件中加载与训练模型的代码注释掉,否则没有预训练模型无法运行:

如果不想注释掉就可以按照下面的方法去下载预训练模型(即权重文件):

在python环境下输入下面命令下载模型即可:

之后找到模型文件(.pth文件),复制路径,添加到加载预训练模型的那行代码中”checkpoint=“的后面即可重新运行,这样会发现运行速度远超未加载权重的时候。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/70873.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于 Python 的网络监控系统开发全解

基于 Python 的网络监控系统开发全解 本文详细阐述如何使用 Python 开发一个网络监控系统。通过介绍系统的功能需求&#xff0c;如网络设备状态监测、流量统计、故障告警等&#xff0c;展示利用 Python 丰富的库实现这些功能的过程&#xff0c;包括scapy进行网络数据包捕获、p…

【多模态处理篇三】【DeepSeek语音合成:TTS音色克隆技术揭秘】

最近帮某明星工作室做AI语音助手时遇到魔幻需求——要求用5秒的咳嗽声克隆出完整音色!传统TTS系统直接翻车,生成的语音像得了重感冒的电音怪物。直到祭出DeepSeek的TTS音色克隆黑科技,才让AI语音从"机器朗读"进化到"声临其境"。今天我们就来扒开这个声音…

基于YOLO11深度学习的苹果叶片病害检测识别系统【python源码+Pyqt5界面+数据集+训练代码】

《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…

一篇docker从入门到精通

Docker Docker 是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实现虚拟化。容器是完全使用沙盒机制&#xff0c;相互之间不会有任何接口&#xff08;类似 iP…

w803|联盛德|WM IoT SDK2.X测试|window11|TOML 文件|外设|TFT_LCD|测试任务|(5):TFT_LCD_LVGL示例

TFT_LCD_LVGL 功能概述 此应用程序是使用 WM IoT SDK 进行 LVGL 功能的示例。它演示了如何初始化 TFT LCD 设备&#xff0c;并创建 LVGL DEMO Task 进行 LVGL 模块的初始化&#xff0c;并展示 LVGL 原生的不同 Demo 场景, 例如&#xff1a; Widgets, Music Player, Benchmark…

openlayers结合turf geojson面获取面积和中心点

在 OpenLayers 中绘制 GeoJSON 面要素并计算面积和中心点&#xff0c;可以结合 OpenLayers 的 ol/format/GeoJSON 模块将 GeoJSON 数据转换为 OpenLayers 的 Feature&#xff0c;然后使用 Turf.js 进行计算。示例代码如下 import Map from ol/Map; import View from ol/View; …

nginx 搭建 IPv6 -> IPv4 反向代理服务器

背景 在实际生产过程中&#xff0c;由于各种原因&#xff0c;我们的在线服务搭建在火山云服务器上&#xff0c;使用火山云包括 ECS、CLB、PLB 等组件进行网络通信&#xff0c;并且通过专线接受来自某公司内部流量。但是在大概 22~23 年&#xff0c;某公司要把所有网络流量变为…

FTP出现“打开 FTP 服务器上的文件夹时发生错误。请检查是否有权限访问该文件夹。”如何处理?

关闭“使用被动FTP”功能&#xff1a;在控制面板的“Internet选项”中&#xff0c;点击“高级”标签卡&#xff0c;找到“使用被动FTP&#xff08;为防火墙和DSL调制解调器兼容性&#xff09;”&#xff0c;并取消勾选124。 检查FTP服务器设置&#xff1a;确保FTP服务器没有开…

wordpress使用CorePress主题设置项总结

宝塔面板设置 软件商店中安装的软件有&#xff1a;&#xff08;宝塔网站加速3.1&#xff09;&#xff08;Nginx 1.18.0&#xff09;&#xff08;MySql 5.6.50&#xff09;&#xff08;PHP-5.6&#xff09;&#xff08;phpMyAdmin 4.4&#xff09;&#xff08;Python项目管理器 …

Oracle Redo日志损坏挽救详细攻略

一 介绍 1.1 介绍 Oracle Redo损坏分四种情况:unused状态日志损坏 inactive状态日志损坏 active状态日志损坏 current状态日志损坏。针对不同状态的日志损坏&#xff0c;处理方式有所不同&#xff0c;下面将逐一介绍。 二 恢复 2.1 unused与inactive状态日志损坏 如果这个…

003 SpringBoot集成Kafka操作

4.SpringBoot集成Kafka 文章目录 4.SpringBoot集成Kafka1.入门示例2.yml完整配置3.关键配置注释说明1. 生产者优化参数2. 消费者可靠性配置3. 监听器高级特性4. 安全认证配置 4.配置验证方法5.不同场景配置模板场景1&#xff1a;高吞吐日志收集场景2&#xff1a;金融级事务消息…

将VsCode变得顺手好用(1

目录 设置中文 配置调试功能 提效和增强相关插件 主题和图标相关插件 创建js文件 设置中文 打开【拓展】 输入【Chinese】 下载完成后重启Vs即可变为中文 配置调试功能 在随便一个位置新建一个文件夹&#xff0c;用于放置调试文件以及你未来写的代码&#xff0c;随便命名但…

1.1部署es:9200

安装es&#xff1a;root用户&#xff1a; 1.布署java环境 - 所有节点 wget https://d6.injdk.cn/oraclejdk/8/jdk-8u341-linux-x64.rpm yum localinstall jdk-8u341-linux-x64.rpm -y java -version 2.下载安装elasticsearch - 所有节点 wget ftp://10.3.148.254/Note/Elk/…

java后端开发day20--面向对象进阶(一)--static继承

&#xff08;以下内容全部来自上述课程&#xff09; 1.static–静态–共享 static表示静态&#xff0c;是java中的一个修饰符&#xff0c;可以修饰成员方法&#xff0c;成员变量。 1.静态变量 被static修饰的成员变量&#xff0c;叫做静态变量。 特点&#xff1a; 被该类…

DeepSeek本地部署+自主开发对话Web应用

文章目录 引言前端部分核心页面DeepSeek.vueMyModal.vue 后端部分WebSocketConfig 配置类AbstractDeepSeekToolDeepSeekWebSocketHandler 数据库设计总结 引言 最近DeepSeep横空出世&#xff0c;在全球内掀起一股热潮&#xff0c;到处都是满血大模型接入的应用&#xff0c;但这…

【算法】798. 差分矩阵

题目 798. 差分矩阵 思路 实质是二维差分&#xff0c;构造数组b&#xff0c;a为b的前缀和&#xff0c;也要用到前缀和的内容&#xff0c;求出数组b之后用b表示a&#xff0c;和一维差分思路类似&#xff0c;不同之处是在加减c时二维要复杂一些。 代码 #include<iostream…

MySQL企业开发中高频使用语句

以下是企业级MySQL开发中高频使用的语句分类及示例&#xff0c;结合典型业务场景说明&#xff1a; 一、数据定义&#xff08;DDL&#xff09; 表结构管理 -- 创建用户表&#xff08;含索引优化&#xff09; CREATE TABLE user (id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR…

使用DeepSeek/chatgpt等AI工具辅助网络协议流量数据包分析

随着deepseek,chatgpt等大模型的能力越来越强大&#xff0c;本文将介绍一下deepseek等LLM在分数流量数据包这方面的能力。为需要借助LLM等大模型辅助分析流量数据包的同学提供参考&#xff0c;也了解一下目前是否有必要继续学习wireshark工具以及复杂的协议知识。 pcap格式 目…

DeepSeek-R1:通过强化学习激发大语言模型的推理能力

注&#xff1a;此文章内容均节选自充电了么创始人&#xff0c;CEO兼CTO陈敬雷老师的新书《自然语言处理原理与实战》&#xff08;人工智能科学与技术丛书&#xff09;【陈敬雷编著】【清华大学出版社】 文章目录 DeepSeek大模型技术系列三DeepSeek大模型技术系列三》DeepSeek-…

基于YOLO11深度学习的医学X光骨折检测与语音提示系统【python源码+Pyqt5界面+数据集+训练代码】

《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…