From 49d811e842bf147c9460c549da98eb6a00d6d45f Mon Sep 17 00:00:00 2001 From: Victor Chen <44614525@qq.com> Date: Fri, 15 Apr 2022 13:45:49 +0800 Subject: [PATCH 1/2] add Pose Estimation UniFormer --- .../cv/pose_estimation/UniFormer/LICENSE | 201 ++++++++++++++++++ .../UniFormer/modelzoo_level.txt | 4 + .../cv/pose_estimation/UniFormer/readme.md | 52 +++++ .../UniFormer/requirements.txt | 6 + .../UniFormer/test/bin_util.py | 79 +++++++ .../UniFormer/test/eval_acc_perf.sh | 59 +++++ .../pose_estimation/UniFormer/test/pth2om.sh | 38 ++++ .../pose_estimation/UniFormer/uniformer.patch | 119 +++++++++++ .../UniFormer/uniformer_postprocess.py | 118 ++++++++++ .../UniFormer/uniformer_preprocess.py | 106 +++++++++ 10 files changed, 782 insertions(+) create mode 100644 ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/LICENSE create mode 100644 ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/modelzoo_level.txt create mode 100644 ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/readme.md create mode 100644 ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/requirements.txt create mode 100644 ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/test/bin_util.py create mode 100644 ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/test/eval_acc_perf.sh create mode 100644 ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/test/pth2om.sh create mode 100644 ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/uniformer.patch create mode 100644 ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/uniformer_postprocess.py create mode 100644 ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/uniformer_preprocess.py diff --git a/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/LICENSE b/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/LICENSE new file mode 100644 index 0000000000..cc87e8683f --- /dev/null +++ b/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2021 Megvii, Base Detection + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/modelzoo_level.txt b/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/modelzoo_level.txt new file mode 100644 index 0000000000..c44d18672f --- /dev/null +++ b/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/modelzoo_level.txt @@ -0,0 +1,4 @@ +FuncStatus:OK +PrecisionStatus:OK +ModelConvert:OK +PerfStatus:OK diff --git a/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/readme.md b/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/readme.md new file mode 100644 index 0000000000..709c35794c --- /dev/null +++ b/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/readme.md @@ -0,0 +1,52 @@ +### Pose Estimation UniFormer模型PyTorch离线推理指导 + +### 1. 环境准备 + +1. 安装依赖 + +```bash +pip install -r requirements.txt +``` + +2. 获取,修改与安装开源模型代码 + +``` +git clone -b main https://github.com/Sense-X/UniFormer.git +cd UniFormer +git reset e8024703bffb89cb7c7d09e0d774a0d2a9f96c25 --hard + +patch -p1 < ../uniformer.patch +cd pose_estimation +pip install mmcv-full==1.3.18 -f https://download.openmmlab.com/mmcv/dist/cpu/torch1.8.0/index.html +pip install -v -e . # or python3 setup.py develop +cd ../.. +``` + +3. 将权重文件[top_down_256x192_global_base.pth](https://drive.google.com/file/d/15tzJaRyEzyWp2mQhpjDbBzuGoyCaJJ-2/view?usp=sharing)放到当前工作目录 + +4. 数据集 + + 获取COCO数据集,并重命名为coco,放到/root/datasets目录 + +5. [获取msame工具](https://gitee.com/ascend/tools/tree/master/msame) + + 将msame文件放到当前工作目录 + +### 2. 离线推理 + +710上执行,执行时使npu-smi info查看设备状态,确保device空闲 + +```bash +bash test/pth2om.sh --batch_size=1 +bash test/eval_acc_perf.sh --datasets_path=/root/datasets/coco --batch_size=1 +``` + +**评测结果:** + +| 模型 | pth精度 | 710离线推理精度 | 性能基准 | 710性能 | +| ----------- | --------- | --------------- | --------- | ------- | +| UniFormer bs1 | AP50=93.6 | AP50=93.5 | 88.914 fps | 162.601 fps | +| UniFormer bs16 | AP50=93.6 | AP50=93.5 | 116.939 fps | 277.441 fps | + +**说明:** +使用COCO数据集的person_keypoints_val2017.json中的边界框标注,而非配置文件的COCO_val2017_detections_AP_H_56_person.json,因为后者中有非常多不含人的边界框,导致推理数据量过大且精度低 \ No newline at end of file diff --git a/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/requirements.txt b/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/requirements.txt new file mode 100644 index 0000000000..5e0f1a4c09 --- /dev/null +++ b/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/requirements.txt @@ -0,0 +1,6 @@ +torch==1.8.0 +torchvision==0.9.0 +numpy +opencv-python +onnx +onnxruntime \ No newline at end of file diff --git a/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/test/bin_util.py b/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/test/bin_util.py new file mode 100644 index 0000000000..d8683f546b --- /dev/null +++ b/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/test/bin_util.py @@ -0,0 +1,79 @@ +# Copyright 2022 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import numpy as np +from argparse import ArgumentParser + + +def pack(input_path, output_path, meta_path, batch_size): + os.makedirs(output_path, exist_ok=True) + file_list = os.listdir(input_path) + meta = [] + + for i in range(0, len(file_list), batch_size): + batch_list = file_list[i:i+batch_size] + batch_list = batch_list + (batch_size - len(batch_list)) * [batch_list[-1]] + batch_img = [] + for file in batch_list: + img = np.fromfile(os.path.join(input_path, file), dtype=np.float32) + batch_img.append(img) + + np.array(batch_img, dtype=np.float32).tofile(os.path.join(output_path, f'{i//batch_size}.bin')) + meta.append(','.join(batch_list)) + + with open(meta_path, 'w') as f: + f.writelines([f'{m}\n' for m in meta]) + + +def unpack(input_path, output_path, meta_path, batch_size): + latest_result = os.listdir(input_path) + latest_result.sort() + input_path = os.path.join(input_path, latest_result[-1]) + output_path = os.path.join(output_path, latest_result[-1]) + os.makedirs(output_path, exist_ok=True) + + lines = [] + with open(meta_path, 'r') as f: + lines = f.readlines() + for i, line in enumerate(lines): + line = line.rstrip() + batch_img = np.fromfile(os.path.join(input_path, f'{i}_output_0.bin'), dtype=np.float32) + batch_img = np.reshape(batch_img, [batch_size, -1]) + for img, name in zip(batch_img, line.split(',')): + img.tofile(os.path.join(output_path, f'{name[:-4]}_output_0.bin')) + + +def main(): + parser = ArgumentParser() + parser.add_argument('--pack', help='pack bin files to batch', + action='store_true') + parser.add_argument('--unpack', help='unpack batch to bin files', + action='store_true') + parser.add_argument('--input', help='input bin file path') + parser.add_argument('--output', help='output bin file path') + parser.add_argument('--meta', help='meta file path', + default='meta.txt') + parser.add_argument('--batch_size', help='batch size', + type=int, default=1) + args = parser.parse_args() + + if args.pack: + pack(args.input, args.output, args.meta, args.batch_size) + elif args.unpack: + unpack(args.input, args.output, args.meta, args.batch_size) + + +if __name__ == '__main__': + main() diff --git a/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/test/eval_acc_perf.sh b/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/test/eval_acc_perf.sh new file mode 100644 index 0000000000..63e2ece29f --- /dev/null +++ b/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/test/eval_acc_perf.sh @@ -0,0 +1,59 @@ +#!/bin/bash + +set -eu + +datasets_path="/root/datasets/coco" +batch_size=1 + +for para in $* +do + if [[ $para == --datasets_path* ]]; then + datasets_path=`echo ${para#*=}` + fi + if [[ $para == --batch_size* ]]; then + batch_size=`echo ${para#*=}` + fi +done + +echo "==== preprocess ====" +rm -rf val2017_bin +python uniformer_preprocess.py --dataset=${datasets_path} + +if [ $? != 0 ]; then + echo "fail!" + exit -1 +fi + +source /usr/local/Ascend/ascend-toolkit/set_env.sh + +echo "==== inference ====" +rm -rf result +if [ $batch_size == 1 ]; then + ./msame --model=uniformer_bs1.om --input=val2017_bin --output=result + + if [ $? != 0 ]; then + echo "fail!" + exit -1 + fi +else + rm -rf val2017_bin_packed result_packed + python test/bin_util.py --pack --input=val2017_bin --output=val2017_bin_packed --batch_size=$batch_size + ./msame --model=uniformer_bs$batch_size.om --input=val2017_bin_packed --output=result_packed + python test/bin_util.py --unpack --input=result_packed --output=result --batch_size=$batch_size + + if [ $? != 0 ]; then + echo "fail!" + exit -1 + fi +fi + +echo "==== postprocess ====" +rm -rf tmp +python uniformer_postprocess.py --dataset=${datasets_path} + +if [ $? != 0 ]; then + echo "fail!" + exit -1 +fi + +echo "success" diff --git a/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/test/pth2om.sh b/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/test/pth2om.sh new file mode 100644 index 0000000000..d0fb930b85 --- /dev/null +++ b/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/test/pth2om.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +set -eu +batch_size=1 + +for para in $* +do + if [[ $para == --batch_size* ]]; then + batch_size=`echo ${para#*=}` + fi +done + +rm -f uniformer_dybs.onnx +cd UniFormer/pose_estimation + +python tools/pytorch2onnx.py \ + exp/top_down_256x192_global_base/config.py \ + ../../top_down_256x192_global_base.pth \ + --output-file \ + ../../uniformer_dybs.onnx + +if [ $? != 0 ]; then + echo "fail!" + exit -1 +fi + +cd ../.. +rm -f uniformer_bs$batch_size.om +source /usr/local/Ascend/ascend-toolkit/set_env.sh + +atc --framework=5 --model=uniformer_dybs.onnx --output=uniformer_bs$batch_size --input_format=NCHW \ + --input_shape="input:$batch_size,3,256,192" --log=error --soc_version=Ascend710 + +if [ -f "uniformer_bs$batch_size.om" ]; then + echo "success" +else + echo "fail!" +fi diff --git a/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/uniformer.patch b/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/uniformer.patch new file mode 100644 index 0000000000..8f077541d8 --- /dev/null +++ b/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/uniformer.patch @@ -0,0 +1,119 @@ +diff --git a/pose_estimation/exp/top_down_256x192_global_base/config.py b/pose_estimation/exp/top_down_256x192_global_base/config.py +index 93a237c..ba81854 100644 +--- a/pose_estimation/exp/top_down_256x192_global_base/config.py ++++ b/pose_estimation/exp/top_down_256x192_global_base/config.py +@@ -65,7 +65,7 @@ model = dict( + loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True)), + train_cfg=dict(), + test_cfg=dict( +- flip_test=True, ++ flip_test=False, + post_process='default', + shift_heatmap=True, + modulate_kernel=11)) +@@ -82,7 +82,7 @@ data_cfg = dict( + nms_thr=1.0, + oks_thr=0.9, + vis_thr=0.2, +- use_gt_bbox=False, ++ use_gt_bbox=True, + det_bbox_thr=0.0, + bbox_file=f'data/coco/person_detection_results/COCO_val2017_detections_AP_H_56_person.json', + ) +diff --git a/pose_estimation/mmpose/datasets/__init__.py b/pose_estimation/mmpose/datasets/__init__.py +index 6c1f409..a0fc424 100644 +--- a/pose_estimation/mmpose/datasets/__init__.py ++++ b/pose_estimation/mmpose/datasets/__init__.py +@@ -14,7 +14,7 @@ from .datasets import ( # isort:skip + TopDownFreiHandDataset, TopDownJhmdbDataset, TopDownMhpDataset, + TopDownMpiiDataset, TopDownMpiiTrbDataset, TopDownOCHumanDataset, + TopDownOneHand10KDataset, TopDownPanopticDataset, +- TopDownPoseTrack18Dataset) ++ ) + + __all__ = [ + 'AnimalATRWDataset', 'TopDownCocoDataset', 'BottomUpCocoDataset', +@@ -25,7 +25,7 @@ __all__ = [ + 'MeshMixDataset', 'MoshDataset', 'MeshAdversarialDataset', + 'TopDownCrowdPoseDataset', 'BottomUpCrowdPoseDataset', + 'TopDownFreiHandDataset', 'TopDownOneHand10KDataset', +- 'TopDownPanopticDataset', 'TopDownPoseTrack18Dataset', ++ 'TopDownPanopticDataset', + 'TopDownJhmdbDataset', 'TopDownMhpDataset', 'Face300WDataset', + 'AnimalHorse10Dataset', 'AnimalMacaqueDataset', 'AnimalFlyDataset', + 'AnimalLocustDataset', 'AnimalZebraDataset', 'build_dataloader', +diff --git a/pose_estimation/mmpose/datasets/datasets/__init__.py b/pose_estimation/mmpose/datasets/datasets/__init__.py +index df787f0..e4d23e8 100644 +--- a/pose_estimation/mmpose/datasets/datasets/__init__.py ++++ b/pose_estimation/mmpose/datasets/datasets/__init__.py +@@ -17,7 +17,7 @@ from .top_down import (TopDownAicDataset, TopDownCocoDataset, + TopDownCocoWholeBodyDataset, TopDownCrowdPoseDataset, + TopDownJhmdbDataset, TopDownMhpDataset, + TopDownMpiiDataset, TopDownMpiiTrbDataset, +- TopDownOCHumanDataset, TopDownPoseTrack18Dataset) ++ TopDownOCHumanDataset) + + __all__ = [ + 'TopDownCocoDataset', 'BottomUpCocoDataset', 'BottomUpMhpDataset', +@@ -28,7 +28,7 @@ __all__ = [ + 'MeshMixDataset', 'MoshDataset', 'MeshAdversarialDataset', + 'TopDownCrowdPoseDataset', 'BottomUpCrowdPoseDataset', + 'TopDownFreiHandDataset', 'TopDownOneHand10KDataset', +- 'TopDownPanopticDataset', 'TopDownPoseTrack18Dataset', ++ 'TopDownPanopticDataset', + 'TopDownJhmdbDataset', 'TopDownMhpDataset', 'DeepFashionDataset', + 'Face300WDataset', 'FaceAFLWDataset', 'FaceWFLWDataset', 'FaceCOFWDataset', + 'Body3DH36MDataset', 'AnimalHorse10Dataset', 'AnimalMacaqueDataset', +diff --git a/pose_estimation/mmpose/datasets/datasets/top_down/__init__.py b/pose_estimation/mmpose/datasets/datasets/top_down/__init__.py +index 7342291..d9a80a5 100644 +--- a/pose_estimation/mmpose/datasets/datasets/top_down/__init__.py ++++ b/pose_estimation/mmpose/datasets/datasets/top_down/__init__.py +@@ -7,11 +7,11 @@ from .topdown_mhp_dataset import TopDownMhpDataset + from .topdown_mpii_dataset import TopDownMpiiDataset + from .topdown_mpii_trb_dataset import TopDownMpiiTrbDataset + from .topdown_ochuman_dataset import TopDownOCHumanDataset +-from .topdown_posetrack18_dataset import TopDownPoseTrack18Dataset ++# from .topdown_posetrack18_dataset import TopDownPoseTrack18Dataset + + __all__ = [ + 'TopDownAicDataset', 'TopDownCocoDataset', 'TopDownCocoWholeBodyDataset', + 'TopDownCrowdPoseDataset', 'TopDownMpiiDataset', 'TopDownMpiiTrbDataset', +- 'TopDownOCHumanDataset', 'TopDownPoseTrack18Dataset', ++ 'TopDownOCHumanDataset', + 'TopDownJhmdbDataset', 'TopDownMhpDataset' + ] +diff --git a/pose_estimation/mmpose/models/backbones/__init__.py b/pose_estimation/mmpose/models/backbones/__init__.py +index e7ced1d..19dff10 100644 +--- a/pose_estimation/mmpose/models/backbones/__init__.py ++++ b/pose_estimation/mmpose/models/backbones/__init__.py +@@ -42,6 +42,6 @@ __all__ = [ + "VGG", + "TCN", + "HRT", +- "VisionTransformer", ++ # "VisionTransformer", + "UniFormer" + ] +diff --git a/pose_estimation/tools/pytorch2onnx.py b/pose_estimation/tools/pytorch2onnx.py +index 9ebd3fe..35b7d59 100644 +--- a/pose_estimation/tools/pytorch2onnx.py ++++ b/pose_estimation/tools/pytorch2onnx.py +@@ -63,11 +63,18 @@ def pytorch2onnx(model, + + one_img = torch.randn(input_shape) + ++ input_names = ["input"] ++ output_names = ["heatmap"] ++ dynamic_axes = {'input': {0: '-1'}, 'heatmap': {0: '-1'}} ++ + register_extra_symbolics(opset_version) + torch.onnx.export( + model, + one_img, + output_file, ++ input_names=input_names, ++ output_names=output_names, ++ dynamic_axes = dynamic_axes, + export_params=True, + keep_initializers_as_inputs=True, + verbose=show, diff --git a/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/uniformer_postprocess.py b/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/uniformer_postprocess.py new file mode 100644 index 0000000000..b24e6790c1 --- /dev/null +++ b/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/uniformer_postprocess.py @@ -0,0 +1,118 @@ +# Copyright 2022 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import mmcv +import numpy as np +from argparse import ArgumentParser +from mmpose.datasets import TopDownCocoDataset +from mmpose.core.evaluation import keypoints_from_heatmaps + + +def _box2cs(box, image_size): + x, y, w, h = box[:4] + + aspect_ratio = 1. * image_size[0] / image_size[1] + center = np.zeros((2), dtype=np.float32) + center[0] = x + w * 0.5 + center[1] = y + h * 0.5 + + if w > aspect_ratio * h: + h = w * 1.0 / aspect_ratio + elif w < aspect_ratio * h: + w = h * aspect_ratio + scale = np.array([w * 1.0 / 200.0, h * 1.0 / 200.0], dtype=np.float32) + scale = scale * 1.25 + return center, scale + + +def main(): + parser = ArgumentParser() + parser.add_argument('--config', help='config file path', + default='UniFormer/pose_estimation/exp/top_down_256x192_global_base/config.py') + parser.add_argument('--dataset', help='dataset path', + default='data/coco') + parser.add_argument('--bin', help='result bin file path', + default='result') + args = parser.parse_args() + + dataset_path = args.dataset + bin_path = args.bin + latest_result = os.listdir(bin_path) + latest_result.sort() + bin_path = os.path.join(bin_path, latest_result[-1]) + + cfg = mmcv.Config.fromfile(args.config) + image_size = cfg.data_cfg['image_size'] + heatmap_size = cfg.data_cfg['heatmap_size'] + ann_file = os.path.join(dataset_path, 'annotations/person_keypoints_val2017.json') + img_prefix = os.path.join(dataset_path, 'val2017/') + + dataset = TopDownCocoDataset( + ann_file=ann_file, + img_prefix=img_prefix, + data_cfg=cfg.data_cfg, + pipeline=[], + test_mode=True) + coco = dataset.coco + + outputs = [] + + # process each image + for image_id in coco.imgs.keys(): + # get bounding box annotations + image = coco.loadImgs(image_id)[0] + image_name = os.path.join(img_prefix, image['file_name']) + ann_ids = coco.getAnnIds(image_id, iscrowd=False) + + output = {'preds': [], 'boxes': [], 'image_paths': [], + 'output_heatmap': None, 'bbox_ids': []} + + for ann_id in ann_ids: + ann = coco.anns[ann_id] + # no keypoints, skip + if 'keypoints' not in ann: + continue + if max(ann['keypoints']) == 0: + continue + if 'num_keypoints' in ann and ann['num_keypoints'] == 0: + continue + + # bbox format is 'xywh' + bbox = ann['bbox'] + center, scale = _box2cs(bbox, image_size) + + heatmap = np.fromfile(os.path.join( + bin_path, f'{ann_id}_output_0.bin'), dtype=np.float32) + heatmap = np.reshape( + heatmap, [1, 17, heatmap_size[1], heatmap_size[0]]) + + preds, maxvals = keypoints_from_heatmaps( + heatmap, [center], [scale]) + keypoints = np.concatenate((preds, maxvals), axis=2) + + output['preds'].append(keypoints[0]) + output['boxes'].append(np.array( + [center[0], center[1], scale[0], scale[1], scale[0] * scale[1] * 200 * 200, 1.0])) + output['image_paths'].append(image_name) + output['bbox_ids'].append(len(output['bbox_ids'])) + + outputs.append(output) + + os.makedirs('tmp', exist_ok=True) + dataset.evaluate(outputs, 'tmp', 'mAP') + + +if __name__ == '__main__': + main() diff --git a/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/uniformer_preprocess.py b/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/uniformer_preprocess.py new file mode 100644 index 0000000000..de54482bfa --- /dev/null +++ b/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/uniformer_preprocess.py @@ -0,0 +1,106 @@ +# Copyright 2022 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import cv2 +import mmcv +import numpy as np +from argparse import ArgumentParser +from xtcocotools.coco import COCO +from mmpose.core.post_processing import get_affine_transform +from tqdm import tqdm + + +def _box2cs(box, image_size): + x, y, w, h = box[:4] + + aspect_ratio = 1. * image_size[0] / image_size[1] + center = np.zeros((2), dtype=np.float32) + center[0] = x + w * 0.5 + center[1] = y + h * 0.5 + + if w > aspect_ratio * h: + h = w * 1.0 / aspect_ratio + elif w < aspect_ratio * h: + w = h * aspect_ratio + scale = np.array([w * 1.0 / 200.0, h * 1.0 / 200.0], dtype=np.float32) + scale = scale * 1.25 + return center, scale + + +def main(): + parser = ArgumentParser() + parser.add_argument('--config', help='config file path', + default='UniFormer/pose_estimation/exp/top_down_256x192_global_base/config.py') + parser.add_argument('--dataset', help='dataset path', + default='data/coco') + parser.add_argument('--bin', help='preprocessed bin file path', + default='val2017_bin') + args = parser.parse_args() + + dataset_path = args.dataset + bin_path = args.bin + os.makedirs(bin_path, exist_ok=True) + + cfg = mmcv.Config.fromfile(args.config) + image_size = cfg.data_cfg['image_size'] + ann_file = os.path.join(dataset_path, 'annotations/person_keypoints_val2017.json') + img_prefix = os.path.join(dataset_path, 'val2017') + + coco = COCO(ann_file) + + # process each image + for image_id in tqdm(coco.imgs.keys()): + # get bounding box annotations + image = coco.loadImgs(image_id)[0] + # print(image) + image_name = os.path.join(img_prefix, image['file_name']) + ori_img = mmcv.imread(image_name) + ann_ids = coco.getAnnIds(image_id, iscrowd=False) + + for ann_id in ann_ids: + ann = coco.anns[ann_id] + # no keypoints, skip + if 'keypoints' not in ann: + continue + if max(ann['keypoints']) == 0: + continue + if 'num_keypoints' in ann and ann['num_keypoints'] == 0: + continue + + # bbox format is 'xywh' + bbox = ann['bbox'] + center, scale = _box2cs(bbox, image_size) + + img = ori_img.copy() + # TopDownAffine + trans = get_affine_transform(center, scale, 0, image_size) + img = cv2.warpAffine( + img, + trans, (int(image_size[0]), int(image_size[1])), + flags=cv2.INTER_LINEAR) + + # NormalizeTensor + mean = np.array([0.485, 0.456, 0.406]) * 255 + std = np.array([0.229, 0.224, 0.225]) * 255 + img = mmcv.imnormalize(img, mean, std) + + img = img.transpose(2, 0, 1) + img = np.expand_dims(img, 0) + + img.tofile(os.path.join(bin_path, f'{ann_id}.bin')) + + +if __name__ == '__main__': + main() -- Gitee From aff7fc91ddb4b87114166803813052f14cbe016d Mon Sep 17 00:00:00 2001 From: Victor Chen <44614525@qq.com> Date: Mon, 18 Apr 2022 15:31:05 +0800 Subject: [PATCH 2/2] update dataset path and reduce code --- .../cv/pose_estimation/UniFormer/readme.md | 4 ++-- .../UniFormer/test/eval_acc_perf.sh | 2 +- .../UniFormer/uniformer_preprocess.py | 20 ++----------------- 3 files changed, 5 insertions(+), 21 deletions(-) diff --git a/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/readme.md b/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/readme.md index 709c35794c..016d16e098 100644 --- a/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/readme.md +++ b/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/readme.md @@ -26,7 +26,7 @@ cd ../.. 4. 数据集 - 获取COCO数据集,并重命名为coco,放到/root/datasets目录 + 获取COCO数据集,并重命名为coco,放到当前目录的data目录下 5. [获取msame工具](https://gitee.com/ascend/tools/tree/master/msame) @@ -38,7 +38,7 @@ cd ../.. ```bash bash test/pth2om.sh --batch_size=1 -bash test/eval_acc_perf.sh --datasets_path=/root/datasets/coco --batch_size=1 +bash test/eval_acc_perf.sh --datasets_path=data/coco --batch_size=1 ``` **评测结果:** diff --git a/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/test/eval_acc_perf.sh b/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/test/eval_acc_perf.sh index 63e2ece29f..ab10278472 100644 --- a/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/test/eval_acc_perf.sh +++ b/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/test/eval_acc_perf.sh @@ -2,7 +2,7 @@ set -eu -datasets_path="/root/datasets/coco" +datasets_path="data/coco" batch_size=1 for para in $* diff --git a/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/uniformer_preprocess.py b/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/uniformer_preprocess.py index de54482bfa..7cc5334fc9 100644 --- a/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/uniformer_preprocess.py +++ b/ACL_PyTorch/contrib/cv/pose_estimation/UniFormer/uniformer_preprocess.py @@ -19,26 +19,10 @@ import numpy as np from argparse import ArgumentParser from xtcocotools.coco import COCO from mmpose.core.post_processing import get_affine_transform +from mmpose.apis.inference import _box2cs from tqdm import tqdm -def _box2cs(box, image_size): - x, y, w, h = box[:4] - - aspect_ratio = 1. * image_size[0] / image_size[1] - center = np.zeros((2), dtype=np.float32) - center[0] = x + w * 0.5 - center[1] = y + h * 0.5 - - if w > aspect_ratio * h: - h = w * 1.0 / aspect_ratio - elif w < aspect_ratio * h: - w = h * aspect_ratio - scale = np.array([w * 1.0 / 200.0, h * 1.0 / 200.0], dtype=np.float32) - scale = scale * 1.25 - return center, scale - - def main(): parser = ArgumentParser() parser.add_argument('--config', help='config file path', @@ -81,7 +65,7 @@ def main(): # bbox format is 'xywh' bbox = ann['bbox'] - center, scale = _box2cs(bbox, image_size) + center, scale = _box2cs(cfg, bbox) img = ori_img.copy() # TopDownAffine -- Gitee