未验证 提交 0a26a1fa 编写于 作者: jm_12138's avatar jm_12138 提交者: GitHub

update human_pose_estimation_resnet50_mpii (#1961)

* update human_pose_estimation_resnet50_mpii

* update

* add clean func

* update save inference model
上级 a223025d
......@@ -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
```
......@@ -5,7 +5,6 @@ from collections import OrderedDict
import cv2
import numpy as np
from PIL import Image
__all__ = ['reader']
......
......@@ -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):
"""
......
# 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
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()
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册