摘要:本案例是CenterNet-Hourglass论文复现的体验案例,此模型是对Objects as Points 中提出的CenterNet进行结果复现。

本文分享自华为云社区《CenterNet-Hourglass (物体检测/Pytorch)》,作者:HWCloudAI。

目标检测常采用Anchor的方法来获取物体可能存在的位置,再对该位置进行分类,这样的做法耗时、低效,同时需要后处理(比如NMS)。CenterNet将目标看成一个点,即目标bounding box的中心点,整个问题转变成了关键点估计问题,其他目标属性,比如尺寸、3D位置、方向和姿态等都以估计的中心点为基准进行参数回归。

本案例是CenterNet-Hourglass论文复现的体验案例,此模型是对Objects as Points 中提出的CenterNet进行结果复现(原论文Table 2 最后一行)。本模型是以Hourglass网络架构作为backbone,以ExtremNet 作为预训练模型,在COCO数据集上进行50epochs的训练后得到的。本项目是基于原论文的官方代码进行针对ModelArts平台的修改来实现ModelArts上的训练与部署。

具体算法介绍:https://marketplace.huaweicloud.com/markets/aihub/modelhub/detail/?id=380f95a6-1552-4128-ac96-36066258853f

注意事项:

1.本案例使用框架:PyTorch1.4.0

2.本案例使用硬件:GPU: 1*NVIDIA-V100NV32(32GB) | CPU: 8 核 64GB

3.运行代码方法: 点击本页面顶部菜单栏的三角形运行按钮或按Ctrl+Enter键 运行每个方块中的代码

4.JupyterLab的详细用法: 请参考《ModelAtrs JupyterLab使用指导》

5.碰到问题的解决办法:请参考《ModelAtrs JupyterLab常见问题解决办法》

1.下载数据和代码

运行下面代码,进行数据和代码的下载和解压

本案例使用COCO数据集。

  1. import os
  2. #数据代码下载
  3. !wget https://obs-aigallery-zc.obs.cn-north-4.myhuaweicloud.com/algorithm/CenterNet.zip
  4. # 解压缩
  5. os.system('unzip CenterNet.zip -d ./')
  1. --2021-06-25 17:50:11-- https://obs-aigallery-zc.obs.cn-north-4.myhuaweicloud.com/algorithm/CenterNet.zip
  2. Resolving proxy-notebook.modelarts.com (proxy-notebook.modelarts.com)... 192.168.6.62
  3. Connecting to proxy-notebook.modelarts.com (proxy-notebook.modelarts.com)|192.168.6.62|:8083... connected.
  4. Proxy request sent, awaiting response... 200 OK
  5. Length: 1529663572 (1.4G) [application/zip]
  6. Saving to: CenterNet.zip
  7. CenterNet.zip 100%[===================>] 1.42G 279MB/s in 5.6s
  8. 2021-06-25 17:50:16 (261 MB/s) - CenterNet.zip saved [1529663572/1529663572]
  9. 0

2.训练

2.1依赖库加载和安装

  1. from __future__ import absolute_import
  2. from __future__ import division
  3. from __future__ import print_function
  4. root_path = './CenterNet/'
  5. os.chdir(root_path)
  6. os.system('pip install pycocotools')
  7. import _init_paths
  8. import torch
  9. import torch.utils.data
  10. from opts import opts
  11. from models.model import create_model, load_model, save_model
  12. from models.data_parallel import DataParallel
  13. from logger import Logger
  14. from datasets.dataset_factory import get_dataset
  15. from trains.train_factory import train_factory
  16. from evaluation import test, prefetch_test, image_infer
  17. USE_MODELARTS = True
  18. INFO:root:Using MoXing-v2.0.0.rc0-19e4d3ab
  19. INFO:root:Using OBS-Python-SDK-3.20.9.1
  20. NMS not imported! If you need it, do
  21. cd $CenterNet_ROOT/src/lib/external
  22. make

2.2训练函数

  1. def main(opt):
  2. torch.manual_seed(opt.seed)
  3. torch.backends.cudnn.benchmark = not opt.not_cuda_benchmark and not opt.test
  4. Dataset = get_dataset(opt.dataset, opt.task)
  5. opt = opts().update_dataset_info_and_set_heads(opt, Dataset)
  6. logger = Logger(opt)
  7. os.environ['CUDA_VISIBLE_DEVICES'] = opt.gpus_str
  8. opt.device = torch.device('cuda' if opt.gpus[0] >= 0 else 'cpu')
  9. print('Creating model...')
  10. model = create_model(opt.arch, opt.heads, opt.head_conv)
  11. optimizer = torch.optim.Adam(model.parameters(), opt.lr)
  12. start_epoch = 0
  13. if opt.load_model != '':
  14. model, optimizer, start_epoch = load_model(
  15. model, opt.load_model, optimizer, opt.resume, opt.lr, opt.lr_step)
  16. Trainer = train_factory[opt.task]
  17. trainer = Trainer(opt, model, optimizer)
  18. trainer.set_device(opt.gpus, opt.chunk_sizes, opt.device)
  19. print('Setting up data...')
  20. train_loader = torch.utils.data.DataLoader(
  21. Dataset(opt, 'train'),
  22. batch_size=opt.batch_size,
  23. shuffle=True,
  24. num_workers=opt.num_workers,
  25. pin_memory=True,
  26. drop_last=True
  27. )
  28. print('Starting training...')
  29. best = 1e10
  30. for epoch in range(start_epoch + 1, opt.num_epochs + 1):
  31. mark = epoch if opt.save_all else 'last'
  32. log_dict_train, _ = trainer.train(epoch, train_loader)
  33. logger.write('epoch: {} |'.format(epoch))
  34. for k, v in log_dict_train.items():
  35. logger.scalar_summary('train_{}'.format(k), v, epoch)
  36. logger.write('{} {:8f} | '.format(k, v))
  37. save_model(os.path.join(opt.save_dir, 'model_last.pth'),
  38. epoch, model)
  39. logger.write('\n')
  40. if epoch in opt.lr_step:
  41. save_model(os.path.join(opt.save_dir, 'model_{}.pth'.format(epoch)),
  42. epoch, model, optimizer)
  43. lr = opt.lr * (0.1 ** (opt.lr_step.index(epoch) + 1))
  44. print('Drop LR to', lr)
  45. for param_group in optimizer.param_groups:
  46. param_group['lr'] = lr
  47. logger.close()

2.3开始训练

训练需要一点时间,请耐心等待

  1. if __name__ == '__main__':
  2. opt = opts().parse()
  3. if USE_MODELARTS:
  4. pwd = os.getcwd()
  5. print('Copying dataset to work space...')
  6. print('Listing directory: ')
  7. print(os.listdir())
  8. if not os.path.exists(opt.save_dir):
  9. os.makedirs(opt.save_dir)
  10. main(opt)
  11. if USE_MODELARTS:
  12. print("Processing model checkpoints & service config for deployment...")
  13. if not opt.eval:
  14. infer_dir = os.path.join(opt.save_dir, 'model')
  15. os.makedirs(infer_dir)
  16. os.system(f'mv ./trained_model/* {infer_dir}')
  17. pretrained_pth = os.path.join(infer_dir, '*.pth')
  18. ckpt_dir = os.path.join(opt.save_dir, 'checkpoints')
  19. os.makedirs(ckpt_dir)
  20. os.system(f'mv {pretrained_pth} {ckpt_dir}')
  21. pth_files = os.path.join(opt.save_dir, '*.pth')
  22. infer_pth = os.path.join(ckpt_dir, f'{opt.model_deploy}.pth')
  23. os.system(f'mv {pth_files} {ckpt_dir}')
  24. os.system(f'mv {infer_pth} {infer_dir}')
  25. print(os.listdir(opt.save_dir))
  26. print("ModelArts post-training work is done!")
  27. Fix size testing.
  28. training chunk_sizes: [8]
  29. The output will be saved to ./output/exp/ctdet/default
  30. Copying dataset to work space...
  31. Listing directory:
  32. ['pre-trained_weights', '.ipynb_checkpoints', 'coco_eval.py', 'train.py', 'coco', 'output', 'training_logs', 'trained_model', '_init_paths.py', '__pycache__', 'coco_classes.py', 'lib', 'evaluation.py']
  33. heads {'hm': 80, 'wh': 2, 'reg': 2}
  34. Creating model...
  35. loaded ./trained_model/epoch_50_mAP_42.7.pth, epoch 50
  36. Setting up data...
  37. ==> initializing coco 2017 train data.
  38. loading annotations into memory...
  39. Done (t=0.54s)
  40. creating index...
  41. index created!
  42. Loaded train 5000 samples
  43. Starting training...
  44. /home/ma-user/anaconda3/envs/Pytorch-1.4.0/lib/python3.6/site-packages/torch/nn/_reduction.py:43: UserWarning: size_average and reduce args will be deprecated, please use reduction='sum' instead.
  45. warnings.warn(warning.format(ret))
  46. ctdet/default| train: [1][0/625] |loss 1.7568 |hm_loss 1.3771 |wh_loss 1.9394 |off_loss 0.1857 |Data 0.384s (0.384s) |Net 5.019s (5.019s)
  47. ctdet/default| train: [1][200/625] |loss 1.9275 |hm_loss 1.4429 |wh_loss 2.7269 |off_loss 0.2119 |Data 0.001s (0.003s) |Net 0.759s (0.779s)
  48. ctdet/default| train: [1][400/625] |loss 1.9290 |hm_loss 1.4430 |wh_loss 2.7423 |off_loss 0.2118 |Data 0.001s (0.002s) |Net 0.760s (0.770s)
  49. ctdet/default| train: [1][600/625] |loss 1.9276 |hm_loss 1.4397 |wh_loss 2.7623 |off_loss 0.2117 |Data 0.001s (0.002s) |Net 0.765s (0.767s)
  50. Processing model checkpoints & service config for deployment...
  51. ['model', 'logs_2021-06-25-17-51', 'opt.txt', 'checkpoints']
  52. ModelArts post-training work is done!

3.模型测试

3.1推理函数

  1. # -*- coding: utf-8 -*-
  2. # TODO 添加模型运行需要导入的模块
  3. import os
  4. import torch
  5. import numpy as np
  6. from PIL import Image
  7. from io import BytesIO
  8. from collections import OrderedDict
  9. import cv2
  10. import sys
  11. sys.path.insert(0, './lib')
  12. from opts import opts
  13. from coco_classes import coco_class_map
  14. from detectors.detector_factory import detector_factory
  15. class ModelClass():
  16. def __init__(self, model_path):
  17. self.model_path = model_path # 本行代码必须保留,且无需修改
  18. self.opt = opts().parse()
  19. self.opt.num_classes = 80
  20. self.opt.resume = True
  21. self.opt.keep_res = True
  22. self.opt.fix_res = False
  23. self.opt.heads = {'hm': 80, 'wh': 2, 'reg': 2}
  24. self.opt.load_model = model_path
  25. self.opt.mean = np.array([0.40789654, 0.44719302, 0.47026115],
  26. dtype=np.float32).reshape(1, 1, 3)
  27. self.opt.std = np.array([0.28863828, 0.27408164, 0.27809835],
  28. dtype=np.float32).reshape(1, 1, 3)
  29. self.opt.batch_infer = False
  30. # configurable varibales:
  31. if 'BATCH_INFER' in os.environ:
  32. print('Batch inference mode!')
  33. self.opt.batch_infer = True
  34. if 'FLIP_TEST' in os.environ:
  35. print('Flip test!')
  36. self.opt.flip_test = True
  37. if 'MULTI_SCALE' in os.environ:
  38. print('Multi scale!')
  39. self.opt.test_scales = [0.5,0.75,1,1.25,1.5]
  40. self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
  41. if not torch.cuda.is_available():
  42. self.opt.gpus = [-1]
  43. self.class_map = coco_class_map()
  44. torch.set_grad_enabled(False)
  45. Detector = detector_factory[self.opt.task]
  46. self.detector = Detector(self.opt)
  47. print('load model success')
  48. def predict(self, file_name):
  49. image = Image.open(file_name).convert('RGB')
  50. img = np.array(image)
  51. img = img[:, :, ::-1]
  52. results = self.detector.run(img)['results']
  53. image = cv2.cvtColor(np.asarray(image),cv2.COLOR_RGB2BGR)
  54. if not self.opt.batch_infer:
  55. for c_id, dets in results.items():
  56. for det in dets:
  57. if det[4] > self.opt.vis_thresh:
  58. scores = str(round(float(det[4]), 4))
  59. classes = self.class_map[c_id]
  60. image = cv2.rectangle(image,(int(det[0]),int(det[1])),(int(det[2]),int(det[3])),(0,255,0),2)
  61. image = cv2.putText(image,classes+':'+scores,(int(det[0]),int(det[1])),cv2.FONT_HERSHEY_SIMPLEX,0.7,(0,0,255),2)
  62. else:
  63. for c_id, dets in results.items():
  64. for det in dets:
  65. scores = str(round(float(det[4]), 4))
  66. classes = self.class_map[c_id]
  67. image = cv2.rectangle(image,(int(det[0]),int(det[1])),(int(det[2]),int(det[3])),(0,255,0),2)
  68. image = cv2.putText(image,classes+':'+scores,(int(det[0]),int(det[1])),cv2.FONT_HERSHEY_SIMPLEX,0.5,(0,0,255),2)
  69. return image

3.2开始推理

可以自行修改预测的图像路径

  1. if __name__ == '__main__':
  2. import matplotlib.pyplot as plt
  3. img_path = './coco/train/000000021903.jpg'
  4. model_path = './output/exp/ctdet/default/model/model_last.pth' #模型的保存路径,你可以自己找一下
  5. # 以下代码无需修改
  6. my_model = ModelClass(model_path)
  7. result = my_model.predict(img_path)
  8. result = Image.fromarray(cv2.cvtColor(result,cv2.COLOR_BGR2RGB))
  9. plt.figure(figsize=(10,10)) #设置窗口大小
  10. plt.imshow(result)
  11. plt.show()
  1. Fix size testing.
  2. training chunk_sizes: [8]
  3. The output will be saved to ./output/exp/ctdet/default
  4. Creating model...
  5. loaded ./output/exp/ctdet/default/model/model_last.pth, epoch 1
  6. load model success

点击关注,第一时间了解华为云新鲜技术~

实践案例丨CenterNet-Hourglass论文复现的更多相关文章

  1. 实践案例丨基于ModelArts AI市场算法MobileNet_v2实现花卉分类

    概述 MobileNetsV2是基于一个流线型的架构,它使用深度可分离的卷积来构建轻量级的深层神经网,此模型基于 MobileNetV2: Inverted Residuals and Linear ...

  2. 实践案例丨基于 Raft 协议的分布式数据库系统应用

    摘要:简单介绍Raft协议的原理.以及存储节点(Pinetree)如何应用 Raft实现复制的一些工程实践经验. 1.引言 在华为分布式数据库的工程实践过程中,我们实现了一个计算存储分离. 底层存储基 ...

  3. 实践案例丨教你一键构建部署发布前端和Node.js服务

    如何使用华为云服务一键构建部署发布前端和Node.js服务 构建部署,一直是一个很繁琐的过程 作为开发,最害怕遇到版本发布,特别是前.后端一起上线发布,项目又特别多的时候. 例如你有10个项目,前后端 ...

  4. 实践案例丨利用小熊派开发板获取土壤湿度传感器的ADC值

    摘要:一文带你用小熊派开发板动手做土壤湿度传感器. 一.实验准备 1.实验环境 一块stm32开发板(推荐使用小熊派),以及数据线 已经安装STM32CubeMX 已经安装KeilMDK,并导入stm ...

  5. FCOS论文复现:通用物体检测算法

    摘要:本案例代码是FCOS论文复现的体验案例,此模型为FCOS论文中所提出算法在ModelArts + PyTorch框架下的实现.本代码支持FCOS + ResNet-101在MS-COCO数据集上 ...

  6. DDD实践案例:引入事件驱动与中间件机制来实现后台管理功能

    DDD实践案例:引入事件驱动与中间件机制来实现后台管理功能 一.引言 在当前的电子商务平台中,用户下完订单之后,然后店家会在后台看到客户下的订单,然后店家可以对客户的订单进行发货操作.此时客户会在自己 ...

  7. 微服务实战(四):服务发现的可行方案以及实践案例 - DockOne.io

    原文:微服务实战(四):服务发现的可行方案以及实践案例 - DockOne.io 这是关于使用微服务架构创建应用系列的第四篇文章.第一篇介绍了微服务架构的模式,讨论了使用微服务架构的优缺点.第二和第三 ...

  8. - 反编译 AndroidKiller 逆向 实践案例 MD

    目录 目录 反编译 AndroidKiller 逆向 实践案例 MD AndroidKiller 简介 插件升级 基本使用 实践案例 修改清单文件 打印 debug 级别的日志 方式一:直接代理 Lo ...

  9. 《SaltStack技术入门与实践》—— 实践案例 <中小型Web架构>3 Memcached配置管理

    实践案例 <中小型Web架构>3 Memcached配置管理 本章节参考<SaltStack技术入门与实践>,感谢该书作者: 刘继伟.沈灿.赵舜东 Memcached介绍 Me ...

  10. Visualizing and Understanding Convolutional Networks论文复现笔记

    目录 Visualizing and Understanding Convolutional Networks 论文复现笔记 Abstract Introduction Approach Visual ...

随机推荐

  1. 实验四报告: 熟悉Python字典、集合、字符串的使用

    实验目标 本实验的主要目标是熟悉Python中字典.集合.字符串的创建和操作,包括字典的创建.访问.修改和合并,集合的创建.访问以及各种集合运算,以及字符串的创建.格式化和常用操作. 实验要求 通过编 ...

  2. 入门篇-其之六-附录一-以Java字节码的角度分析i++和++i

    前言:众所周知,i++和++i的区别是:i++先将i的值赋值给变量,再将i的值自增1:而++i则是先将i的值自增1,再将结果赋值给变量.因此,二者最终都给i自增了1,只是方式不同而已. 当然,如果在面 ...

  3. CSP2021游记

    题外话 中午十二点半到了考场.没到时间不让进,恰巧发现 lhm 在对面饭店于是去讨论了一下上午 J 组的题,复习了线段树板子( 等到进考场坐好的时候已经两点半了,看考号本来以为我们同机房三个同学会坐一 ...

  4. 机器学习|K邻近(K Nearest-Neighbours)

    本文从概念.原理.距离函数.K 值选择.K 值影响..优缺点.应用几方面详细讲述了 KNN 算法 K 近临(K Nearest-Neighbours) 一种简单的监督学习算法,惰性学习算法,在技术上并 ...

  5. 最新 2023.2 版本 IDEA 永久破解教程,IDEA 破解补丁永久激活(亲测有效)

    最近 jetbrains 官方发布了 2023.2 版本的 IDEA,之前的激活方法并不支持这个新的版本. 下面是最新的激活教程,激活步骤和之前是类似的,只是换用了不同的补丁文件. 本教程支持 Jet ...

  6. c#中建造者设计模式详解

    基础介绍:   将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示.   说白了就是将一个复杂的对象拆分成一个一个零件,然后按照既定顺序和规则进行组装,最终形成这个相对复杂的对象 ...

  7. C# 压缩PDF文件

    PDF 文件可以包含文本.图片及各种媒体元素,但如果文件太大则会影响传输效果同时也会占用过多磁盘空间.通过压缩PDF文件,能够有效减小文件大小,从而提高传输效率并节省存储空间.想要通过C#代码快速有效 ...

  8. CSS 样式书写顺序及规范

    作者:WangMin 格言:努力做好自己喜欢的每一件事 在项目中,大部分前端程序员都没有按照良好的CSS书写规范来写CSS代码,每次写css样式都是用到什么就在样式表后添加什么,完全没有考虑到样式属性 ...

  9. Net 高级调试之十:轻量级代码生成的调试

    一.简介 今天是<Net 高级调试>的第十篇文章.说起来,高级调试,调试的内容还是挺多的,技巧也不少,但是,要想做一个合格的高级调试人员,还需要掌握如何调试动态生成的IL代码.今天要探讨的 ...

  10. DataGridView合并单元格,重绘后选中内容被覆盖的解决办法

    DataGridView合并单元格只能进行重绘,网上基本上使用的是下面的方法: 1 /// <summary> 2 /// 说明:纵向合并单元格 3 /// 参数:dgv DataGrid ...