From 0a26a1fabfa7f2d0a8239498f1da79e1b47a57ae Mon Sep 17 00:00:00 2001 From: jm12138 <2286040843@qq.com> Date: Fri, 16 Sep 2022 15:16:39 +0800 Subject: [PATCH] update human_pose_estimation_resnet50_mpii (#1961) * update human_pose_estimation_resnet50_mpii * update * add clean func * update save inference model --- .../README.md | 16 +- .../data_feed.py | 1 - .../module.py | 61 +++---- .../pose_resnet.py | 157 ------------------ .../test.py | 83 +++++++++ 5 files changed, 114 insertions(+), 204 deletions(-) delete mode 100644 modules/image/keypoint_detection/human_pose_estimation_resnet50_mpii/pose_resnet.py create mode 100644 modules/image/keypoint_detection/human_pose_estimation_resnet50_mpii/test.py diff --git a/modules/image/keypoint_detection/human_pose_estimation_resnet50_mpii/README.md b/modules/image/keypoint_detection/human_pose_estimation_resnet50_mpii/README.md index 7bb49522..ad3b7c7c 100644 --- a/modules/image/keypoint_detection/human_pose_estimation_resnet50_mpii/README.md +++ b/modules/image/keypoint_detection/human_pose_estimation_resnet50_mpii/README.md @@ -89,20 +89,14 @@ - data (OrderedDict): 人体骨骼关键点的坐标。 - ```python - def save_inference_model(dirname, - model_filename=None, - params_filename=None, - combined=True): + def save_inference_model(dirname): ``` - 将模型保存到指定路径。 - **参数** - - dirname: 存在模型的目录名称 - - model_filename: 模型文件名称,默认为__model__ - - params_filename: 参数文件名称,默认为__params__(仅当combined为True时生效) - - combined: 是否将参数保存到统一的一个文件中 + - dirname: 模型保存路径 ## 四、服务部署 @@ -155,6 +149,10 @@ * 1.1.1 +* 1.2.0 + + 移除 fluid api + * ```shell - $ hub install human_pose_estimation_resnet50_mpii==1.1.1 + $ hub install human_pose_estimation_resnet50_mpii==1.2.0 ``` diff --git a/modules/image/keypoint_detection/human_pose_estimation_resnet50_mpii/data_feed.py b/modules/image/keypoint_detection/human_pose_estimation_resnet50_mpii/data_feed.py index a86e90cf..ab9d57a6 100644 --- a/modules/image/keypoint_detection/human_pose_estimation_resnet50_mpii/data_feed.py +++ b/modules/image/keypoint_detection/human_pose_estimation_resnet50_mpii/data_feed.py @@ -5,7 +5,6 @@ from collections import OrderedDict import cv2 import numpy as np -from PIL import Image __all__ = ['reader'] diff --git a/modules/image/keypoint_detection/human_pose_estimation_resnet50_mpii/module.py b/modules/image/keypoint_detection/human_pose_estimation_resnet50_mpii/module.py index 43bf5b84..e7a8e19e 100644 --- a/modules/image/keypoint_detection/human_pose_estimation_resnet50_mpii/module.py +++ b/modules/image/keypoint_detection/human_pose_estimation_resnet50_mpii/module.py @@ -6,15 +6,15 @@ import ast import os import argparse +import paddle +import paddle.jit +import paddle.static import numpy as np -import paddle.fluid as fluid -import paddlehub as hub -from paddle.fluid.core import PaddleTensor, AnalysisConfig, create_paddle_predictor +from paddle.inference import Config, create_predictor from paddlehub.module.module import moduleinfo, runnable, serving -from human_pose_estimation_resnet50_mpii.processor import base64_to_cv2, postprocess -from human_pose_estimation_resnet50_mpii.data_feed import reader -from human_pose_estimation_resnet50_mpii.pose_resnet import ResNet +from .processor import base64_to_cv2, postprocess +from .data_feed import reader @moduleinfo( @@ -24,20 +24,22 @@ from human_pose_estimation_resnet50_mpii.pose_resnet import ResNet author_email="paddle-dev@baidu.comi", summary= "Paddle implementation for the paper `Simple baselines for human pose estimation and tracking`, trained with the MPII dataset.", - version="1.1.1") -class HumanPoseEstimation(hub.Module): - def _initialize(self): - self.default_pretrained_model_path = os.path.join(self.directory, "pose-resnet50-mpii-384x384") + version="1.2.0") +class HumanPoseEstimation: + def __init__(self): + self.default_pretrained_model_path = os.path.join(self.directory, "pose-resnet50-mpii-384x384", "model") self._set_config() def _set_config(self): """ predictor config setting """ - cpu_config = AnalysisConfig(self.default_pretrained_model_path) + model = self.default_pretrained_model_path+'.pdmodel' + params = self.default_pretrained_model_path+'.pdiparams' + cpu_config = Config(model, params) cpu_config.disable_glog_info() cpu_config.disable_gpu() - self.cpu_predictor = create_paddle_predictor(cpu_config) + self.cpu_predictor = create_predictor(cpu_config) try: _places = os.environ["CUDA_VISIBLE_DEVICES"] @@ -46,10 +48,10 @@ class HumanPoseEstimation(hub.Module): except: use_gpu = False if use_gpu: - gpu_config = AnalysisConfig(self.default_pretrained_model_path) + gpu_config = Config(model, params) gpu_config.disable_glog_info() gpu_config.enable_use_gpu(memory_pool_init_size_mb=1000, device_id=0) - self.gpu_predictor = create_paddle_predictor(gpu_config) + self.gpu_predictor = create_predictor(gpu_config) def keypoint_detection(self, images=None, @@ -80,7 +82,6 @@ class HumanPoseEstimation(hub.Module): total_num = len(all_data) loop_num = int(np.ceil(total_num / batch_size)) - res = list() for iter_id in range(loop_num): batch_data = list() @@ -92,9 +93,14 @@ class HumanPoseEstimation(hub.Module): pass # feed batch image batch_image = np.array([data['image'] for data in batch_data]) - batch_image = PaddleTensor(batch_image.copy()) - output = self.gpu_predictor.run([batch_image]) if use_gpu else self.cpu_predictor.run([batch_image]) - output = np.expand_dims(output[0].as_ndarray(), axis=1) + predictor = self.gpu_predictor if use_gpu else self.cpu_predictor + input_names = predictor.get_input_names() + input_handle = predictor.get_input_handle(input_names[0]) + input_handle.copy_from_cpu(batch_image) + predictor.run() + output_names = predictor.get_output_names() + output_handle = predictor.get_output_handle(output_names[0]) + output = np.expand_dims(output_handle.copy_to_cpu(), axis=1) # postprocess one by one for i in range(len(batch_data)): out = postprocess( @@ -107,25 +113,6 @@ class HumanPoseEstimation(hub.Module): res.append(out) return res - def save_inference_model(self, dirname, model_filename=None, params_filename=None, combined=True): - if combined: - model_filename = "__model__" if not model_filename else model_filename - params_filename = "__params__" if not params_filename else params_filename - place = fluid.CPUPlace() - exe = fluid.Executor(place) - - program, feeded_var_names, target_vars = fluid.io.load_inference_model( - dirname=self.default_pretrained_model_path, executor=exe) - - fluid.io.save_inference_model( - dirname=dirname, - main_program=program, - executor=exe, - feeded_var_names=feeded_var_names, - target_vars=target_vars, - model_filename=model_filename, - params_filename=params_filename) - @serving def serving_method(self, images, **kwargs): """ diff --git a/modules/image/keypoint_detection/human_pose_estimation_resnet50_mpii/pose_resnet.py b/modules/image/keypoint_detection/human_pose_estimation_resnet50_mpii/pose_resnet.py deleted file mode 100644 index f5a7638a..00000000 --- a/modules/image/keypoint_detection/human_pose_estimation_resnet50_mpii/pose_resnet.py +++ /dev/null @@ -1,157 +0,0 @@ -# coding=utf-8 -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - -import paddle.fluid as fluid - -__all__ = ["ResNet", "ResNet50", "ResNet101", "ResNet152"] - -BN_MOMENTUM = 0.9 - - -class ResNet(): - def __init__(self, layers=50, kps_num=16, test_mode=False): - """ - :param layers: int, the layers number which is used here - :param kps_num: int, the number of keypoints in accord with the dataset - :param test_mode: bool, if True, only return output heatmaps, no loss - - :return: loss, output heatmaps - """ - self.k = kps_num - self.layers = layers - self.test_mode = test_mode - - def net(self, input, target=None, target_weight=None): - layers = self.layers - supported_layers = [50, 101, 152] - assert layers in supported_layers, \ - "supported layers are {} but input layer is {}".format(supported_layers, layers) - - if layers == 50: - depth = [3, 4, 6, 3] - elif layers == 101: - depth = [3, 4, 23, 3] - elif layers == 152: - depth = [3, 8, 36, 3] - num_filters = [64, 128, 256, 512] - - conv = self.conv_bn_layer(input=input, num_filters=64, filter_size=7, stride=2, act='relu') - conv = fluid.layers.pool2d(input=conv, pool_size=3, pool_stride=2, pool_padding=1, pool_type='max') - - for block in range(len(depth)): - for i in range(depth[block]): - conv = self.bottleneck_block( - input=conv, num_filters=num_filters[block], stride=2 if i == 0 and block != 0 else 1) - - conv = fluid.layers.conv2d_transpose( - input=conv, - num_filters=256, - filter_size=4, - padding=1, - stride=2, - param_attr=fluid.param_attr.ParamAttr(initializer=fluid.initializer.Normal(0., 0.001)), - act=None, - bias_attr=False) - conv = fluid.layers.batch_norm(input=conv, act='relu', momentum=BN_MOMENTUM) - conv = fluid.layers.conv2d_transpose( - input=conv, - num_filters=256, - filter_size=4, - padding=1, - stride=2, - param_attr=fluid.param_attr.ParamAttr(initializer=fluid.initializer.Normal(0., 0.001)), - act=None, - bias_attr=False) - conv = fluid.layers.batch_norm(input=conv, act='relu', momentum=BN_MOMENTUM) - conv = fluid.layers.conv2d_transpose( - input=conv, - num_filters=256, - filter_size=4, - padding=1, - stride=2, - param_attr=fluid.param_attr.ParamAttr(initializer=fluid.initializer.Normal(0., 0.001)), - act=None, - bias_attr=False) - conv = fluid.layers.batch_norm(input=conv, act='relu', momentum=BN_MOMENTUM) - - out = fluid.layers.conv2d( - input=conv, - num_filters=self.k, - filter_size=1, - stride=1, - padding=0, - act=None, - param_attr=fluid.param_attr.ParamAttr(initializer=fluid.initializer.Normal(0., 0.001))) - - if self.test_mode: - return out - else: - loss = self.calc_loss(out, target, target_weight) - return loss, out - - def conv_bn_layer(self, input, num_filters, filter_size, stride=1, groups=1, act=None): - conv = fluid.layers.conv2d( - input=input, - num_filters=num_filters, - filter_size=filter_size, - stride=stride, - padding=(filter_size - 1) // 2, - groups=groups, - param_attr=fluid.param_attr.ParamAttr(initializer=fluid.initializer.Normal(0., 0.001)), - act=None, - bias_attr=False) - return fluid.layers.batch_norm(input=conv, act=act, momentum=BN_MOMENTUM) - - def shortcut(self, input, ch_out, stride): - ch_in = input.shape[1] - if ch_in != ch_out or stride != 1: - return self.conv_bn_layer(input, ch_out, 1, stride) - else: - return input - - def calc_loss(self, heatmap, target, target_weight): - _, c, h, w = heatmap.shape - x = fluid.layers.reshape(heatmap, (-1, self.k, h * w)) - y = fluid.layers.reshape(target, (-1, self.k, h * w)) - w = fluid.layers.reshape(target_weight, (-1, self.k)) - - x = fluid.layers.split(x, num_or_sections=self.k, dim=1) - y = fluid.layers.split(y, num_or_sections=self.k, dim=1) - w = fluid.layers.split(w, num_or_sections=self.k, dim=1) - - _list = [] - for idx in range(self.k): - _tmp = fluid.layers.scale(x=x[idx] - y[idx], scale=1.) - _tmp = _tmp * _tmp - _tmp = fluid.layers.reduce_mean(_tmp, dim=2) - _list.append(_tmp * w[idx]) - - _loss = fluid.layers.concat(_list, axis=0) - _loss = fluid.layers.reduce_mean(_loss) - return 0.5 * _loss - - def bottleneck_block(self, input, num_filters, stride): - conv0 = self.conv_bn_layer(input=input, num_filters=num_filters, filter_size=1, act='relu') - conv1 = self.conv_bn_layer(input=conv0, num_filters=num_filters, filter_size=3, stride=stride, act='relu') - conv2 = self.conv_bn_layer(input=conv1, num_filters=num_filters * 4, filter_size=1, act=None) - - short = self.shortcut(input, num_filters * 4, stride) - - return fluid.layers.elementwise_add(x=short, y=conv2, act='relu') - - -def ResNet50(): - model = ResNet(layers=50) - return model - - -def ResNet101(): - model = ResNet(layers=101) - return model - - -def ResNet152(): - model = ResNet(layers=152) - return model diff --git a/modules/image/keypoint_detection/human_pose_estimation_resnet50_mpii/test.py b/modules/image/keypoint_detection/human_pose_estimation_resnet50_mpii/test.py new file mode 100644 index 00000000..0878026b --- /dev/null +++ b/modules/image/keypoint_detection/human_pose_estimation_resnet50_mpii/test.py @@ -0,0 +1,83 @@ +import os +import shutil +import unittest + +import cv2 +import requests +import paddlehub as hub + + +os.environ['CUDA_VISIBLE_DEVICES'] = '0' + + +class TestHubModule(unittest.TestCase): + @classmethod + def setUpClass(cls) -> None: + img_url = 'https://ai-studio-static-online.cdn.bcebos.com/7799a8ccc5f6471b9d56fb6eff94f82a08b70ca2c7594d3f99877e366c0a2619' + if not os.path.exists('tests'): + os.makedirs('tests') + response = requests.get(img_url) + assert response.status_code == 200, 'Network Error.' + with open('tests/test.jpg', 'wb') as f: + f.write(response.content) + cls.module = hub.Module(name="human_pose_estimation_resnet50_mpii") + + @classmethod + def tearDownClass(cls) -> None: + shutil.rmtree('tests') + shutil.rmtree('inference') + shutil.rmtree('output_pose') + + def test_keypoint_detection1(self): + results = self.module.keypoint_detection( + paths=['tests/test.jpg'] + ) + kps = results[0]['data'] + self.assertIsInstance(kps, dict) + + def test_keypoint_detection2(self): + results = self.module.keypoint_detection( + images=[cv2.imread('tests/test.jpg')] + ) + kps = results[0]['data'] + self.assertIsInstance(kps, dict) + + def test_keypoint_detection3(self): + results = self.module.keypoint_detection( + images=[cv2.imread('tests/test.jpg')], + visualization=True + ) + kps = results[0]['data'] + self.assertIsInstance(kps, dict) + + def test_keypoint_detection4(self): + results = self.module.keypoint_detection( + images=[cv2.imread('tests/test.jpg')], + use_gpu=True + ) + kps = results[0]['data'] + self.assertIsInstance(kps, dict) + + def test_keypoint_detection5(self): + self.assertRaises( + AssertionError, + self.module.keypoint_detection, + paths=['no.jpg'] + ) + + def test_keypoint_detection6(self): + self.assertRaises( + AttributeError, + self.module.keypoint_detection, + images=['test.jpg'] + ) + + def test_save_inference_model(self): + self.module.save_inference_model('./inference/model') + + self.assertTrue(os.path.exists('./inference/model.pdmodel')) + self.assertTrue(os.path.exists('./inference/model.pdiparams')) + + +if __name__ == "__main__": + unittest.main() -- GitLab