• 实践案例丨CenterNet-Hourglass论文复现


    摘要:本案例是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上的训练与部署。

    具体算法介绍:AI Gallery_算法_模型_云市场-华为云

    注意事项:

    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

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

     

  • 相关阅读:
    docker离线安装和使用
    FME之PythonCaller遍历(循环)列表(数组)
    github中RabbitMq延迟插件rabbitmq-delayed-message-exchange查找并下载
    iPhone开发--Xcode15下载iOS 17.0.1 Simulator Runtime失败解决方案
    超六成专科生的月薪不足5000元?网友:本科和研究生也是
    W中国笔记本电脑包行业竞争动态与销售渠道分析报告2022-2028年
    大数据之hadoop入门
    .NET WebAPI 自定义 NullableConverter 解决可为空类型字段入参“”空字符触发转换异常问题
    Java开发学习(二十七)----SpringMVC之Rest风格解析及快速开发
    鲜花静态HTML网页作业作品 大学生鲜花网页设计制作成品 简单DIV CSS布局网站
  • 原文地址:https://blog.csdn.net/devcloud/article/details/128187001