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.rhkb.cn/news/24592.html

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

相关文章

方法的有关知识(含递归)

方法使用 方法就是一个 代码片段 . 类似于 C 语言中的 " 函数 " 。 方法(代码片段)定义: public class Method{ // 方法的定义public static int add(int x, int y) {return x y;} }修饰符(public static) 返回值类型 方法名称([参数类型 形参]){ 方法体代码;…

公链开发与公链生态开发:构建未来区块链世界的基石

在区块链技术日新月异的今天&#xff0c;公链&#xff08;Public Blockchain&#xff09;作为去中心化网络的核心&#xff0c;不仅为数字资产交易提供了坚实的基础&#xff0c;更推动了智能合约、去中心化应用&#xff08;DApps&#xff09;等生态系统的蓬勃发展。公链开发与公…

python+django+transformers模型:实现商品推荐功能(集成nacos配置,数据端mongo)

一、环境安装准备 #创建 虚拟运行环境python -m venv myicrplatenv#刷新source myicrplatenv/bin/activate#python Django 集成nacospip install nacos-sdk-python#安装 Djangopip3 install Django5.1#安装 pymysql settings.py 里面需要 # 强制用pymysql替代默认的MySQLdb pym…

vue3-07模拟vue3的响应式原理Proxy (代理对象)与Reflect (反射对象)

1.实现原理 通过Proxy (代理对象): 拦截对象中任意属性的变化,包括: 性值的读写、性的添加、属性的删除。通过Reflect (反射对象): 对源对象的属性进行操作。 new Proxy(data,{ // 拦截读取属性值 get (target, prop) ( return Reflect.get(target, prop) // 拦截设置属性值或…

微信小程序源码逆向 MacOS

前言 日常工作中经常会遇到对小程序的渗透测试&#xff0c;微信小程序的源码是保存在用户客户端本地&#xff0c;在渗透的过程中我们需要提取小程序的源码进行问题分析&#xff0c;本篇介绍如何在苹果电脑 MacOS 系统上提取微信小程序的源码。 0x01 微信小程序提取 在苹果电…

Python 3.12安装流程

一、下载Python安装包 访问Python官网&#xff1a;Python.org 点击 Download Python 3.12按钮&#xff08;自动识别您的操作系统&#xff09;。 二、运行安装程序 找到下载的安装文件&#xff08;如 python-3.12.3-amd64.exe&#xff09;&#xff0c;双击运行。 勾选 Add py…

【2025.2.25更新】wordpress免费AI插件,文章内容、图片自动生成、视频自动生成、网站AI客服、批量采集文章,内置deepseek联网满血版

wordpress免费AI插件&#xff0c;文章内容、文章图片、长尾关键词、视频自动生成、网站AI客服、批量采集文章&#xff0c;插件已接入腾讯云大模型知识引擎xDeepSeek&#xff0c;基于腾讯云大模型知识引擎xDeepSeek可联网满血版&#xff0c;插件可实现文章生成、长尾关键词生成、…

apache-maven-3.2.1

MAVEN_HOME D:\apache-maven-3.2.1 PATH D:\apache-maven-3.2.1\bin cmd mvn -v <localRepository>d:\localRepository</localRepository> setting.xml <?xml version"1.0" encoding"UTF-8"?><!-- Licensed to the Apache Soft…

10、C++面向对象三大特性【高频】

面向对象编程 具有 封装、继承、多态 三个主要特性 封装&#xff1a; 将属性和行为作为一个整体、一个类&#xff0c;来表现生活中的事物 将属性和行为加以权限控制&#xff0c;包括public 公共权限、protected 保护权限、private 私有权限这三种&#xff0c;从而让 自己的属性…

探索浮点数在内存中的存储(附带快速计算补码转十进制)

目录 一、浮点数在内存中的存储 1、常见的浮点数&#xff1a; 2、浮点数存储规则&#xff1a; 3、内存中无法精确存储&#xff1a; 4、移码与指数位E&#xff1a; 5、指数E的三种情况&#xff1a; 二、快速计算补码转十进制 1、第一种方法讨论&#xff1a; 2、第二种方…

Windows版FFmpeg使用及B站视频下载示例python源码

Windows版FFmpeg使用及B站视频下载示例python源码 FFmpeg介绍和下载 FFmpeg 是一个功能强大、灵活且广泛使用的多媒体处理工具&#xff0c;无论是在专业领域还是日常使用中&#xff0c;都能满足各种多媒体处理需求。FFmpeg 是一个开源项目&#xff0c;遵循 LGPL 或 GPL 许可。…

最新版 (持续更新)docker 加速源 linux yum 源

收藏两个网站&#xff0c;配置docker 加速源与yum 源。 docker 加速源链接 Docker/DockerHub 国内镜像源/加速列表&#xff08;2月25日更新-长期维护&#xff09;-腾讯云开发者社区-腾讯云https://cloud.tencent.com/developer/article/2485043 yum 源 CentOS7停服后yum源配置…

计算机三级网络技术备考(2)

#第二章关于中小型网络系统总体规划与设计方法 考点一&#xff1a;网络总体设计 考点二网络关键设备选型 考点三服务器的选型 #第三章&#xff1a;IP地址规划设计技术 考点1&#xff1a;二进制和十进制转换 小练习记得做昂 考点2&#xff1a;IP地址分类及规划方法 A类&#x…

【代码软件 | vs2019】vs2019+Qt5.12.12开发环境 的下载、安装详细介绍

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

【DeepSeek探索篇(四)】高效学习与工作,从搭建DeepSeek个人知识库开始!

高效学习与工作&#xff0c;从搭建DeepSeek个人知识库开始&#xff01; 打工人和学习者必看&#xff01;你为何急需一个个人知识库&#xff1f;搭建个人知识库需要用到哪些技术呢&#xff1f;一、模型微调与RAG技术简介二、RAG技术原理剖析 揭秘Embedding&#xff1a;为何它是D…

AI数字人系统源码部署解决方案!!!

一、开场白 如今&#xff0c;科技的步伐越来越快&#xff0c;数字人已经从想象中走进了我们的现实生活。它们在娱乐、教育、医疗等多个领域大放异彩。了解数字人的代码开发技术&#xff0c;能让我们更好地理解其工作原理&#xff0c;为那些想在这一领域大展拳脚或者用数字人技…

【网络】HTTPS协议原理

文章目录 1. HTTPS 是什么2. 常见的加密方式3. 数据摘要4. 加密方案测试4.1 只是用对称加密4.2 只使用非对称加密4.3 双方都使用非对称加密4.4 对称 非对称 5. 证书5.1 数据签名5.2 CA 证书5.3 方案五 非对称加密 对称加密 证书认证 1. HTTPS 是什么 HTTP 协议内容都是按照…

计算机网络————(三)

前文二 前文一 Websocket协议 是一种存在TCP协议之上的协议 当客户端需要了解服务器是否更新就需要不断给客户端发送请求询问是否更新&#xff0c;这行会造成服务端压力很大 而Websocket相当于服务器一旦更新了就会给客户端发送消息表明自己更新了&#xff0c;类似客户端订阅…

Blueprint —— Events

目录 一&#xff0c;Event Level Reset 二&#xff0c;Event Actor Begin Overlap 三&#xff0c;Event Actor End Overlap 四&#xff0c;Event Hit 五&#xff0c;Event Any Damage 六&#xff0c;Event Point Damage 七&#xff0c;Event Radial Damage 八&#xff…

博云先进算力管理平台AIOS已上线全尺寸DeepSeek系列模型

在异构基础设施上轻松运行全尺寸DeepSeek DeepSeek于2024年12月发布了包括 DeepSeek V3、R1、Janus Pro等多版本模型。V3版本适用于通用型自然语言处理任务&#xff0c;R1专注于复杂推理任务&#xff0c;而 Janus Pro 则擅长多模态理解与生成&#xff0c;可满足企业不同 AI 场…