【极市打榜】算法竞赛/打榜通用技巧总结(附源码)
极市平台
共 9479字,需浏览 19分钟
· 2021-11-27
极市导读
极市打榜是面向计算机视觉开发者的算法竞技,参与者人人都可以通过提高算法分数(精度+性能分)获得早鸟奖励+分分超越奖励,排行榜前三名的胜利者将有机会获得该算法的极市复购订单,获得持续的订单收益。
提供免费算力+真实场景数据集;早鸟奖励+分分超越奖励+持续订单分成,实时提现!
前言
模型选取
目标检测 Yolo系列:yolov5, yolo4, yolov3等 SSD nanodet yolox 语义分割 BiSeNet STDC 目标追踪 yolov5+deepsort 视频(动作)分类 TSM SlowFast x3d
编码和训练
结果图可保存在 /project/train/result-graph
,那么训练完成后即可在训练页面查看
将训练的保存路径设置为 /project/train/models
,那么训练终止后,从保存的模型重新加载后,仍然可以恢复训练
可以对随机划分数据集设置随机数种子,以保证每次训练的数据都是一致的
random.seed(1)
如果github下载过慢,这里我们可以使用一个镜像网址进行操作: hub.fastgit.org
,例如将
git clone https://github.com/ExtremeMart/ev_sdk.git
wget https://github.com/ExtremeMart/dev-docs/archive/refs/tags/v3.0.3.zip
git clone https://hub.fastgit.org/ExtremeMart/ev_sdk.git
wget https://hub.fastgit.org/ExtremeMart/dev-docs/archive/refs/tags/v3.0.3.zip
如果遇到资源不足导致实例打开失败,可尝试多次启动实例,如果还是不行,可以尝试重建实例。
测试
pip install nvidia-pyindex
pip install nvidia-tensorrt pycuda
cd /usr/local
# install cuda10.2
mkdir temp && cd temp && wget https://minio.cvmart.net/user-file/9876/886bcb1539b2460f8938f63fb5643356.zip && unzip 886bcb1539b2460f8938f63fb5643356.zip
dpkg -i libxnvctrl0_440.33.01-0ubuntu1_amd64.deb libxnvctrl-dev_440.33.01-0ubuntu1_amd64.deb cuda-cluster-runtime-10-2_10.2.89-1_amd64.deb cuda-cluster-devel-10-2_10.2.89-1_amd64.deb nsight-compute-2019.5.0_2019.5.0.14-1_amd64.deb NsightSystems-linux-public-2019.5.2.16-b54ef97.deb
cd ../ && rm -rf temp cuda cuda-10.1 && ln -s /usr/local/cuda-10.2 /usr/local/cuda
# install cudnn8.1
wget https://minio.cvmart.net/user-file/9876/0e24bccb454b4f54aedb9395ff781691.deb && dpkg -i 0e24bccb454b4f54aedb9395ff781691.deb
# install TensorRT7.2.3
wget https://minio.cvmart.net/user-file/9876/10e90f8459754eebbabe0e95026f0119.gz && tar -xf 10e90f8459754eebbabe0e95026f0119.gz
echo "export LD_LIBRARY_PATH=/usr/local/TensorRT-7.2.3.4/lib:$LD_LIBRARY_PATH" >> ~/.zshrc && source ~/.zshrc
rm 10e90f8459754eebbabe0e95026f0119.gz 0e24bccb454b4f54aedb9395ff781691.deb
# build opencv-4.1.2
cd /home
wget https://minio.cvmart.net/user-file/9876/e695f9548daa4fd7a942691505bb3d94.zip && unzip e695f9548daa4fd7a942691505bb3d94.zip && rm e695f9548daa4fd7a942691505bb3d94.zip
cd opencv-4.1.2 && mkdir build && cd build
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local -D OPENCV_EXTRA_MODULES_PATH=/home/opencv_contrib -D PYTHON_DEFAULT_EXECUTABLE=/usr/bin/python3 -D BUILD_opencv_python3=OFF -D BUILD_opencv_python2=OFF -D PYTHON3_EXCUTABLE=/usr/bin/python3 -D WITH_CUDA=OFF -D OPENCV_GENERATE_PKGCONFIG=ON ..
make -j8
make install
更改测试输入尺寸,可以加速网络运行速度,但是可能会降低精度。 测试时,可以更改置信度等参数,去寻找更好的测试结果。 由于目前平台不支持测试备注,因此我们可以用文档记录每次所改的测试参数。
快速部署
例子
配置好训练环境和测试环境, 可参考前面。 对数据集进行转换,得到yolo格式的数据集,并划分数据集。
from __future__ import division
from __future__ import print_function
from __future__ import absolute_import
import os
import sys
import shutil
import pathlib
import random
import xml.etree.ElementTree as ET
import io
from global_config import *
train_data_dir = os.path.join(project_root, 'dataset/images/train/')
valid_data_dir = os.path.join(project_root, 'dataset/images/valid')
annotations_train_dir = os.path.join(project_root, 'dataset/labels/train')
annotations_valid_dir = os.path.join(project_root, 'dataset/labels/valid')
supported_fmt = ['.jpg', '.JPG']
def convert_box(size, box):
dw = 1. / (size[0])
dh = 1. / (size[1])
x, y, w, h = (box[0] + box[1]) / 2.0 - 1, (box[2] + box[3]) / 2.0 - 1, box[1] - box[0], box[3] - box[2]
return x * dw, y * dh, w * dw, h * dh
def xml_to_yolo(data_list,annotations_dir):
"""将data_list表示的(图片, 标签)对转换成yolo记录
"""
xml_list = []
for data in data_list:
out_file = open(os.path.join(annotations_dir, os.path.basename(data['label']).replace('.xml', '.txt')), 'w')
tree = ET.parse(data['label'])
root = tree.getroot()
size = root.find('size')
w = int(size.find('width').text)
h = int(size.find('height').text)
for obj in root.iter('object'):
# difficult = obj.find('difficult').text
cls = obj.find('name').text
if cls not in classes: #or int(difficult) == 1:
continue
cls_id = classes.index(cls)
xmlbox = obj.find('bndbox')
b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text), float(xmlbox.find('ymax').text))
bb = convert_box((w, h), b)
out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')
out_file.close()
if __name__ == '__main__':
os.makedirs(project_root, exist_ok=True)
os.makedirs(train_data_dir, exist_ok=True)
os.makedirs(valid_data_dir, exist_ok=True)
os.makedirs(annotations_train_dir, exist_ok=True)
os.makedirs(annotations_valid_dir, exist_ok=True)
if not os.path.exists(sys.argv[1]):
print(f'{sys.argv[1]} 不存在!')
exit(-1)
# 遍历数据集目录下所有xml文件及其对应的图片
dataset_path = pathlib.Path(sys.argv[1])
found_data_list = []
for xml_file in dataset_path.glob('**/*.xml'):
possible_images = [xml_file.with_suffix(suffix) for suffix in supported_fmt]
supported_images = list(filter(lambda p: p.is_file(), possible_images))
if len(supported_images) == 0:
print(f'找不到对应的图片文件:`{xml_file.as_posix()}`')
continue
found_data_list.append({'image': supported_images[0], 'label': xml_file})
# 随机化数据集,将数据集拆分成训练集和验证集,并将其拷贝到/project/train/src_repo/dataset下
random.seed(1)
random.shuffle(found_data_list)
train_data_count = len(found_data_list) * 4 / 5
train_data_list = []
valid_data_list = []
for i, data in enumerate(found_data_list):
if i < train_data_count: # 训练集
dst = train_data_dir
data_list = train_data_list
else: # 验证集
dst = valid_data_dir
data_list = valid_data_list
image_dst = (pathlib.Path(dst) / data['image'].name).as_posix()
label_dst = (pathlib.Path(dst) / data['label'].name).as_posix()
shutil.copy(data['image'].as_posix(), image_dst)
shutil.copy(data['label'].as_posix(), label_dst)
data_list.append({'image': image_dst, 'label': label_dst})
#xml to yolo
xml_to_yolo(train_data_list, annotations_train_dir)
xml_to_yolo(valid_data_list, annotations_valid_dir)
print('Successfully converted xml to yolo.')
用 yolov5 对数据集进行训练,通过调参获得一个最好的模型。
#!/bin/bash
# 创建默认目录,训练过程中生成的模型文件、日志、图必须保存在这些固定目录下,训练完成后这些文件将被保存
rm -rf /project/train/models/result-graphs && rm -rf /project/train/log && rm -rf /project/train/src_repo/dataset
mkdir -p /project/train/result-graphs && mkdir -p /project/train/log
project_root_dir=/project/train/src_repo
dataset_dir=/home/data
log_file=/project/train/log/log.txt
if [ ! -z $1 ]; then
num_train_steps=$1
else
num_train_steps=10
fi
if [ ! -z $2 ]; then
batch_size=$2
else
batch_size=16
fi
if [ ! -z $3 ]; then
workers=$3
else
workers=2
fi
echo "Converting dataset..." \
&& python3 -u ${project_root_dir}/convert_dataset.py ${dataset_dir} | tee -a ${log_file} \
&& cd ${project_root_dir} && cp data.yaml yolov5/data/ \
&& pip install -i https://mirrors.cloud.tencent.com/pypi/simple -r /project/train/src_repo/yolov5/requirements.txt \
&& echo "Start training..." \
&& cd yolov5 && python3 -u train.py --data data.yaml --project /project/train/models --batch-size ${batch_size} --epochs ${num_train_steps} --workers ${workers} 2>&1 | tee -a ${log_file} \
&& echo "Done!!!" \
&& echo "Copy result images to /project/train/result-graphs ..." \
&& cp /project/train/models/exp/*.jpg /project/train/models/exp/*.png /project/train/result-graphs | tee -a ${log_file} \
&& echo "Finished!!!"
参考github的tensorrtx对模型进行转换,以及完成sdk的代码编写。
from __future__ import print_function
import logging as log
import os
import pathlib
import json
import cv2
import numpy as np
import time
from yolov5_trt import YoLov5TRT, warmUpThread
# For objection detection task, replace your target labels here.
categories = ['reflective_vest','no_reflective_vest','person_reflective_vest','person_no_reflective_vest']
def init():
"""
Initialize model
Returns: model
"""
engine_file_path = "/project/ev_sdk/model/best.engine"
yolov5_wrapper = YoLov5TRT(engine_file_path)
try:
#warm up
for i in range(5):
# create a new thread to do warm_up
thread1 = warmUpThread(yolov5_wrapper)
thread1.start()
thread1.join()
finally:
# destroy the instance
yolov5_wrapper.destroy()
return yolov5_wrapper
def process_image(net=None, input_image=None, args=None, **kwargs):
"""Do inference to analysis input_image and get output
Attributes:
net: model handle
input_image (numpy.ndarray): image to be process, format: (h, w, c), BGR
thresh: thresh value
Returns: process result
"""
if not net or input_image is None:
log.error('Invalid input args')
return json.dumps({'model_data':{'objects':[]}})
data = net.infer((x for x in [input_image]))[0]
res_json={'model_data':dict()}
if data[0] is None:
return json.dumps({'model_data':{'objects':[]}})
else:
detect_objs = []
for i in range(len(data[0])):
xyxy, conf, cls = data[0][i], data[1][i], int(data[2][i])
detect_objs.append({
'name': categories[cls],
'xmin': int(xyxy[0]),
'ymin': int(xyxy[1]),
'xmax': int(xyxy[2]),
'ymax': int(xyxy[3]),
'confidence': float(conf)
})
res_json['model_data']['objects'] = detect_objs
return json.dumps(res_json)
if __name__ == '__main__':
# Test API
img = cv2.imread('/project/ev_sdk/data/test.jpg')
predictor = init()
import time
s = time.time()
for i in range(20):
res = process_image(predictor, img)
e = time.time()
print(res)
print((e-s)/20)
更改阈值或者输入尺寸参数,进行测试得到最优结果。
总结
如果觉得有用,就请分享到朋友圈吧!
公众号后台回复“transformer”获取最新Transformer综述论文下载~
# CV技术社群邀请函 #
备注:姓名-学校/公司-研究方向-城市(如:小极-北大-目标检测-深圳)
即可申请加入极市目标检测/图像分割/工业检测/人脸/医学影像/3D/SLAM/自动驾驶/超分辨率/姿态估计/ReID/GAN/图像增强/OCR/视频理解等技术交流群
每月大咖直播分享、真实项目需求对接、求职内推、算法竞赛、干货资讯汇总、与 10000+来自港科大、北大、清华、中科院、CMU、腾讯、百度等名校名企视觉开发者互动交流~
评论
轻松掌握开源项目的二次开发技巧
大厂技术 高级前端 Node进阶点击上方 程序员成长指北,关注公众号回复1,加入高级Node交流群本文作者:@方长_beezen 原文链接:https://juejin.cn/post/7358647992608489535前言随着软件行业的迅速
程序员成长指北
0
微软开源MS-DOS操作系统源码,冲到GitHub第一了!
大家好,我是轩辕。这两天逛GitHub的时候,突然发现一个叫 MS-DOS的项目冲到Trending榜首了!定睛一看,微软官方啊,搜了一下才知道,原来前两天,微软把MS-DOS 4.0系统开源了!关于这个系统,估计现在很多程序员都不知道了,或者只在古老的教科书上看过这玩意儿。MS-DOS,全称为Mi
编程技术宇宙
6
Python加速运行技巧
Python 是一种脚本语言,相比 C/C++ 这样的编译语言,在效率和性能方面存在一些不足。但是,有很多时候,Python 的效率并没有想象中的那么夸张。本文对一些 Python 代码加速运行的技巧进行整理。 0. 代码优化原则 本文会介绍不少的 Python 代码加速运行的技巧。在深入代码优化细
机器学习算法与Python实战
0
15种时间序列预测方法总结(包含多种方法代码实现)
向AI转型的程序员都关注了这个号👇👇👇在这篇文章中,我们将深入探讨时间序列预测的基本概念和方法。我们将首先介绍单元预测和多元预测的概念,然后详细介绍各种深度学习和传统机器学习方法如何应用于时间序列预测,包括循环神经网络(RNN)、一维卷积神经网络(1D-CNN)、Transformer、自回归模型(
机器学习AI算法工程
0
APP 安全测试项总结
一、安装包测试 1.1、关于反编译 目的是为了保护公司的知识产权和安全方面的考虑等,一些程序开发人员会在源码中硬编码一些敏感信息,如密码。而且若程序内部一些设计欠佳的逻辑,也可能隐含漏洞,一旦源码泄漏,安全隐患巨大。 为了避免这些问题,除了代码审核外,通常开发的做法是对代码进行混淆,混淆后源代
测试开发技术
0
10个高级的 SQL 查询技巧
来源:towardsdatascience.com/ten-advanced-sql-concepts-you-should-know-for-data-science-interviews-4d7015ec74b0👉 欢迎加入小哈的星球 ,你将获得: 专属的项目实战 / Jav
小哈学Java
0
【Python】Python加速运行技巧
Python 是一种脚本语言,相比 C/C++ 这样的编译语言,在效率和性能方面存在一些不足。但是,有很多时候,Python 的效率并没有想象中的那么夸张。本文对一些 Python 代码加速运行的技巧进行整理。 0. 代码优化原则 本文会介绍不少的 Python 代码加速运行的技巧。在深入代码优化细
机器学习初学者
0
微服务与领域驱动设计,架构实践总结
来源:知了一笑👉 欢迎加入小哈的星球 ,你将获得: 专属的项目实战 / Java 学习路线 / 一对一提问 / 学习打卡 / 赠书福利全栈前后端分离博客项目 2.0 版本完结啦, 演示链接:http://116.62.199.48/ ,新
小哈学Java
0