【终端目标检测03】nanodet训练自己的数据集、NCNN部署到Android

news2024/11/22 9:57:58

nanodet训练自己的数据集、NCNN部署到Android

    • 一、介绍
    • 二、训练自己的数据集
      • 1. 运行环境
      • 2. 数据集
      • 3. 配置文件
      • 4. 训练
      • 5. 训练可视化
      • 6. 测试
    • 三、部署到android
      • 1. 使用官方权重文件部署
        • 1.1 下载权重文件
        • 1.2 使用Android Studio部署apk
      • 2. 部署自己的模型【暂时存在问题】
        • 2.1 生成ncnn模型
        • 2.2 部署到android

一、介绍

看看作者自己的介绍吧

NanoDet-Plus 知乎中文介绍

NanoDet 知乎中文介绍

在这里插入图片描述

二、训练自己的数据集

1. 运行环境

conda create -n nanodet python=3.8 -y
conda activate nanodet

conda install pytorch torchvision cudatoolkit=11.1 -c pytorch -c conda-forge

git clone https://github.com/RangiLyu/nanodet.git
cd nanodet

pip install -r requirements.txt

python setup.py develop

2. 数据集

该示例最后使用的是coco格式的标注文件,下方提供了一个voc转coco的脚本。

import os
from tqdm import tqdm
import xml.etree.ElementTree as ET
import json
 
class_names = ["cat", "bird", "dog"]


def voc2coco(data_dir, train_path, val_path):
    xml_dir = os.path.join(data_dir, 'Annotations')
    img_dir = os.path.join(data_dir, 'JPEGImages')
     
    train_xmls = []
    for f in os.listdir(train_path):
        train_xmls.append(os.path.join(train_path, f))
    val_xmls = []
    for f in os.listdir(val_path):
        val_xmls.append(os.path.join(val_path, f))

    print('got xmls')
    train_coco = xml2coco(train_xmls)
    val_coco = xml2coco(val_xmls)
    with open(os.path.join(data_dir, 'coco_train.json'), 'w') as f:
        json.dump(train_coco, f, ensure_ascii=False, indent=2)
        json.dump(val_coco, f, ensure_ascii=False, indent=2)
    print('done')
 
 
def xml2coco(xmls):
    coco_anno = {'info': {}, 'images': [], 'licenses': [], 'annotations': [], 'categories': []}
    coco_anno['categories'] = [{'supercategory': j, 'id': i + 1, 'name': j} for i, j in enumerate(class_names)]
    img_id = 0
    anno_id = 0
    for fxml in tqdm(xmls):
        try:
            tree = ET.parse(fxml)
            objects = tree.findall('object')
        except:
            print('err xml file: ', fxml)
            continue
        if len(objects) < 1:
            print('no object in ', fxml)
            continue
        img_id += 1
        size = tree.find('size')
        ih = float(size.find('height').text)
        iw = float(size.find('width').text)
        img_name = fxml.strip().split('/')[-1].replace('xml', 'jpg')
        img_name = img_name.split('\\')
        img_name = img_name[-1]
        img_info = {}
        img_info['id'] = img_id
        img_info['file_name'] = img_name
        img_info['height'] = ih
        img_info['width'] = iw
        coco_anno['images'].append(img_info)
 
        for obj in objects:
            cls_name = obj.find('name').text
            if cls_name == "water":
                continue
            bbox = obj.find('bndbox')
            x1 = float(bbox.find('xmin').text)
            y1 = float(bbox.find('ymin').text)
            x2 = float(bbox.find('xmax').text)
            y2 = float(bbox.find('ymax').text)
            if x2 < x1 or y2 < y1:
                print('bbox not valid: ', fxml)
                continue
            anno_id += 1
            bb = [x1, y1, x2 - x1, y2 - y1]
            categery_id = class_names.index(cls_name) + 1
            area = (x2 - x1) * (y2 - y1)
            anno_info = {}
            anno_info['segmentation'] = []
            anno_info['area'] = area
            anno_info['image_id'] = img_id
            anno_info['bbox'] = bb
            anno_info['iscrowd'] = 0
            anno_info['category_id'] = categery_id
            anno_info['id'] = anno_id
            coco_anno['annotations'].append(anno_info)
 
    return coco_anno

if __name__ == '__main__':
    save_dir = './datasets/annotations' # 保存json文件的路径
    train_dir = './datasets/annotations/train/' # 训练集xml文件的存放路径
    val_dir = './datasets/annotations/val/' # 验证集xml文件的存放路径
    voc2coco(save_dir, train_dir, val_dir)

最后数据集的路径如下:

-datasets
|--images
|	|--train
|	|	|--00001.jpg
|	|	|--00004.jpg
|	|	|--...
|	|--val
|	|	|--00002.jpg
|	|	|--00003.jpg
|	|	|--...
|--annatotions
|	|--coco_train.json
|	|--coco_val.json

3. 配置文件

nanodet-m-416.yml为例,对照自己的数据集主要修改以下部分

model:
	head:
		num_classes: 3 # 数据集类别数
		
data:
  train:
    img_path: F:/datasets/images/train # 训练集图片路径
    ann_path: F:/datasets/annotations/coco_train.json # 训练集json文件路径
  val:
    img_path: F:/datasets/images/val # 验证集图片路径
    ann_path: F:/datasets/annotations/coco_val.json # 验证集json文件路径
    
device:
  gpu_ids: [0] # GPU
  workers_per_gpu: 8 # 线程数
  batchsize_per_gpu: 60 # batch size

schedule:
  total_epochs: 280 # 总epoch数
  val_intervals: 10 # 每10个epoch进行输出一次对验证集的识别结果
  
class_names: ["cat", "bird", "dog"] # 数据集类别

4. 训练

python tools/train.py config/legacy_v0.x_configs/nanodet-m-416.yml

如果训练中途断了,需要接着训练。首先修改nanodet-m-416.ymlresumeload_model这两行注释去掉,并将model_last.ckpt的路径补上(注意去掉注释后检查下这两行缩进是否正确),然后再python tools/train.py config/legacy_v0.x_configs/nanodet-m-416.yml

schedule:
  resume:
  load_model: F:/nanodet/workspace/nanodet_m_416/model_last.ckpt
  optimizer:
    name: SGD
    lr: 0.14
    momentum: 0.9
    weight_decay: 0.0001

报错:

OSError: [WinError 1455] 页面文件太小,无法完成操作。 Error loading "F:\Anaconda3\envs\
nanodet\lib\site-packages\torch\lib\shm.dll" or one of its dependencies.

方案:减小配置文件中线程数workers_per_gpu,或者直接设为0不使用并行。

5. 训练可视化

TensorBoard日志保存在./nanodet/workspace/nanodet_m_416路径下,可视化命令如下:

tensorboard --logdir=./nanodet/workspace/nanodet_m_416

在这里插入图片描述

6. 测试

方法一:

python demo/demo.py image --config config/legacy_v0.x_configs/nanodet-m-416.yml --model nanodet_m_416.ckpt --path test.jpg

方法二:

运行demo\demo-inference-with-pytorch.ipynb脚本(修改代码中from demo.demo import Predictorfrom demo import Predictor

在这里插入图片描述

三、部署到android

1. 使用官方权重文件部署

1.1 下载权重文件

1)在F:\nanodet\demo_android_ncnn\app\src\main路径下新建一个文件夹assets

2)将F:\nanodet\demo_android_ncnn\app\src\main\cpp\ncnn-20211208-android-vulkan路径下的nanodet-plus-m_416.binnanodet-plus-m_416.param复制到F:\nanodet\demo_android_ncnn\app\src\main\assets下,并重命名为nanodet.binnanodet.param

3)(可选)下载Yolov4和v5的ncnn模型到F:\nanodet\demo_android_ncnn\app\src\main\assets路径下;

在这里插入图片描述

1.2 使用Android Studio部署apk

使用Android Studio打开F:\nanodet\demo_android_ncnn文件夹,按照自己的安卓版本选择相应的Platforms,值得注意的是,NDK需要安装21.0.6113669版本的,否则会报错类似“No version of NDK matched the requested version 21.0.6113669. Versions available locally: 21.3.6528147”。【详细操作可以查看我之前的文章中的1.2节:【终端目标检测01】基于NCNN将YOLOX部署到Android】

在这里插入图片描述

部署结果:
在这里插入图片描述

2. 部署自己的模型【暂时存在问题】

2.1 生成ncnn模型
  • 先转换为onnx文件:
python tools/export_onnx.py --cfg_path config\legacy_v0.x_configs\nanodet-m-416.yml --model_path nanodet_m_416.ckpt
  • 再转换为ncnn模型:

使用在线转换https://convertmodel.com/

在这里插入图片描述

将转换后的bin和param文件放置到assets文件夹下,可以重命名为nanodet.bin和nanodet.param,也可以修改jni_interface.cpp文件中NanoDet::detector = new NanoDet(mgr, "nanodet_self-sim-opt.param", "nanodet_self-sim-opt.bin", useGPU);

2.2 部署到android

我使用的是nanodet-m-416.yml训练了自己的模型,按照官方的文档修改nanodet.h中超参数,make projectrun app都没有报错,但是手机运行程序时识别有问题(类别并不是我自己数据集的类别),暂时还没发现问题所在。

在这里插入图片描述

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

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

相关文章

2023第一届OPENAIGC开发者大赛圆满收官获奖名单公示

11月4日&#xff0c;历时两个月的「2023第一届开放AIGC开发者大赛」在苏州国际博览中心圆满收官。本次大赛以“AI生成未来”为主题&#xff0c;旨在寻找并推动中国大模型、AIGC领域的创新人才和前沿技术应用。云集来自各大行业与领域的企业、高校等323支优秀团队&#xff0c;共…

记录访问http链接,刷新页面会自动转到https问题

解决方法 点击地址栏前边小锁的标识&#xff0c;会弹出窗口&#xff0c;选择网站设置&#xff0c;然后找到左边”隐私与安全“选项卡下的”不安全内容“选项&#xff0c;默认的选项是”屏蔽&#xff08;默认&#xff09;“&#xff0c;改成”允许“。

OSPF下的MGRE实验

一、实验要求 1、R1-R3-R4构建全连的MGRE环境 2、R1-R5-R6建立hub-spoke的MGRE环境&#xff0c;其中R1为中心 3、R1-R3...R6均存在环回网段模拟用户私网&#xff0c;使用OSPF使全网可达 4、其中R2为ISP路由器&#xff0c;仅配置IP地址 二、实验拓扑图 三、实验配置 1、给各路…

国内MES系统应用研究报告 | MES系统如何选型?

随着制造企业数字化转型需求的增强&#xff0c;工业软件的需求也不断被激发。 2022年&#xff0c;中国MES软件&#xff08;制造执行系统&#xff09;及服务市场规模实现23.8%的较高速增长。同时&#xff0c;随着工业互联网、MOM的兴起和不断发展&#xff0c;也推动着MES持续发…

宠物商城系统

源码下载地址 支持&#xff1a;远程部署/安装/调试、讲解、二次开发/修改/定制 宠物商城系统&#xff0c;支持登录、注册、浏览、搜索、详情页、加入购物车。比较简单

怎样选择文件外发控制系统,让数据实现高效安全交换?

制造型企业都非常重视其知识产权&#xff08;IP&#xff09;的安全性&#xff0c;尤其是其最有价值的产品设计数据的安全问题。基于复杂的供应链生态&#xff0c;每天可能要与几十家甚至上百家供应商及合作伙伴进行数据交换。不管是一级还是二级供应商&#xff0c;合作伙伴还是…

大华同轴电缆低时延监控方案300ms

1.具体的方案如下&#xff1a; 同轴电缆可以最长支持500米&#xff0c;8路视频流&#xff0c;原始视频流 产品型号&#xff1a;DH-HAC-HFW2401M-I1 和 DH/HCVR7104HS-V6 京东的上宣称实时&#xff1a; 2.时延具体参数 找技术厂家咨询了具体的时延参数&#xff0c;厂家说无法…

【文末送书】博客模板

【点我-这里送书】 本人详解 作者&#xff1a;王文峰&#xff0c;参加过 CSDN 2020年度博客之星&#xff0c;《Java王大师王天师》 公众号&#xff1a;JAVA开发王大师&#xff0c;专注于天道酬勤的 Java 开发问题中国国学、传统文化和代码爱好者的程序人生&#xff0c;期待你的…

halcon快速傅里叶变换

说明 低频特征是灰度变化不明显&#xff0c;例如图像整体轮廓&#xff0c;高频特征是图像灰度变化剧烈&#xff0c;如图像边缘和噪声。一个重要的经验结论&#xff1a;低频代表图像整体轮廓&#xff0c;高频代表了图像噪声&#xff0c;中频代表图像边缘、纹理等细节。 傅里叶变…

经典矩阵试题(一)

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 文章目录 一、回型矩阵1、题目介绍2、思路讲解3、代码实现4、结果 二、蛇型矩阵1、题目介绍2、思路讲解…

免费获取阿里ACA云助理考试卷

请查收你的第一张上云证书 免费考取8个 ACA认证训练营_阿里云培训中心-阿里云https://edu.aliyun.com/trainingcamp/352200?spma2c6h.13788135.J_2488678810.25.251e1ff0kJH3qn&utm_contentg_1000381871&accounttraceid56a1a68f6d344b8daab17edff3d5b9e4yrfk在这里领…

分享99个节日庆典PPT,总有一款适合您

分享99个节日庆典PPT&#xff0c;总有一款适合您 PPT下载链接&#xff1a;https://pan.baidu.com/s/16tBTcXRc7aGU1rQkcVZeOA?pwd8888 提取码&#xff1a;8888 Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 学习知识费力气&#xff0c;收集整理更不易。知识…

【python基础题】——程序题(一)

&#x1f383;个人专栏&#xff1a; &#x1f42c; 算法设计与分析&#xff1a;算法设计与分析_IT闫的博客-CSDN博客 &#x1f433;Java基础&#xff1a;Java基础_IT闫的博客-CSDN博客 &#x1f40b;c语言&#xff1a;c语言_IT闫的博客-CSDN博客 &#x1f41f;MySQL&#xff1a…

项目经理制定项目计划的大作用:明确目标、步骤和监控

作为一名软件项目经理&#xff0c;我意识到在今天必须完成一份项目阶段汇报材料。 因此&#xff0c;我打开了电脑&#xff0c;但在我开始编写之前&#xff0c;我意识到还有一个重要的技术问题尚未确定最终方案。 为了确保项目的顺利进行&#xff0c;我决定召集项目技术骨干进…

干洗店洗鞋店管理系统app小程序;

干洗店洗鞋店管理系统是一款专业的洗衣店管理软件&#xff0c;集成了前台收费收银系统、会员卡管理系统和财务报表系统等强大功能。界面简洁优美&#xff0c;操作直观简单。这款系统为干洗店和洗衣店提供了成本分析、利润分析、洗衣流程管理等诸多实用功能&#xff0c;用全新的…

分类模型的Top 1和Top 5

分类模型的Top 1和Top 5 flyfish 模型分类的结果指标如下图 acc top1 和 acc top5这两列 关于Top 1和Top 5分两种 top 1 accuracy top 5 accuracy 和 top 1 error rate top 5 error rate 这里将需要评估的分类器称为模型 假如一共要测试N张图像&#xff0c;一共有1000个类…

官宣:博士后扩招!

10月26日&#xff0c;《党的十八大以来博士后事业发展综述》发布&#xff0c;其中显示&#xff0c;十八大以来&#xff0c;博士后招收培养规模逐年扩大&#xff0c;博士后进站人数由2012年的1.25万人增长到2022年的3.2万人&#xff0c;2021年、2022年连续两年突破3万人。 图片来…

3.3-DIY一个Base Image

如果执行docker命令提示下面的权限错误&#xff1a; 需要在命令前加上sudo&#xff0c;例如&#xff1a;sudo docker image ls 但是每次都加sudo有些麻烦&#xff0c;有没有办法其他更简便的方法&#xff1f; 我们要去掉sudo就是让当前用户有执行docker命令的权限。 第一步需要…

RabiitMQ消息队列系统

一、MQ 1、概念&#xff1a; MQ 全称为 Message Queue (消息队列)&#xff0c;是一种应用程序对应用程序的通信方法。MQ 允许应用程序将消息写入队列&#xff0c;其他应用程序从队列中读取并处理这些消息&#xff0c;不需要它们之间直接相互联系。消息队列可用于实现异步通信…

信息系统项目管理师改机考的真实感受

继上篇文章讨论的架构师考试通过后&#xff0c;去年也通过了系统分析师&#xff0c;今年刚刚考完信息系统项目管理师&#xff0c;为什么要再写一篇”真实感受“&#xff1f;因为这次改革为机考&#xff0c;时间上也有所调整&#xff0c;考试感受完全不同。 这里不谈考试技巧&am…