Initial snapshot: hand motion pipeline (Dyn-HaMR + dex-retargeting + SPIDER)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+122
@@ -0,0 +1,122 @@
|
||||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
import numpy as np
|
||||
import torch
|
||||
|
||||
from mmpose.models.detectors import AssociativeEmbedding
|
||||
|
||||
|
||||
def test_ae_forward():
|
||||
model_cfg = dict(
|
||||
type='AssociativeEmbedding',
|
||||
pretrained=None,
|
||||
backbone=dict(type='ResNet', depth=18),
|
||||
keypoint_head=dict(
|
||||
type='AESimpleHead',
|
||||
in_channels=512,
|
||||
num_joints=17,
|
||||
num_deconv_layers=0,
|
||||
tag_per_joint=True,
|
||||
with_ae_loss=[True],
|
||||
extra=dict(final_conv_kernel=1, ),
|
||||
loss_keypoint=dict(
|
||||
type='MultiLossFactory',
|
||||
num_joints=17,
|
||||
num_stages=1,
|
||||
ae_loss_type='exp',
|
||||
with_ae_loss=[True],
|
||||
push_loss_factor=[0.001],
|
||||
pull_loss_factor=[0.001],
|
||||
with_heatmaps_loss=[True],
|
||||
heatmaps_loss_factor=[1.0])),
|
||||
train_cfg=dict(),
|
||||
test_cfg=dict(
|
||||
num_joints=17,
|
||||
max_num_people=30,
|
||||
scale_factor=[1],
|
||||
with_heatmaps=[True],
|
||||
with_ae=[True],
|
||||
project2image=True,
|
||||
nms_kernel=5,
|
||||
nms_padding=2,
|
||||
tag_per_joint=True,
|
||||
detection_threshold=0.1,
|
||||
tag_threshold=1,
|
||||
use_detection_val=True,
|
||||
ignore_too_much=False,
|
||||
adjust=True,
|
||||
refine=True,
|
||||
soft_nms=False,
|
||||
flip_test=True,
|
||||
post_process=True,
|
||||
shift_heatmap=True,
|
||||
use_gt_bbox=True,
|
||||
flip_pairs=[[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12],
|
||||
[13, 14], [15, 16]],
|
||||
))
|
||||
|
||||
detector = AssociativeEmbedding(model_cfg['backbone'],
|
||||
model_cfg['keypoint_head'],
|
||||
model_cfg['train_cfg'],
|
||||
model_cfg['test_cfg'],
|
||||
model_cfg['pretrained'])
|
||||
|
||||
detector.init_weights()
|
||||
|
||||
input_shape = (1, 3, 256, 256)
|
||||
mm_inputs = _demo_mm_inputs(input_shape)
|
||||
|
||||
imgs = mm_inputs.pop('imgs')
|
||||
target = mm_inputs.pop('target')
|
||||
mask = mm_inputs.pop('mask')
|
||||
joints = mm_inputs.pop('joints')
|
||||
img_metas = mm_inputs.pop('img_metas')
|
||||
|
||||
# Test forward train
|
||||
losses = detector.forward(
|
||||
imgs, target, mask, joints, img_metas, return_loss=True)
|
||||
assert isinstance(losses, dict)
|
||||
|
||||
# Test forward test
|
||||
with torch.no_grad():
|
||||
_ = detector.forward(imgs, img_metas=img_metas, return_loss=False)
|
||||
_ = detector.forward_dummy(imgs)
|
||||
|
||||
|
||||
def _demo_mm_inputs(input_shape=(1, 3, 256, 256)):
|
||||
"""Create a superset of inputs needed to run test or train batches.
|
||||
|
||||
Args:
|
||||
input_shape (tuple):
|
||||
input batch dimensions
|
||||
"""
|
||||
(N, C, H, W) = input_shape
|
||||
|
||||
rng = np.random.RandomState(0)
|
||||
|
||||
imgs = rng.rand(*input_shape)
|
||||
target = np.zeros([N, 17, H // 32, W // 32], dtype=np.float32)
|
||||
mask = np.ones([N, H // 32, W // 32], dtype=np.float32)
|
||||
joints = np.zeros([N, 30, 17, 2], dtype=np.float32)
|
||||
|
||||
img_metas = [{
|
||||
'image_file':
|
||||
'test.jpg',
|
||||
'aug_data': [torch.zeros(1, 3, 256, 256)],
|
||||
'test_scale_factor': [1],
|
||||
'base_size': (256, 256),
|
||||
'center':
|
||||
np.array([128, 128]),
|
||||
'scale':
|
||||
np.array([1.28, 1.28]),
|
||||
'flip_index':
|
||||
[0, 2, 1, 4, 3, 6, 5, 8, 7, 10, 9, 12, 11, 14, 13, 16, 15]
|
||||
} for _ in range(N)]
|
||||
|
||||
mm_inputs = {
|
||||
'imgs': torch.FloatTensor(imgs).requires_grad_(True),
|
||||
'target': [torch.FloatTensor(target)],
|
||||
'mask': [torch.FloatTensor(mask)],
|
||||
'joints': [torch.FloatTensor(joints)],
|
||||
'img_metas': img_metas
|
||||
}
|
||||
return mm_inputs
|
||||
+483
@@ -0,0 +1,483 @@
|
||||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
import numpy as np
|
||||
import pytest
|
||||
import torch
|
||||
|
||||
from mmpose.models import AEHigherResolutionHead, AESimpleHead
|
||||
|
||||
|
||||
def test_ae_simple_head():
|
||||
"""test bottom up AE simple head."""
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
# extra
|
||||
_ = AESimpleHead(
|
||||
in_channels=512,
|
||||
num_joints=17,
|
||||
with_ae_loss=[True],
|
||||
extra=[],
|
||||
loss_keypoint=dict(
|
||||
type='MultiLossFactory',
|
||||
num_joints=17,
|
||||
num_stages=1,
|
||||
ae_loss_type='exp',
|
||||
with_ae_loss=[True],
|
||||
push_loss_factor=[0.001],
|
||||
pull_loss_factor=[0.001],
|
||||
with_heatmaps_loss=[True],
|
||||
heatmaps_loss_factor=[1.0]))
|
||||
# test final_conv_kernel
|
||||
with pytest.raises(AssertionError):
|
||||
_ = AESimpleHead(
|
||||
in_channels=512,
|
||||
num_joints=17,
|
||||
with_ae_loss=[True],
|
||||
extra={'final_conv_kernel': -1},
|
||||
loss_keypoint=dict(
|
||||
type='MultiLossFactory',
|
||||
num_joints=17,
|
||||
num_stages=1,
|
||||
ae_loss_type='exp',
|
||||
with_ae_loss=[True],
|
||||
push_loss_factor=[0.001],
|
||||
pull_loss_factor=[0.001],
|
||||
with_heatmaps_loss=[True],
|
||||
heatmaps_loss_factor=[1.0]))
|
||||
head = AESimpleHead(
|
||||
in_channels=512,
|
||||
num_joints=17,
|
||||
with_ae_loss=[True],
|
||||
extra={'final_conv_kernel': 3},
|
||||
loss_keypoint=dict(
|
||||
type='MultiLossFactory',
|
||||
num_joints=17,
|
||||
num_stages=1,
|
||||
ae_loss_type='exp',
|
||||
with_ae_loss=[True],
|
||||
push_loss_factor=[0.001],
|
||||
pull_loss_factor=[0.001],
|
||||
with_heatmaps_loss=[True],
|
||||
heatmaps_loss_factor=[1.0]))
|
||||
head.init_weights()
|
||||
assert head.final_layer.padding == (1, 1)
|
||||
head = AESimpleHead(
|
||||
in_channels=512,
|
||||
num_joints=17,
|
||||
with_ae_loss=[True],
|
||||
extra={'final_conv_kernel': 1},
|
||||
loss_keypoint=dict(
|
||||
type='MultiLossFactory',
|
||||
num_joints=17,
|
||||
num_stages=1,
|
||||
ae_loss_type='exp',
|
||||
with_ae_loss=[True],
|
||||
push_loss_factor=[0.001],
|
||||
pull_loss_factor=[0.001],
|
||||
with_heatmaps_loss=[True],
|
||||
heatmaps_loss_factor=[1.0]))
|
||||
head.init_weights()
|
||||
assert head.final_layer.padding == (0, 0)
|
||||
head = AESimpleHead(
|
||||
in_channels=512,
|
||||
num_joints=17,
|
||||
with_ae_loss=[True],
|
||||
loss_keypoint=dict(
|
||||
type='MultiLossFactory',
|
||||
num_joints=17,
|
||||
num_stages=1,
|
||||
ae_loss_type='exp',
|
||||
with_ae_loss=[True],
|
||||
push_loss_factor=[0.001],
|
||||
pull_loss_factor=[0.001],
|
||||
with_heatmaps_loss=[True],
|
||||
heatmaps_loss_factor=[1.0]))
|
||||
head.init_weights()
|
||||
assert head.final_layer.padding == (0, 0)
|
||||
# test with_ae_loss
|
||||
head = AESimpleHead(
|
||||
in_channels=512,
|
||||
num_joints=17,
|
||||
num_deconv_layers=0,
|
||||
with_ae_loss=[True],
|
||||
extra={'final_conv_kernel': 3},
|
||||
loss_keypoint=dict(
|
||||
type='MultiLossFactory',
|
||||
num_joints=17,
|
||||
num_stages=1,
|
||||
ae_loss_type='exp',
|
||||
with_ae_loss=[True],
|
||||
push_loss_factor=[0.001],
|
||||
pull_loss_factor=[0.001],
|
||||
with_heatmaps_loss=[True],
|
||||
heatmaps_loss_factor=[1.0]))
|
||||
head.init_weights()
|
||||
input_shape = (1, 512, 32, 32)
|
||||
inputs = _demo_inputs(input_shape)
|
||||
out = head(inputs)
|
||||
assert out[0].shape == torch.Size([1, 34, 32, 32])
|
||||
head = AESimpleHead(
|
||||
in_channels=512,
|
||||
num_joints=17,
|
||||
num_deconv_layers=0,
|
||||
with_ae_loss=[False],
|
||||
extra={'final_conv_kernel': 3},
|
||||
loss_keypoint=dict(
|
||||
type='MultiLossFactory',
|
||||
num_joints=17,
|
||||
num_stages=1,
|
||||
ae_loss_type='exp',
|
||||
with_ae_loss=[True],
|
||||
push_loss_factor=[0.001],
|
||||
pull_loss_factor=[0.001],
|
||||
with_heatmaps_loss=[True],
|
||||
heatmaps_loss_factor=[1.0]))
|
||||
head.init_weights()
|
||||
input_shape = (1, 512, 32, 32)
|
||||
inputs = _demo_inputs(input_shape)
|
||||
out = head(inputs)
|
||||
assert out[0].shape == torch.Size([1, 17, 32, 32])
|
||||
# test tag_per_joint
|
||||
head = AESimpleHead(
|
||||
in_channels=512,
|
||||
num_joints=17,
|
||||
num_deconv_layers=0,
|
||||
tag_per_joint=False,
|
||||
with_ae_loss=[False],
|
||||
extra={'final_conv_kernel': 3},
|
||||
loss_keypoint=dict(
|
||||
type='MultiLossFactory',
|
||||
num_joints=17,
|
||||
num_stages=1,
|
||||
ae_loss_type='exp',
|
||||
with_ae_loss=[True],
|
||||
push_loss_factor=[0.001],
|
||||
pull_loss_factor=[0.001],
|
||||
with_heatmaps_loss=[True],
|
||||
heatmaps_loss_factor=[1.0]))
|
||||
head.init_weights()
|
||||
input_shape = (1, 512, 32, 32)
|
||||
inputs = _demo_inputs(input_shape)
|
||||
out = head(inputs)
|
||||
assert out[0].shape == torch.Size([1, 17, 32, 32])
|
||||
head = AESimpleHead(
|
||||
in_channels=512,
|
||||
num_joints=17,
|
||||
num_deconv_layers=0,
|
||||
tag_per_joint=False,
|
||||
with_ae_loss=[True],
|
||||
extra={'final_conv_kernel': 3},
|
||||
loss_keypoint=dict(
|
||||
type='MultiLossFactory',
|
||||
num_joints=17,
|
||||
num_stages=1,
|
||||
ae_loss_type='exp',
|
||||
with_ae_loss=[True],
|
||||
push_loss_factor=[0.001],
|
||||
pull_loss_factor=[0.001],
|
||||
with_heatmaps_loss=[True],
|
||||
heatmaps_loss_factor=[1.0]))
|
||||
head.init_weights()
|
||||
input_shape = (1, 512, 32, 32)
|
||||
inputs = _demo_inputs(input_shape)
|
||||
out = head(inputs)
|
||||
assert out[0].shape == torch.Size([1, 18, 32, 32])
|
||||
head = AESimpleHead(
|
||||
in_channels=512,
|
||||
num_joints=17,
|
||||
num_deconv_layers=0,
|
||||
tag_per_joint=False,
|
||||
with_ae_loss=[True],
|
||||
extra={'final_conv_kernel': 3},
|
||||
loss_keypoint=dict(
|
||||
type='MultiLossFactory',
|
||||
num_joints=17,
|
||||
num_stages=1,
|
||||
ae_loss_type='exp',
|
||||
with_ae_loss=[True],
|
||||
push_loss_factor=[0.001],
|
||||
pull_loss_factor=[0.001],
|
||||
with_heatmaps_loss=[True],
|
||||
heatmaps_loss_factor=[1.0]))
|
||||
head.init_weights()
|
||||
input_shape = (1, 512, 32, 32)
|
||||
inputs = _demo_inputs(input_shape)
|
||||
out = head([inputs])
|
||||
assert out[0].shape == torch.Size([1, 18, 32, 32])
|
||||
|
||||
|
||||
def test_ae_higherresolution_head():
|
||||
"""test bottom up AE higherresolution head."""
|
||||
|
||||
# test final_conv_kernel
|
||||
with pytest.raises(AssertionError):
|
||||
_ = AEHigherResolutionHead(
|
||||
in_channels=512,
|
||||
num_joints=17,
|
||||
with_ae_loss=[True, False],
|
||||
extra={'final_conv_kernel': 0},
|
||||
loss_keypoint=dict(
|
||||
type='MultiLossFactory',
|
||||
num_joints=17,
|
||||
num_stages=2,
|
||||
ae_loss_type='exp',
|
||||
with_ae_loss=[True, False],
|
||||
push_loss_factor=[0.001, 0.001],
|
||||
pull_loss_factor=[0.001, 0.001],
|
||||
with_heatmaps_loss=[True, True],
|
||||
heatmaps_loss_factor=[1.0, 1.0]))
|
||||
head = AEHigherResolutionHead(
|
||||
in_channels=512,
|
||||
num_joints=17,
|
||||
with_ae_loss=[True, False],
|
||||
extra={'final_conv_kernel': 3},
|
||||
cat_output=[True],
|
||||
loss_keypoint=dict(
|
||||
type='MultiLossFactory',
|
||||
num_joints=17,
|
||||
num_stages=2,
|
||||
ae_loss_type='exp',
|
||||
with_ae_loss=[True, False],
|
||||
push_loss_factor=[0.001, 0.001],
|
||||
pull_loss_factor=[0.001, 0.001],
|
||||
with_heatmaps_loss=[True, True],
|
||||
heatmaps_loss_factor=[1.0, 1.0]))
|
||||
head.init_weights()
|
||||
assert head.final_layers[0].padding == (1, 1)
|
||||
head = AEHigherResolutionHead(
|
||||
in_channels=512,
|
||||
num_joints=17,
|
||||
with_ae_loss=[True, False],
|
||||
extra={'final_conv_kernel': 1},
|
||||
cat_output=[True],
|
||||
loss_keypoint=dict(
|
||||
type='MultiLossFactory',
|
||||
num_joints=17,
|
||||
num_stages=2,
|
||||
ae_loss_type='exp',
|
||||
with_ae_loss=[True, False],
|
||||
push_loss_factor=[0.001, 0.001],
|
||||
pull_loss_factor=[0.001, 0.001],
|
||||
with_heatmaps_loss=[True, True],
|
||||
heatmaps_loss_factor=[1.0, 1.0]))
|
||||
head.init_weights()
|
||||
assert head.final_layers[0].padding == (0, 0)
|
||||
head = AEHigherResolutionHead(
|
||||
in_channels=512,
|
||||
num_joints=17,
|
||||
with_ae_loss=[True, False],
|
||||
cat_output=[True],
|
||||
loss_keypoint=dict(
|
||||
type='MultiLossFactory',
|
||||
num_joints=17,
|
||||
num_stages=2,
|
||||
ae_loss_type='exp',
|
||||
with_ae_loss=[True, False],
|
||||
push_loss_factor=[0.001, 0.001],
|
||||
pull_loss_factor=[0.001, 0.001],
|
||||
with_heatmaps_loss=[True, True],
|
||||
heatmaps_loss_factor=[1.0, 1.0]))
|
||||
head.init_weights()
|
||||
assert head.final_layers[0].padding == (0, 0)
|
||||
# test deconv layers
|
||||
with pytest.raises(ValueError):
|
||||
_ = AEHigherResolutionHead(
|
||||
in_channels=512,
|
||||
num_joints=17,
|
||||
with_ae_loss=[True, False],
|
||||
num_deconv_kernels=[1],
|
||||
cat_output=[True],
|
||||
loss_keypoint=dict(
|
||||
type='MultiLossFactory',
|
||||
num_joints=17,
|
||||
num_stages=2,
|
||||
ae_loss_type='exp',
|
||||
with_ae_loss=[True, False],
|
||||
push_loss_factor=[0.001, 0.001],
|
||||
pull_loss_factor=[0.001, 0.001],
|
||||
with_heatmaps_loss=[True, True],
|
||||
heatmaps_loss_factor=[1.0, 1.0]))
|
||||
head = AEHigherResolutionHead(
|
||||
in_channels=512,
|
||||
num_joints=17,
|
||||
with_ae_loss=[True, False],
|
||||
num_deconv_kernels=[4],
|
||||
cat_output=[True],
|
||||
loss_keypoint=dict(
|
||||
type='MultiLossFactory',
|
||||
num_joints=17,
|
||||
num_stages=2,
|
||||
ae_loss_type='exp',
|
||||
with_ae_loss=[True, False],
|
||||
push_loss_factor=[0.001, 0.001],
|
||||
pull_loss_factor=[0.001, 0.001],
|
||||
with_heatmaps_loss=[True, True],
|
||||
heatmaps_loss_factor=[1.0, 1.0]))
|
||||
head.init_weights()
|
||||
assert head.deconv_layers[0][0][0].output_padding == (0, 0)
|
||||
head = AEHigherResolutionHead(
|
||||
in_channels=512,
|
||||
num_joints=17,
|
||||
with_ae_loss=[True, False],
|
||||
num_deconv_kernels=[3],
|
||||
cat_output=[True],
|
||||
loss_keypoint=dict(
|
||||
type='MultiLossFactory',
|
||||
num_joints=17,
|
||||
num_stages=2,
|
||||
ae_loss_type='exp',
|
||||
with_ae_loss=[True, False],
|
||||
push_loss_factor=[0.001, 0.001],
|
||||
pull_loss_factor=[0.001, 0.001],
|
||||
with_heatmaps_loss=[True, True],
|
||||
heatmaps_loss_factor=[1.0, 1.0]))
|
||||
head.init_weights()
|
||||
assert head.deconv_layers[0][0][0].output_padding == (1, 1)
|
||||
head = AEHigherResolutionHead(
|
||||
in_channels=512,
|
||||
num_joints=17,
|
||||
with_ae_loss=[True, False],
|
||||
num_deconv_kernels=[2],
|
||||
cat_output=[True],
|
||||
loss_keypoint=dict(
|
||||
type='MultiLossFactory',
|
||||
num_joints=17,
|
||||
num_stages=2,
|
||||
ae_loss_type='exp',
|
||||
with_ae_loss=[True, False],
|
||||
push_loss_factor=[0.001, 0.001],
|
||||
pull_loss_factor=[0.001, 0.001],
|
||||
with_heatmaps_loss=[True, True],
|
||||
heatmaps_loss_factor=[1.0, 1.0]))
|
||||
head.init_weights()
|
||||
assert head.deconv_layers[0][0][0].output_padding == (0, 0)
|
||||
# test tag_per_joint & ae loss
|
||||
head = AEHigherResolutionHead(
|
||||
in_channels=512,
|
||||
num_joints=17,
|
||||
tag_per_joint=False,
|
||||
with_ae_loss=[False, False],
|
||||
extra={'final_conv_kernel': 3},
|
||||
cat_output=[True],
|
||||
loss_keypoint=dict(
|
||||
type='MultiLossFactory',
|
||||
num_joints=17,
|
||||
num_stages=2,
|
||||
ae_loss_type='exp',
|
||||
with_ae_loss=[False, False],
|
||||
push_loss_factor=[0.001, 0.001],
|
||||
pull_loss_factor=[0.001, 0.001],
|
||||
with_heatmaps_loss=[True, True],
|
||||
heatmaps_loss_factor=[1.0, 1.0]))
|
||||
head.init_weights()
|
||||
input_shape = (1, 512, 32, 32)
|
||||
inputs = _demo_inputs(input_shape)
|
||||
out = head(inputs)
|
||||
assert out[0].shape == torch.Size([1, 17, 32, 32])
|
||||
assert out[1].shape == torch.Size([1, 17, 64, 64])
|
||||
head = AEHigherResolutionHead(
|
||||
in_channels=512,
|
||||
num_joints=17,
|
||||
tag_per_joint=False,
|
||||
with_ae_loss=[True, False],
|
||||
extra={'final_conv_kernel': 3},
|
||||
cat_output=[True],
|
||||
loss_keypoint=dict(
|
||||
type='MultiLossFactory',
|
||||
num_joints=17,
|
||||
num_stages=2,
|
||||
ae_loss_type='exp',
|
||||
with_ae_loss=[True, False],
|
||||
push_loss_factor=[0.001, 0.001],
|
||||
pull_loss_factor=[0.001, 0.001],
|
||||
with_heatmaps_loss=[True, True],
|
||||
heatmaps_loss_factor=[1.0, 1.0]))
|
||||
head.init_weights()
|
||||
input_shape = (1, 512, 32, 32)
|
||||
inputs = _demo_inputs(input_shape)
|
||||
out = head(inputs)
|
||||
assert out[0].shape == torch.Size([1, 18, 32, 32])
|
||||
assert out[1].shape == torch.Size([1, 17, 64, 64])
|
||||
head = AEHigherResolutionHead(
|
||||
in_channels=512,
|
||||
num_joints=17,
|
||||
tag_per_joint=True,
|
||||
with_ae_loss=[True, True],
|
||||
extra={'final_conv_kernel': 3},
|
||||
cat_output=[True],
|
||||
loss_keypoint=dict(
|
||||
type='MultiLossFactory',
|
||||
num_joints=17,
|
||||
num_stages=2,
|
||||
ae_loss_type='exp',
|
||||
with_ae_loss=[True, True],
|
||||
push_loss_factor=[0.001, 0.001],
|
||||
pull_loss_factor=[0.001, 0.001],
|
||||
with_heatmaps_loss=[True, True],
|
||||
heatmaps_loss_factor=[1.0, 1.0]))
|
||||
head.init_weights()
|
||||
input_shape = (1, 512, 32, 32)
|
||||
inputs = _demo_inputs(input_shape)
|
||||
out = head(inputs)
|
||||
assert out[0].shape == torch.Size([1, 34, 32, 32])
|
||||
assert out[1].shape == torch.Size([1, 34, 64, 64])
|
||||
# cat_output
|
||||
head = AEHigherResolutionHead(
|
||||
in_channels=512,
|
||||
num_joints=17,
|
||||
tag_per_joint=True,
|
||||
with_ae_loss=[True, True],
|
||||
extra={'final_conv_kernel': 3},
|
||||
cat_output=[False],
|
||||
loss_keypoint=dict(
|
||||
type='MultiLossFactory',
|
||||
num_joints=17,
|
||||
num_stages=2,
|
||||
ae_loss_type='exp',
|
||||
with_ae_loss=[True, True],
|
||||
push_loss_factor=[0.001, 0.001],
|
||||
pull_loss_factor=[0.001, 0.001],
|
||||
with_heatmaps_loss=[True, True],
|
||||
heatmaps_loss_factor=[1.0, 1.0]))
|
||||
head.init_weights()
|
||||
input_shape = (1, 512, 32, 32)
|
||||
inputs = _demo_inputs(input_shape)
|
||||
out = head(inputs)
|
||||
assert out[0].shape == torch.Size([1, 34, 32, 32])
|
||||
assert out[1].shape == torch.Size([1, 34, 64, 64])
|
||||
head = AEHigherResolutionHead(
|
||||
in_channels=512,
|
||||
num_joints=17,
|
||||
tag_per_joint=True,
|
||||
with_ae_loss=[True, True],
|
||||
extra={'final_conv_kernel': 3},
|
||||
cat_output=[False],
|
||||
loss_keypoint=dict(
|
||||
type='MultiLossFactory',
|
||||
num_joints=17,
|
||||
num_stages=2,
|
||||
ae_loss_type='exp',
|
||||
with_ae_loss=[True, True],
|
||||
push_loss_factor=[0.001, 0.001],
|
||||
pull_loss_factor=[0.001, 0.001],
|
||||
with_heatmaps_loss=[True, True],
|
||||
heatmaps_loss_factor=[1.0, 1.0]))
|
||||
head.init_weights()
|
||||
input_shape = (1, 512, 32, 32)
|
||||
inputs = _demo_inputs(input_shape)
|
||||
out = head([inputs])
|
||||
assert out[0].shape == torch.Size([1, 34, 32, 32])
|
||||
assert out[1].shape == torch.Size([1, 34, 64, 64])
|
||||
|
||||
|
||||
def _demo_inputs(input_shape=(1, 3, 64, 64)):
|
||||
"""Create a superset of inputs needed to run backbone.
|
||||
|
||||
Args:
|
||||
input_shape (tuple): input batch dimensions.
|
||||
Default: (1, 3, 64, 64).
|
||||
Returns:
|
||||
Random input tensor with the size of input_shape.
|
||||
"""
|
||||
inps = np.random.random(input_shape)
|
||||
inps = torch.FloatTensor(inps)
|
||||
return inps
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
import numpy as np
|
||||
import torch
|
||||
|
||||
from mmpose.models import build_posenet
|
||||
|
||||
|
||||
def test_interhand3d_forward():
|
||||
# model settings
|
||||
model_cfg = dict(
|
||||
type='Interhand3D',
|
||||
pretrained='torchvision://resnet50',
|
||||
backbone=dict(type='ResNet', depth=50),
|
||||
keypoint_head=dict(
|
||||
type='Interhand3DHead',
|
||||
keypoint_head_cfg=dict(
|
||||
in_channels=2048,
|
||||
out_channels=21 * 64,
|
||||
depth_size=64,
|
||||
num_deconv_layers=3,
|
||||
num_deconv_filters=(256, 256, 256),
|
||||
num_deconv_kernels=(4, 4, 4),
|
||||
),
|
||||
root_head_cfg=dict(
|
||||
in_channels=2048,
|
||||
heatmap_size=64,
|
||||
hidden_dims=(512, ),
|
||||
),
|
||||
hand_type_head_cfg=dict(
|
||||
in_channels=2048,
|
||||
num_labels=2,
|
||||
hidden_dims=(512, ),
|
||||
),
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True),
|
||||
loss_root_depth=dict(type='L1Loss'),
|
||||
loss_hand_type=dict(type='BCELoss', use_target_weight=True),
|
||||
),
|
||||
train_cfg={},
|
||||
test_cfg=dict(flip_test=True, shift_heatmap=True))
|
||||
|
||||
detector = build_posenet(model_cfg)
|
||||
detector.init_weights()
|
||||
|
||||
input_shape = (2, 3, 256, 256)
|
||||
mm_inputs = _demo_mm_inputs(input_shape)
|
||||
|
||||
imgs = mm_inputs.pop('imgs')
|
||||
target = mm_inputs.pop('target')
|
||||
target_weight = mm_inputs.pop('target_weight')
|
||||
img_metas = mm_inputs.pop('img_metas')
|
||||
|
||||
# Test forward train
|
||||
losses = detector.forward(
|
||||
imgs, target, target_weight, img_metas, return_loss=True)
|
||||
assert isinstance(losses, dict)
|
||||
|
||||
# Test forward test
|
||||
with torch.no_grad():
|
||||
_ = detector.forward(imgs, img_metas=img_metas, return_loss=False)
|
||||
_ = detector.forward_dummy(imgs)
|
||||
|
||||
|
||||
def _demo_mm_inputs(input_shape=(1, 3, 256, 256), num_outputs=None):
|
||||
"""Create a superset of inputs needed to run test or train batches.
|
||||
|
||||
Args:
|
||||
input_shape (tuple):
|
||||
input batch dimensions
|
||||
"""
|
||||
(N, C, H, W) = input_shape
|
||||
|
||||
rng = np.random.RandomState(0)
|
||||
|
||||
imgs = rng.rand(*input_shape)
|
||||
imgs = torch.FloatTensor(imgs)
|
||||
|
||||
target = [
|
||||
imgs.new_zeros(N, 42, 64, H // 4, W // 4),
|
||||
imgs.new_zeros(N, 1),
|
||||
imgs.new_zeros(N, 2),
|
||||
]
|
||||
target_weight = [
|
||||
imgs.new_ones(N, 42, 1),
|
||||
imgs.new_ones(N, 1),
|
||||
imgs.new_ones(N),
|
||||
]
|
||||
|
||||
img_metas = [{
|
||||
'img_shape': (H, W, C),
|
||||
'center': np.array([W / 2, H / 2]),
|
||||
'scale': np.array([0.5, 0.5]),
|
||||
'bbox_score': 1.0,
|
||||
'bbox_id': 0,
|
||||
'flip_pairs': [],
|
||||
'inference_channel': np.arange(42),
|
||||
'image_file': '<demo>.png',
|
||||
'heatmap3d_depth_bound': 400.0,
|
||||
'root_depth_bound': 400.0,
|
||||
} for _ in range(N)]
|
||||
|
||||
mm_inputs = {
|
||||
'imgs': imgs.requires_grad_(True),
|
||||
'target': target,
|
||||
'target_weight': target_weight,
|
||||
'img_metas': img_metas
|
||||
}
|
||||
return mm_inputs
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
import numpy as np
|
||||
import torch
|
||||
|
||||
from mmpose.models import Interhand3DHead
|
||||
|
||||
|
||||
def test_interhand_3d_head():
|
||||
"""Test interhand 3d head."""
|
||||
N = 4
|
||||
input_shape = (N, 2048, 8, 8)
|
||||
inputs = torch.rand(input_shape, dtype=torch.float32)
|
||||
target = [
|
||||
inputs.new_zeros(N, 42, 64, 64, 64),
|
||||
inputs.new_zeros(N, 1),
|
||||
inputs.new_zeros(N, 2),
|
||||
]
|
||||
target_weight = [
|
||||
inputs.new_ones(N, 42, 1),
|
||||
inputs.new_ones(N, 1),
|
||||
inputs.new_ones(N),
|
||||
]
|
||||
|
||||
img_metas = [{
|
||||
'img_shape': (256, 256, 3),
|
||||
'center': np.array([112, 112]),
|
||||
'scale': np.array([0.5, 0.5]),
|
||||
'bbox_score': 1.0,
|
||||
'bbox_id': 0,
|
||||
'flip_pairs': [],
|
||||
'inference_channel': np.arange(42),
|
||||
'image_file': '<demo>.png',
|
||||
'heatmap3d_depth_bound': 400.0,
|
||||
'root_depth_bound': 400.0,
|
||||
} for _ in range(N)]
|
||||
|
||||
head = Interhand3DHead(
|
||||
keypoint_head_cfg=dict(
|
||||
in_channels=2048,
|
||||
out_channels=21 * 64,
|
||||
depth_size=64,
|
||||
num_deconv_layers=3,
|
||||
num_deconv_filters=(256, 256, 256),
|
||||
num_deconv_kernels=(4, 4, 4),
|
||||
),
|
||||
root_head_cfg=dict(
|
||||
in_channels=2048,
|
||||
heatmap_size=64,
|
||||
hidden_dims=(512, ),
|
||||
),
|
||||
hand_type_head_cfg=dict(
|
||||
in_channels=2048,
|
||||
num_labels=2,
|
||||
hidden_dims=(512, ),
|
||||
),
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True),
|
||||
loss_root_depth=dict(type='L1Loss'),
|
||||
loss_hand_type=dict(type='BCELoss', use_target_weight=True),
|
||||
train_cfg={},
|
||||
test_cfg={},
|
||||
)
|
||||
head.init_weights()
|
||||
|
||||
# test forward
|
||||
output = head(inputs)
|
||||
assert isinstance(output, list)
|
||||
assert len(output) == 3
|
||||
assert output[0].shape == (N, 42, 64, 64, 64)
|
||||
assert output[1].shape == (N, 1)
|
||||
assert output[2].shape == (N, 2)
|
||||
|
||||
# test loss computation
|
||||
losses = head.get_loss(output, target, target_weight)
|
||||
assert 'hand_loss' in losses
|
||||
assert 'rel_root_loss' in losses
|
||||
assert 'hand_type_loss' in losses
|
||||
|
||||
# test inference model
|
||||
flip_pairs = [[i, 21 + i] for i in range(21)]
|
||||
output = head.inference_model(inputs, flip_pairs)
|
||||
assert isinstance(output, list)
|
||||
assert len(output) == 3
|
||||
assert output[0].shape == (N, 42, 64, 64, 64)
|
||||
assert output[1].shape == (N, 1)
|
||||
assert output[2].shape == (N, 2)
|
||||
|
||||
# test decode
|
||||
result = head.decode(img_metas, output)
|
||||
assert 'preds' in result
|
||||
assert 'rel_root_depth' in result
|
||||
assert 'hand_type' in result
|
||||
@@ -0,0 +1,68 @@
|
||||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
import numpy as np
|
||||
import torch
|
||||
import torch.nn as nn
|
||||
from mmcv.cnn import build_conv_layer, build_upsample_layer
|
||||
|
||||
|
||||
def test_build_upsample_layer():
|
||||
layer1 = nn.ConvTranspose2d(
|
||||
in_channels=3,
|
||||
out_channels=10,
|
||||
kernel_size=3,
|
||||
stride=2,
|
||||
padding=1,
|
||||
output_padding=1,
|
||||
bias=False)
|
||||
|
||||
layer2 = build_upsample_layer(
|
||||
dict(type='deconv'),
|
||||
in_channels=3,
|
||||
out_channels=10,
|
||||
kernel_size=3,
|
||||
stride=2,
|
||||
padding=1,
|
||||
output_padding=1,
|
||||
bias=False)
|
||||
layer2.load_state_dict(layer1.state_dict())
|
||||
|
||||
input_shape = (1, 3, 32, 32)
|
||||
inputs = _demo_inputs(input_shape)
|
||||
out1 = layer1(inputs)
|
||||
out2 = layer2(inputs)
|
||||
assert torch.equal(out1, out2)
|
||||
|
||||
|
||||
def test_build_conv_layer():
|
||||
layer1 = nn.Conv2d(
|
||||
in_channels=3, out_channels=10, kernel_size=3, stride=1, padding=1)
|
||||
|
||||
layer2 = build_conv_layer(
|
||||
cfg=dict(type='Conv2d'),
|
||||
in_channels=3,
|
||||
out_channels=10,
|
||||
kernel_size=3,
|
||||
stride=1,
|
||||
padding=1)
|
||||
|
||||
layer2.load_state_dict(layer1.state_dict())
|
||||
|
||||
input_shape = (1, 3, 32, 32)
|
||||
inputs = _demo_inputs(input_shape)
|
||||
out1 = layer1(inputs)
|
||||
out2 = layer2(inputs)
|
||||
assert torch.equal(out1, out2)
|
||||
|
||||
|
||||
def _demo_inputs(input_shape=(1, 3, 64, 64)):
|
||||
"""Create a superset of inputs needed to run backbone.
|
||||
|
||||
Args:
|
||||
input_shape (tuple): input batch dimensions.
|
||||
Default: (1, 3, 64, 64).
|
||||
Returns:
|
||||
Random input tensor with the size of input_shape.
|
||||
"""
|
||||
inps = np.random.random(input_shape)
|
||||
inps = torch.FloatTensor(inps)
|
||||
return inps
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
import os.path as osp
|
||||
import tempfile
|
||||
|
||||
import numpy as np
|
||||
import torch
|
||||
|
||||
from mmpose.core.optimizer import build_optimizers
|
||||
from mmpose.models.detectors.mesh import ParametricMesh
|
||||
from tests.utils.mesh_utils import generate_smpl_weight_file
|
||||
|
||||
|
||||
def test_parametric_mesh_forward():
|
||||
"""Test parametric mesh forward."""
|
||||
|
||||
tmpdir = tempfile.TemporaryDirectory()
|
||||
# generate weight file for SMPL model.
|
||||
generate_smpl_weight_file(tmpdir.name)
|
||||
|
||||
# Test ParametricMesh without discriminator
|
||||
model_cfg = dict(
|
||||
pretrained=None,
|
||||
backbone=dict(type='ResNet', depth=50),
|
||||
mesh_head=dict(
|
||||
type='HMRMeshHead',
|
||||
in_channels=2048,
|
||||
smpl_mean_params='tests/data/smpl/smpl_mean_params.npz'),
|
||||
disc=None,
|
||||
smpl=dict(
|
||||
type='SMPL',
|
||||
smpl_path=tmpdir.name,
|
||||
joints_regressor=osp.join(tmpdir.name,
|
||||
'test_joint_regressor.npy')),
|
||||
train_cfg=dict(disc_step=1),
|
||||
test_cfg=dict(
|
||||
flip_test=False,
|
||||
post_process='default',
|
||||
shift_heatmap=True,
|
||||
modulate_kernel=11),
|
||||
loss_mesh=dict(
|
||||
type='MeshLoss',
|
||||
joints_2d_loss_weight=1,
|
||||
joints_3d_loss_weight=1,
|
||||
vertex_loss_weight=1,
|
||||
smpl_pose_loss_weight=1,
|
||||
smpl_beta_loss_weight=1,
|
||||
focal_length=5000,
|
||||
img_res=256),
|
||||
loss_gan=None)
|
||||
|
||||
detector = ParametricMesh(**model_cfg)
|
||||
detector.init_weights()
|
||||
|
||||
optimizers_config = dict(generator=dict(type='Adam', lr=0.0001))
|
||||
optims = build_optimizers(detector, optimizers_config)
|
||||
|
||||
input_shape = (1, 3, 256, 256)
|
||||
mm_inputs = _demo_mm_inputs(input_shape)
|
||||
# Test forward train
|
||||
output = detector.train_step(mm_inputs, optims)
|
||||
assert isinstance(output, dict)
|
||||
|
||||
# Test forward test
|
||||
with torch.no_grad():
|
||||
output = detector.val_step(data_batch=mm_inputs)
|
||||
assert isinstance(output, dict)
|
||||
|
||||
imgs = mm_inputs.pop('img')
|
||||
img_metas = mm_inputs.pop('img_metas')
|
||||
output = detector.forward(imgs, img_metas=img_metas, return_loss=False)
|
||||
assert isinstance(output, dict)
|
||||
|
||||
# Test ParametricMesh with discriminator
|
||||
model_cfg['disc'] = dict()
|
||||
model_cfg['loss_gan'] = dict(
|
||||
type='GANLoss',
|
||||
gan_type='lsgan',
|
||||
real_label_val=1.0,
|
||||
fake_label_val=0.0,
|
||||
loss_weight=1)
|
||||
|
||||
optimizers_config['discriminator'] = dict(type='Adam', lr=0.0001)
|
||||
|
||||
detector = ParametricMesh(**model_cfg)
|
||||
detector.init_weights()
|
||||
optims = build_optimizers(detector, optimizers_config)
|
||||
|
||||
input_shape = (1, 3, 256, 256)
|
||||
mm_inputs = _demo_mm_inputs(input_shape)
|
||||
# Test forward train
|
||||
output = detector.train_step(mm_inputs, optims)
|
||||
assert isinstance(output, dict)
|
||||
|
||||
# Test forward test
|
||||
with torch.no_grad():
|
||||
output = detector.val_step(data_batch=mm_inputs)
|
||||
assert isinstance(output, dict)
|
||||
|
||||
imgs = mm_inputs.pop('img')
|
||||
img_metas = mm_inputs.pop('img_metas')
|
||||
output = detector.forward(imgs, img_metas=img_metas, return_loss=False)
|
||||
assert isinstance(output, dict)
|
||||
|
||||
_ = detector.forward_dummy(imgs)
|
||||
|
||||
tmpdir.cleanup()
|
||||
|
||||
|
||||
def _demo_mm_inputs(input_shape=(1, 3, 256, 256)):
|
||||
"""Create a superset of inputs needed to run test or train batches.
|
||||
|
||||
Args:
|
||||
input_shape (tuple):
|
||||
input batch dimensions
|
||||
"""
|
||||
(N, C, H, W) = input_shape
|
||||
|
||||
rng = np.random.RandomState(0)
|
||||
|
||||
imgs = rng.rand(*input_shape)
|
||||
joints_2d = np.zeros([N, 24, 2])
|
||||
joints_2d_visible = np.ones([N, 24, 1])
|
||||
joints_3d = np.zeros([N, 24, 3])
|
||||
joints_3d_visible = np.ones([N, 24, 1])
|
||||
pose = np.zeros([N, 72])
|
||||
beta = np.zeros([N, 10])
|
||||
has_smpl = np.ones([N])
|
||||
mosh_theta = np.zeros([N, 3 + 72 + 10])
|
||||
|
||||
img_metas = [{
|
||||
'img_shape': (H, W, C),
|
||||
'center': np.array([W / 2, H / 2]),
|
||||
'scale': np.array([0.5, 0.5]),
|
||||
'bbox_score': 1.0,
|
||||
'flip_pairs': [],
|
||||
'inference_channel': np.arange(17),
|
||||
'image_file': '<demo>.png',
|
||||
} for _ in range(N)]
|
||||
|
||||
mm_inputs = {
|
||||
'img': torch.FloatTensor(imgs).requires_grad_(True),
|
||||
'joints_2d': torch.FloatTensor(joints_2d),
|
||||
'joints_2d_visible': torch.FloatTensor(joints_2d_visible),
|
||||
'joints_3d': torch.FloatTensor(joints_3d),
|
||||
'joints_3d_visible': torch.FloatTensor(joints_3d_visible),
|
||||
'pose': torch.FloatTensor(pose),
|
||||
'beta': torch.FloatTensor(beta),
|
||||
'has_smpl': torch.FloatTensor(has_smpl),
|
||||
'img_metas': img_metas,
|
||||
'mosh_theta': torch.FloatTensor(mosh_theta)
|
||||
}
|
||||
|
||||
return mm_inputs
|
||||
@@ -0,0 +1,76 @@
|
||||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
import numpy as np
|
||||
import pytest
|
||||
import torch
|
||||
|
||||
from mmpose.models import HMRMeshHead
|
||||
from mmpose.models.misc.discriminator import SMPLDiscriminator
|
||||
|
||||
|
||||
def test_mesh_hmr_head():
|
||||
"""Test hmr mesh head."""
|
||||
head = HMRMeshHead(in_channels=512)
|
||||
head.init_weights()
|
||||
|
||||
input_shape = (1, 512, 8, 8)
|
||||
inputs = _demo_inputs(input_shape)
|
||||
out = head(inputs)
|
||||
smpl_rotmat, smpl_shape, camera = out
|
||||
assert smpl_rotmat.shape == torch.Size([1, 24, 3, 3])
|
||||
assert smpl_shape.shape == torch.Size([1, 10])
|
||||
assert camera.shape == torch.Size([1, 3])
|
||||
"""Test hmr mesh head with assigned mean parameters and n_iter """
|
||||
head = HMRMeshHead(
|
||||
in_channels=512,
|
||||
smpl_mean_params='tests/data/smpl/smpl_mean_params.npz',
|
||||
n_iter=3)
|
||||
head.init_weights()
|
||||
input_shape = (1, 512, 8, 8)
|
||||
inputs = _demo_inputs(input_shape)
|
||||
out = head(inputs)
|
||||
smpl_rotmat, smpl_shape, camera = out
|
||||
assert smpl_rotmat.shape == torch.Size([1, 24, 3, 3])
|
||||
assert smpl_shape.shape == torch.Size([1, 10])
|
||||
assert camera.shape == torch.Size([1, 3])
|
||||
|
||||
# test discriminator with SMPL pose parameters
|
||||
# in rotation matrix representation
|
||||
disc = SMPLDiscriminator(
|
||||
beta_channel=(10, 10, 5, 1),
|
||||
per_joint_channel=(9, 32, 32, 16, 1),
|
||||
full_pose_channel=(23 * 16, 256, 1))
|
||||
pred_theta = (camera, smpl_rotmat, smpl_shape)
|
||||
pred_score = disc(pred_theta)
|
||||
assert pred_score.shape[1] == 25
|
||||
|
||||
# test discriminator with SMPL pose parameters
|
||||
# in axis-angle representation
|
||||
pred_theta = (camera, camera.new_zeros([1, 72]), smpl_shape)
|
||||
pred_score = disc(pred_theta)
|
||||
assert pred_score.shape[1] == 25
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
_ = SMPLDiscriminator(
|
||||
beta_channel=[10, 10, 5, 1],
|
||||
per_joint_channel=(9, 32, 32, 16, 1),
|
||||
full_pose_channel=(23 * 16, 256, 1))
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
_ = SMPLDiscriminator(
|
||||
beta_channel=(10, ),
|
||||
per_joint_channel=(9, 32, 32, 16, 1),
|
||||
full_pose_channel=(23 * 16, 256, 1))
|
||||
|
||||
|
||||
def _demo_inputs(input_shape=(1, 3, 64, 64)):
|
||||
"""Create a superset of inputs needed to run mesh head.
|
||||
|
||||
Args:
|
||||
input_shape (tuple): input batch dimensions.
|
||||
Default: (1, 3, 64, 64).
|
||||
Returns:
|
||||
Random input tensor with the size of input_shape.
|
||||
"""
|
||||
inps = np.random.random(input_shape)
|
||||
inps = torch.FloatTensor(inps)
|
||||
return inps
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
import numpy as np
|
||||
import torch
|
||||
|
||||
from mmpose.models.detectors import MultiTask
|
||||
|
||||
|
||||
def test_multitask_forward():
|
||||
"""Test multitask forward."""
|
||||
|
||||
# build MultiTask detector
|
||||
model_cfg = dict(
|
||||
backbone=dict(type='ResNet', depth=50),
|
||||
heads=[
|
||||
dict(
|
||||
type='DeepposeRegressionHead',
|
||||
in_channels=2048,
|
||||
num_joints=17,
|
||||
loss_keypoint=dict(
|
||||
type='SmoothL1Loss', use_target_weight=False)),
|
||||
],
|
||||
necks=[dict(type='GlobalAveragePooling')],
|
||||
head2neck={0: 0},
|
||||
pretrained=None,
|
||||
)
|
||||
model = MultiTask(**model_cfg)
|
||||
|
||||
# build inputs and target
|
||||
mm_inputs = _demo_mm_inputs()
|
||||
inputs = mm_inputs['img']
|
||||
target = [mm_inputs['target_keypoints']]
|
||||
target_weight = [mm_inputs['target_weight']]
|
||||
img_metas = mm_inputs['img_metas']
|
||||
|
||||
# Test forward train
|
||||
losses = model(inputs, target, target_weight, return_loss=True)
|
||||
assert 'reg_loss' in losses and 'acc_pose' in losses
|
||||
|
||||
# Test forward test
|
||||
outputs = model(inputs, img_metas=img_metas, return_loss=False)
|
||||
assert 'preds' in outputs
|
||||
|
||||
# Test dummy forward
|
||||
outputs = model.forward_dummy(inputs)
|
||||
assert outputs[0].shape == torch.Size([1, 17, 2])
|
||||
|
||||
# Build multitask detector with no neck
|
||||
model_cfg = dict(
|
||||
backbone=dict(type='ResNet', depth=50),
|
||||
heads=[
|
||||
dict(
|
||||
type='TopdownHeatmapSimpleHead',
|
||||
in_channels=2048,
|
||||
out_channels=17,
|
||||
num_deconv_layers=3,
|
||||
num_deconv_filters=(256, 256, 256),
|
||||
num_deconv_kernels=(4, 4, 4),
|
||||
loss_keypoint=dict(
|
||||
type='JointsMSELoss', use_target_weight=True))
|
||||
],
|
||||
pretrained=None,
|
||||
)
|
||||
model = MultiTask(**model_cfg)
|
||||
|
||||
# build inputs and target
|
||||
target = [mm_inputs['target_heatmap']]
|
||||
|
||||
# Test forward train
|
||||
losses = model(inputs, target, target_weight, return_loss=True)
|
||||
assert 'heatmap_loss' in losses and 'acc_pose' in losses
|
||||
|
||||
# Test forward test
|
||||
outputs = model(inputs, img_metas=img_metas, return_loss=False)
|
||||
assert 'preds' in outputs
|
||||
|
||||
# Test dummy forward
|
||||
outputs = model.forward_dummy(inputs)
|
||||
assert outputs[0].shape == torch.Size([1, 17, 64, 64])
|
||||
|
||||
|
||||
def _demo_mm_inputs(input_shape=(1, 3, 256, 256)):
|
||||
"""Create a superset of inputs needed to run test or train.
|
||||
|
||||
Args:
|
||||
input_shape (tuple):
|
||||
input batch dimensions
|
||||
"""
|
||||
(N, C, H, W) = input_shape
|
||||
|
||||
rng = np.random.RandomState(0)
|
||||
|
||||
imgs = rng.rand(*input_shape)
|
||||
|
||||
target_keypoints = np.zeros([N, 17, 2])
|
||||
target_heatmap = np.zeros([N, 17, H // 4, W // 4])
|
||||
target_weight = np.ones([N, 17, 1])
|
||||
|
||||
img_metas = [{
|
||||
'img_shape': (H, W, C),
|
||||
'center': np.array([W / 2, H / 2]),
|
||||
'scale': np.array([0.5, 0.5]),
|
||||
'bbox_score': 1.0,
|
||||
'bbox_id': 0,
|
||||
'flip_pairs': [],
|
||||
'inference_channel': np.arange(17),
|
||||
'image_file': '<demo>.png',
|
||||
} for _ in range(N)]
|
||||
|
||||
mm_inputs = {
|
||||
'img': torch.FloatTensor(imgs).requires_grad_(True),
|
||||
'target_keypoints': torch.FloatTensor(target_keypoints),
|
||||
'target_heatmap': torch.FloatTensor(target_heatmap),
|
||||
'target_weight': torch.FloatTensor(target_weight),
|
||||
'img_metas': img_metas,
|
||||
}
|
||||
return mm_inputs
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
import tempfile
|
||||
|
||||
from mmcv import Config
|
||||
|
||||
from mmpose.datasets import DATASETS, build_dataloader
|
||||
from mmpose.models import builder
|
||||
|
||||
|
||||
def test_voxelpose_forward():
|
||||
dataset = 'Body3DMviewDirectPanopticDataset'
|
||||
dataset_class = DATASETS.get(dataset)
|
||||
dataset_info = Config.fromfile(
|
||||
'configs/_base_/datasets/panoptic_body3d.py').dataset_info
|
||||
space_size = [8000, 8000, 2000]
|
||||
space_center = [0, -500, 800]
|
||||
cube_size = [20, 20, 8]
|
||||
data_cfg = dict(
|
||||
image_size=[960, 512],
|
||||
heatmap_size=[[240, 128]],
|
||||
space_size=space_size,
|
||||
space_center=space_center,
|
||||
cube_size=cube_size,
|
||||
num_joints=15,
|
||||
seq_list=['160906_band1'],
|
||||
cam_list=[(0, 12), (0, 6)],
|
||||
num_cameras=2,
|
||||
seq_frame_interval=1,
|
||||
subset='train',
|
||||
need_2d_label=True,
|
||||
need_camera_param=True,
|
||||
root_id=2)
|
||||
|
||||
pipeline = [
|
||||
dict(
|
||||
type='MultiItemProcess',
|
||||
pipeline=[
|
||||
dict(
|
||||
type='BottomUpGenerateTarget', sigma=3, max_num_people=20)
|
||||
]),
|
||||
dict(
|
||||
type='DiscardDuplicatedItems',
|
||||
keys_list=[
|
||||
'joints_3d', 'joints_3d_visible', 'ann_info', 'roots_3d',
|
||||
'num_persons', 'sample_id'
|
||||
]),
|
||||
dict(
|
||||
type='GenerateVoxel3DHeatmapTarget',
|
||||
sigma=200.0,
|
||||
joint_indices=[2]),
|
||||
dict(type='RenameKeys', key_pairs=[('targets', 'input_heatmaps')]),
|
||||
dict(
|
||||
type='Collect',
|
||||
keys=['targets_3d', 'input_heatmaps'],
|
||||
meta_keys=[
|
||||
'camera', 'center', 'scale', 'joints_3d', 'num_persons',
|
||||
'joints_3d_visible', 'roots_3d', 'sample_id'
|
||||
]),
|
||||
]
|
||||
|
||||
model_cfg = dict(
|
||||
type='DetectAndRegress',
|
||||
backbone=None,
|
||||
human_detector=dict(
|
||||
type='VoxelCenterDetector',
|
||||
image_size=[960, 512],
|
||||
heatmap_size=[240, 128],
|
||||
space_size=space_size,
|
||||
cube_size=cube_size,
|
||||
space_center=space_center,
|
||||
center_net=dict(
|
||||
type='V2VNet', input_channels=15, output_channels=1),
|
||||
center_head=dict(
|
||||
type='CuboidCenterHead',
|
||||
space_size=space_size,
|
||||
space_center=space_center,
|
||||
cube_size=cube_size,
|
||||
max_num=3,
|
||||
max_pool_kernel=3),
|
||||
train_cfg=dict(dist_threshold=500000000.0),
|
||||
test_cfg=dict(center_threshold=0.0),
|
||||
),
|
||||
pose_regressor=dict(
|
||||
type='VoxelSinglePose',
|
||||
image_size=[960, 512],
|
||||
heatmap_size=[240, 128],
|
||||
sub_space_size=[2000, 2000, 2000],
|
||||
sub_cube_size=[20, 20, 8],
|
||||
num_joints=15,
|
||||
pose_net=dict(
|
||||
type='V2VNet', input_channels=15, output_channels=15),
|
||||
pose_head=dict(type='CuboidPoseHead', beta=100.0),
|
||||
train_cfg=None,
|
||||
test_cfg=None))
|
||||
|
||||
model = builder.build_posenet(model_cfg)
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
dataset = dataset_class(
|
||||
ann_file=tmpdir + '/tmp_train.pkl',
|
||||
img_prefix='tests/data/panoptic_body3d/',
|
||||
data_cfg=data_cfg,
|
||||
pipeline=pipeline,
|
||||
dataset_info=dataset_info,
|
||||
test_mode=False)
|
||||
|
||||
data_loader = build_dataloader(
|
||||
dataset,
|
||||
seed=None,
|
||||
dist=False,
|
||||
shuffle=False,
|
||||
drop_last=False,
|
||||
workers_per_gpu=1,
|
||||
samples_per_gpu=1)
|
||||
|
||||
for data in data_loader:
|
||||
# test forward_train
|
||||
_ = model(
|
||||
img=None,
|
||||
img_metas=data['img_metas'].data[0],
|
||||
return_loss=True,
|
||||
targets_3d=data['targets_3d'],
|
||||
input_heatmaps=data['input_heatmaps'])
|
||||
|
||||
# test forward_test
|
||||
_ = model(
|
||||
img=None,
|
||||
img_metas=data['img_metas'].data[0],
|
||||
return_loss=False,
|
||||
input_heatmaps=data['input_heatmaps'])
|
||||
+197
@@ -0,0 +1,197 @@
|
||||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
import mmcv
|
||||
import numpy as np
|
||||
import torch
|
||||
|
||||
from mmpose.models import build_posenet
|
||||
|
||||
|
||||
def _create_inputs(joint_num_in,
|
||||
joint_channel_in,
|
||||
joint_num_out,
|
||||
joint_channel_out,
|
||||
seq_len,
|
||||
batch_size,
|
||||
semi=False):
|
||||
rng = np.random.RandomState(0)
|
||||
pose_in = rng.rand(batch_size, joint_num_in * joint_channel_in, seq_len)
|
||||
target = np.zeros((batch_size, joint_num_out, joint_channel_out),
|
||||
dtype=np.float32)
|
||||
target_weight = np.ones((batch_size, joint_num_out, joint_channel_out),
|
||||
dtype=np.float32)
|
||||
|
||||
meta_info = {
|
||||
'root_position': np.zeros((1, joint_channel_out), np.float32),
|
||||
'root_position_index': 0,
|
||||
'target_mean': np.zeros((joint_num_out, joint_channel_out),
|
||||
np.float32),
|
||||
'target_std': np.ones((joint_num_out, joint_channel_out), np.float32)
|
||||
}
|
||||
metas = [meta_info.copy() for _ in range(batch_size)]
|
||||
inputs = {
|
||||
'input': torch.FloatTensor(pose_in).requires_grad_(True),
|
||||
'target': torch.FloatTensor(target),
|
||||
'target_weight': torch.FloatTensor(target_weight),
|
||||
'metas': metas,
|
||||
}
|
||||
|
||||
if semi:
|
||||
traj_target = np.zeros((batch_size, 1, joint_channel_out), np.float32)
|
||||
unlabeled_pose_in = rng.rand(batch_size,
|
||||
joint_num_in * joint_channel_in, seq_len)
|
||||
unlabeled_target_2d = np.zeros(
|
||||
(batch_size, joint_num_out, joint_channel_in), dtype=np.float32)
|
||||
intrinsics = np.ones((batch_size, 4))
|
||||
|
||||
inputs['traj_target'] = torch.FloatTensor(traj_target)
|
||||
inputs['unlabeled_input'] = torch.FloatTensor(
|
||||
unlabeled_pose_in).requires_grad_(True)
|
||||
inputs['unlabeled_target_2d'] = torch.FloatTensor(unlabeled_target_2d)
|
||||
inputs['intrinsics'] = torch.FloatTensor(intrinsics)
|
||||
|
||||
return inputs
|
||||
|
||||
|
||||
def test_pose_lifter_forward():
|
||||
# Test forward train for supervised learning with pose model only
|
||||
model_cfg = dict(
|
||||
type='PoseLifter',
|
||||
pretrained=None,
|
||||
backbone=dict(type='TCN', in_channels=2 * 17),
|
||||
keypoint_head=dict(
|
||||
type='TemporalRegressionHead',
|
||||
in_channels=1024,
|
||||
num_joints=16,
|
||||
max_norm=1.0,
|
||||
loss_keypoint=dict(type='MPJPELoss'),
|
||||
test_cfg=dict(restore_global_position=True)),
|
||||
train_cfg=dict(),
|
||||
test_cfg=dict())
|
||||
|
||||
cfg = mmcv.Config({'model': model_cfg})
|
||||
detector = build_posenet(cfg.model)
|
||||
|
||||
detector.init_weights()
|
||||
|
||||
inputs = _create_inputs(
|
||||
joint_num_in=17,
|
||||
joint_channel_in=2,
|
||||
joint_num_out=16,
|
||||
joint_channel_out=3,
|
||||
seq_len=27,
|
||||
batch_size=8)
|
||||
|
||||
losses = detector.forward(
|
||||
inputs['input'],
|
||||
inputs['target'],
|
||||
inputs['target_weight'],
|
||||
inputs['metas'],
|
||||
return_loss=True)
|
||||
|
||||
assert isinstance(losses, dict)
|
||||
|
||||
# Test forward test for supervised learning with pose model only
|
||||
with torch.no_grad():
|
||||
_ = detector.forward(
|
||||
inputs['input'],
|
||||
inputs['target'],
|
||||
inputs['target_weight'],
|
||||
inputs['metas'],
|
||||
return_loss=False)
|
||||
_ = detector.forward_dummy(inputs['input'])
|
||||
|
||||
# Test forward train for semi-supervised learning
|
||||
model_cfg = dict(
|
||||
type='PoseLifter',
|
||||
pretrained=None,
|
||||
backbone=dict(type='TCN', in_channels=2 * 17),
|
||||
keypoint_head=dict(
|
||||
type='TemporalRegressionHead',
|
||||
in_channels=1024,
|
||||
num_joints=17,
|
||||
loss_keypoint=dict(type='MPJPELoss'),
|
||||
test_cfg=dict(restore_global_position=True)),
|
||||
traj_backbone=dict(type='TCN', in_channels=2 * 17),
|
||||
traj_head=dict(
|
||||
type='TemporalRegressionHead',
|
||||
in_channels=1024,
|
||||
num_joints=1,
|
||||
loss_keypoint=dict(type='MPJPELoss'),
|
||||
is_trajectory=True),
|
||||
loss_semi=dict(
|
||||
type='SemiSupervisionLoss',
|
||||
joint_parents=[
|
||||
0, 0, 1, 2, 0, 4, 5, 0, 7, 8, 9, 8, 11, 12, 8, 14, 15
|
||||
]),
|
||||
train_cfg=dict(),
|
||||
test_cfg=dict())
|
||||
|
||||
cfg = mmcv.Config({'model': model_cfg})
|
||||
detector = build_posenet(cfg.model)
|
||||
|
||||
detector.init_weights()
|
||||
|
||||
inputs = _create_inputs(
|
||||
joint_num_in=17,
|
||||
joint_channel_in=2,
|
||||
joint_num_out=17,
|
||||
joint_channel_out=3,
|
||||
seq_len=27,
|
||||
batch_size=8,
|
||||
semi=True)
|
||||
|
||||
losses = detector.forward(**inputs, return_loss=True)
|
||||
|
||||
assert isinstance(losses, dict)
|
||||
assert 'proj_loss' in losses
|
||||
|
||||
# Test forward test for semi-supervised learning
|
||||
with torch.no_grad():
|
||||
_ = detector.forward(**inputs, return_loss=False)
|
||||
_ = detector.forward_dummy(inputs['input'])
|
||||
|
||||
# Test forward train for supervised learning with pose model and trajectory
|
||||
# model sharing one backbone
|
||||
model_cfg = dict(
|
||||
type='PoseLifter',
|
||||
pretrained=None,
|
||||
backbone=dict(type='TCN', in_channels=2 * 17),
|
||||
keypoint_head=dict(
|
||||
type='TemporalRegressionHead',
|
||||
in_channels=1024,
|
||||
num_joints=17,
|
||||
loss_keypoint=dict(type='MPJPELoss'),
|
||||
test_cfg=dict(restore_global_position=True)),
|
||||
traj_head=dict(
|
||||
type='TemporalRegressionHead',
|
||||
in_channels=1024,
|
||||
num_joints=1,
|
||||
loss_keypoint=dict(type='MPJPELoss'),
|
||||
is_trajectory=True),
|
||||
train_cfg=dict(),
|
||||
test_cfg=dict())
|
||||
|
||||
cfg = mmcv.Config({'model': model_cfg})
|
||||
detector = build_posenet(cfg.model)
|
||||
|
||||
detector.init_weights()
|
||||
|
||||
inputs = _create_inputs(
|
||||
joint_num_in=17,
|
||||
joint_channel_in=2,
|
||||
joint_num_out=17,
|
||||
joint_channel_out=3,
|
||||
seq_len=27,
|
||||
batch_size=8,
|
||||
semi=True)
|
||||
|
||||
losses = detector.forward(**inputs, return_loss=True)
|
||||
|
||||
assert isinstance(losses, dict)
|
||||
assert 'traj_loss' in losses
|
||||
|
||||
# Test forward test for semi-supervised learning with pose model and
|
||||
# trajectory model sharing one backbone
|
||||
with torch.no_grad():
|
||||
_ = detector.forward(**inputs, return_loss=False)
|
||||
_ = detector.forward_dummy(inputs['input'])
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
import numpy as np
|
||||
import pytest
|
||||
import torch
|
||||
|
||||
from mmpose.models import TemporalRegressionHead
|
||||
|
||||
|
||||
def test_temporal_regression_head():
|
||||
"""Test temporal head."""
|
||||
|
||||
# w/o global position restoration
|
||||
head = TemporalRegressionHead(
|
||||
in_channels=1024,
|
||||
num_joints=17,
|
||||
loss_keypoint=dict(type='MPJPELoss', use_target_weight=True),
|
||||
test_cfg=dict(restore_global_position=False))
|
||||
|
||||
head.init_weights()
|
||||
|
||||
with pytest.raises(AssertionError):
|
||||
# ndim of the input tensor should be 3
|
||||
input_shape = (1, 1024, 1, 1)
|
||||
inputs = _demo_inputs(input_shape)
|
||||
_ = head(inputs)
|
||||
|
||||
with pytest.raises(AssertionError):
|
||||
# size of the last dim should be 1
|
||||
input_shape = (1, 1024, 3)
|
||||
inputs = _demo_inputs(input_shape)
|
||||
_ = head(inputs)
|
||||
|
||||
input_shape = (1, 1024, 1)
|
||||
inputs = _demo_inputs(input_shape)
|
||||
out = head(inputs)
|
||||
assert out.shape == torch.Size([1, 17, 3])
|
||||
|
||||
loss = head.get_loss(out, out, None)
|
||||
assert torch.allclose(loss['reg_loss'], torch.tensor(0.))
|
||||
|
||||
_ = head.inference_model(inputs)
|
||||
_ = head.inference_model(inputs, [(0, 1), (2, 3)])
|
||||
metas = [{}]
|
||||
|
||||
acc = head.get_accuracy(out, out, None, metas=metas)
|
||||
assert acc['mpjpe'] == 0.
|
||||
np.testing.assert_almost_equal(acc['p_mpjpe'], 0., decimal=6)
|
||||
|
||||
# w/ global position restoration
|
||||
head = TemporalRegressionHead(
|
||||
in_channels=1024,
|
||||
num_joints=16,
|
||||
loss_keypoint=dict(type='MPJPELoss', use_target_weight=True),
|
||||
test_cfg=dict(restore_global_position=True))
|
||||
head.init_weights()
|
||||
|
||||
input_shape = (1, 1024, 1)
|
||||
inputs = _demo_inputs(input_shape)
|
||||
metas = [{
|
||||
'root_position': np.zeros((1, 3)),
|
||||
'root_position_index': 0,
|
||||
'root_weight': 1.
|
||||
}]
|
||||
out = head(inputs)
|
||||
assert out.shape == torch.Size([1, 16, 3])
|
||||
|
||||
inference_out = head.inference_model(inputs)
|
||||
acc = head.get_accuracy(out, out, torch.ones_like(out), metas)
|
||||
assert acc['mpjpe'] == 0.
|
||||
np.testing.assert_almost_equal(acc['p_mpjpe'], 0.)
|
||||
|
||||
_ = head.decode(metas, inference_out)
|
||||
|
||||
# trajectory model (only predict root position)
|
||||
head = TemporalRegressionHead(
|
||||
in_channels=1024,
|
||||
num_joints=1,
|
||||
loss_keypoint=dict(type='MPJPELoss', use_target_weight=True),
|
||||
is_trajectory=True,
|
||||
test_cfg=dict(restore_global_position=False))
|
||||
|
||||
head.init_weights()
|
||||
|
||||
input_shape = (1, 1024, 1)
|
||||
inputs = _demo_inputs(input_shape)
|
||||
out = head(inputs)
|
||||
assert out.shape == torch.Size([1, 1, 3])
|
||||
|
||||
loss = head.get_loss(out, out.squeeze(1), torch.ones_like(out))
|
||||
assert torch.allclose(loss['traj_loss'], torch.tensor(0.))
|
||||
|
||||
|
||||
def _demo_inputs(input_shape=(1, 1024, 1)):
|
||||
"""Create a superset of inputs needed to run head.
|
||||
|
||||
Args:
|
||||
input_shape (tuple): input batch dimensions.
|
||||
Default: (1, 1024, 1).
|
||||
Returns:
|
||||
Random input tensor with the size of input_shape.
|
||||
"""
|
||||
inps = np.random.random(input_shape)
|
||||
inps = torch.FloatTensor(inps)
|
||||
return inps
|
||||
+517
@@ -0,0 +1,517 @@
|
||||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
import copy
|
||||
|
||||
import numpy as np
|
||||
import torch
|
||||
|
||||
from mmpose.models.detectors import PoseWarper, TopDown
|
||||
|
||||
|
||||
def test_vipnas_forward():
|
||||
# model settings
|
||||
|
||||
channel_cfg = dict(
|
||||
num_output_channels=17,
|
||||
dataset_joints=17,
|
||||
dataset_channel=[
|
||||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
|
||||
],
|
||||
inference_channel=[
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
|
||||
])
|
||||
|
||||
model_cfg = dict(
|
||||
type='TopDown',
|
||||
pretrained=None,
|
||||
backbone=dict(type='ViPNAS_ResNet', depth=50),
|
||||
keypoint_head=dict(
|
||||
type='ViPNASHeatmapSimpleHead',
|
||||
in_channels=608,
|
||||
out_channels=channel_cfg['num_output_channels'],
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True)),
|
||||
train_cfg=dict(),
|
||||
test_cfg=dict(
|
||||
flip_test=True,
|
||||
post_process='default',
|
||||
shift_heatmap=True,
|
||||
modulate_kernel=11))
|
||||
|
||||
detector = TopDown(model_cfg['backbone'], None, model_cfg['keypoint_head'],
|
||||
model_cfg['train_cfg'], model_cfg['test_cfg'],
|
||||
model_cfg['pretrained'])
|
||||
|
||||
input_shape = (1, 3, 256, 256)
|
||||
mm_inputs = _demo_mm_inputs(input_shape)
|
||||
|
||||
imgs = mm_inputs.pop('imgs')
|
||||
target = mm_inputs.pop('target')
|
||||
target_weight = mm_inputs.pop('target_weight')
|
||||
img_metas = mm_inputs.pop('img_metas')
|
||||
|
||||
# Test forward train
|
||||
losses = detector.forward(
|
||||
imgs, target, target_weight, img_metas, return_loss=True)
|
||||
assert isinstance(losses, dict)
|
||||
|
||||
# Test forward test
|
||||
with torch.no_grad():
|
||||
_ = detector.forward(imgs, img_metas=img_metas, return_loss=False)
|
||||
|
||||
|
||||
def test_topdown_forward():
|
||||
model_cfg = dict(
|
||||
type='TopDown',
|
||||
pretrained=None,
|
||||
backbone=dict(type='ResNet', depth=18),
|
||||
keypoint_head=dict(
|
||||
type='TopdownHeatmapSimpleHead',
|
||||
in_channels=512,
|
||||
out_channels=17,
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True)),
|
||||
train_cfg=dict(),
|
||||
test_cfg=dict(
|
||||
flip_test=True,
|
||||
post_process='default',
|
||||
shift_heatmap=True,
|
||||
modulate_kernel=11))
|
||||
|
||||
detector = TopDown(model_cfg['backbone'], None, model_cfg['keypoint_head'],
|
||||
model_cfg['train_cfg'], model_cfg['test_cfg'],
|
||||
model_cfg['pretrained'])
|
||||
|
||||
detector.init_weights()
|
||||
|
||||
input_shape = (1, 3, 256, 256)
|
||||
mm_inputs = _demo_mm_inputs(input_shape)
|
||||
|
||||
imgs = mm_inputs.pop('imgs')
|
||||
target = mm_inputs.pop('target')
|
||||
target_weight = mm_inputs.pop('target_weight')
|
||||
img_metas = mm_inputs.pop('img_metas')
|
||||
|
||||
# Test forward train
|
||||
losses = detector.forward(
|
||||
imgs, target, target_weight, img_metas, return_loss=True)
|
||||
assert isinstance(losses, dict)
|
||||
|
||||
# Test forward test
|
||||
with torch.no_grad():
|
||||
_ = detector.forward(imgs, img_metas=img_metas, return_loss=False)
|
||||
|
||||
# flip test
|
||||
model_cfg = dict(
|
||||
type='TopDown',
|
||||
pretrained=None,
|
||||
backbone=dict(
|
||||
type='HourglassNet',
|
||||
num_stacks=1,
|
||||
),
|
||||
keypoint_head=dict(
|
||||
type='TopdownHeatmapMultiStageHead',
|
||||
in_channels=256,
|
||||
out_channels=17,
|
||||
num_stages=1,
|
||||
num_deconv_layers=0,
|
||||
extra=dict(final_conv_kernel=1, ),
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=False)),
|
||||
train_cfg=dict(),
|
||||
test_cfg=dict(
|
||||
flip_test=True,
|
||||
post_process='default',
|
||||
shift_heatmap=True,
|
||||
modulate_kernel=11))
|
||||
|
||||
detector = TopDown(model_cfg['backbone'], None, model_cfg['keypoint_head'],
|
||||
model_cfg['train_cfg'], model_cfg['test_cfg'],
|
||||
model_cfg['pretrained'])
|
||||
|
||||
# Test forward train
|
||||
losses = detector.forward(
|
||||
imgs, target, target_weight, img_metas, return_loss=True)
|
||||
assert isinstance(losses, dict)
|
||||
|
||||
# Test forward test
|
||||
with torch.no_grad():
|
||||
_ = detector.forward(imgs, img_metas=img_metas, return_loss=False)
|
||||
|
||||
model_cfg = dict(
|
||||
type='TopDown',
|
||||
pretrained=None,
|
||||
backbone=dict(
|
||||
type='HourglassNet',
|
||||
num_stacks=1,
|
||||
),
|
||||
keypoint_head=dict(
|
||||
type='TopdownHeatmapMultiStageHead',
|
||||
in_channels=256,
|
||||
out_channels=17,
|
||||
num_stages=1,
|
||||
num_deconv_layers=0,
|
||||
extra=dict(final_conv_kernel=1, ),
|
||||
loss_keypoint=[
|
||||
dict(
|
||||
type='JointsMSELoss',
|
||||
use_target_weight=True,
|
||||
loss_weight=1.)
|
||||
]),
|
||||
train_cfg=dict(),
|
||||
test_cfg=dict(
|
||||
flip_test=True,
|
||||
post_process='default',
|
||||
shift_heatmap=True,
|
||||
modulate_kernel=11))
|
||||
|
||||
detector = TopDown(model_cfg['backbone'], None, model_cfg['keypoint_head'],
|
||||
model_cfg['train_cfg'], model_cfg['test_cfg'],
|
||||
model_cfg['pretrained'])
|
||||
|
||||
detector.init_weights()
|
||||
|
||||
input_shape = (1, 3, 256, 256)
|
||||
mm_inputs = _demo_mm_inputs(input_shape, num_outputs=None)
|
||||
|
||||
imgs = mm_inputs.pop('imgs')
|
||||
target = mm_inputs.pop('target')
|
||||
target_weight = mm_inputs.pop('target_weight')
|
||||
img_metas = mm_inputs.pop('img_metas')
|
||||
|
||||
# Test forward train
|
||||
losses = detector.forward(
|
||||
imgs, target, target_weight, img_metas, return_loss=True)
|
||||
assert isinstance(losses, dict)
|
||||
# Test forward test
|
||||
with torch.no_grad():
|
||||
_ = detector.forward(imgs, img_metas=img_metas, return_loss=False)
|
||||
|
||||
model_cfg = dict(
|
||||
type='TopDown',
|
||||
pretrained=None,
|
||||
backbone=dict(
|
||||
type='RSN',
|
||||
unit_channels=256,
|
||||
num_stages=1,
|
||||
num_units=4,
|
||||
num_blocks=[2, 2, 2, 2],
|
||||
num_steps=4,
|
||||
norm_cfg=dict(type='BN')),
|
||||
keypoint_head=dict(
|
||||
type='TopdownHeatmapMSMUHead',
|
||||
out_shape=(64, 48),
|
||||
unit_channels=256,
|
||||
out_channels=17,
|
||||
num_stages=1,
|
||||
num_units=4,
|
||||
use_prm=False,
|
||||
norm_cfg=dict(type='BN'),
|
||||
loss_keypoint=[dict(type='JointsMSELoss', use_target_weight=True)]
|
||||
* 3 + [dict(type='JointsOHKMMSELoss', use_target_weight=True)]),
|
||||
train_cfg=dict(num_units=4),
|
||||
test_cfg=dict(
|
||||
flip_test=True,
|
||||
post_process='default',
|
||||
shift_heatmap=False,
|
||||
unbiased_decoding=False,
|
||||
modulate_kernel=5))
|
||||
|
||||
detector = TopDown(model_cfg['backbone'], None, model_cfg['keypoint_head'],
|
||||
model_cfg['train_cfg'], model_cfg['test_cfg'],
|
||||
model_cfg['pretrained'])
|
||||
|
||||
detector.init_weights()
|
||||
|
||||
input_shape = (1, 3, 256, 192)
|
||||
mm_inputs = _demo_mm_inputs(input_shape, num_outputs=4)
|
||||
|
||||
imgs = mm_inputs.pop('imgs')
|
||||
target = mm_inputs.pop('target')
|
||||
target_weight = mm_inputs.pop('target_weight')
|
||||
img_metas = mm_inputs.pop('img_metas')
|
||||
|
||||
# Test forward train
|
||||
losses = detector.forward(
|
||||
imgs, target, target_weight, img_metas, return_loss=True)
|
||||
assert isinstance(losses, dict)
|
||||
# Test forward test
|
||||
with torch.no_grad():
|
||||
_ = detector.forward(imgs, img_metas=img_metas, return_loss=False)
|
||||
_ = detector.forward_dummy(imgs)
|
||||
|
||||
|
||||
def test_posewarper_forward():
|
||||
# test PoseWarper
|
||||
model_cfg = dict(
|
||||
type='PoseWarper',
|
||||
pretrained=None,
|
||||
backbone=dict(
|
||||
type='HRNet',
|
||||
in_channels=3,
|
||||
extra=dict(
|
||||
stage1=dict(
|
||||
num_modules=1,
|
||||
num_branches=1,
|
||||
block='BOTTLENECK',
|
||||
num_blocks=(4, ),
|
||||
num_channels=(64, )),
|
||||
stage2=dict(
|
||||
num_modules=1,
|
||||
num_branches=2,
|
||||
block='BASIC',
|
||||
num_blocks=(4, 4),
|
||||
num_channels=(48, 96)),
|
||||
stage3=dict(
|
||||
num_modules=4,
|
||||
num_branches=3,
|
||||
block='BASIC',
|
||||
num_blocks=(4, 4, 4),
|
||||
num_channels=(48, 96, 192)),
|
||||
stage4=dict(
|
||||
num_modules=3,
|
||||
num_branches=4,
|
||||
block='BASIC',
|
||||
num_blocks=(4, 4, 4, 4),
|
||||
num_channels=(48, 96, 192, 384))),
|
||||
frozen_stages=4,
|
||||
),
|
||||
concat_tensors=True,
|
||||
neck=dict(
|
||||
type='PoseWarperNeck',
|
||||
in_channels=48,
|
||||
freeze_trans_layer=True,
|
||||
out_channels=17,
|
||||
inner_channels=128,
|
||||
deform_groups=17,
|
||||
dilations=(3, 6, 12, 18, 24),
|
||||
trans_conv_kernel=1,
|
||||
res_blocks_cfg=dict(block='BASIC', num_blocks=20),
|
||||
offsets_kernel=3,
|
||||
deform_conv_kernel=3),
|
||||
keypoint_head=dict(
|
||||
type='TopdownHeatmapSimpleHead',
|
||||
in_channels=17,
|
||||
out_channels=17,
|
||||
num_deconv_layers=0,
|
||||
extra=dict(final_conv_kernel=0, ),
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True)),
|
||||
train_cfg=dict(),
|
||||
test_cfg=dict(
|
||||
flip_test=False,
|
||||
post_process='default',
|
||||
shift_heatmap=True,
|
||||
modulate_kernel=11))
|
||||
|
||||
detector = PoseWarper(model_cfg['backbone'], model_cfg['neck'],
|
||||
model_cfg['keypoint_head'], model_cfg['train_cfg'],
|
||||
model_cfg['test_cfg'], model_cfg['pretrained'], None,
|
||||
model_cfg['concat_tensors'])
|
||||
assert detector.concat_tensors
|
||||
|
||||
detector.init_weights()
|
||||
|
||||
input_shape = (2, 3, 64, 64)
|
||||
num_frames = 2
|
||||
mm_inputs = _demo_mm_inputs(input_shape, None, num_frames)
|
||||
|
||||
imgs = mm_inputs.pop('imgs')
|
||||
target = mm_inputs.pop('target')
|
||||
target_weight = mm_inputs.pop('target_weight')
|
||||
img_metas = mm_inputs.pop('img_metas')
|
||||
|
||||
# Test forward train
|
||||
losses = detector.forward(
|
||||
imgs, target, target_weight, img_metas, return_loss=True)
|
||||
assert isinstance(losses, dict)
|
||||
|
||||
# Test forward test
|
||||
with torch.no_grad():
|
||||
_ = detector.forward(imgs, img_metas=img_metas, return_loss=False)
|
||||
_ = detector.forward_dummy(imgs)
|
||||
|
||||
# test argument 'concat_tensors'
|
||||
model_cfg_copy = copy.deepcopy(model_cfg)
|
||||
model_cfg_copy['concat_tensors'] = False
|
||||
|
||||
detector = PoseWarper(model_cfg_copy['backbone'], model_cfg_copy['neck'],
|
||||
model_cfg_copy['keypoint_head'],
|
||||
model_cfg_copy['train_cfg'],
|
||||
model_cfg_copy['test_cfg'],
|
||||
model_cfg_copy['pretrained'], None,
|
||||
model_cfg_copy['concat_tensors'])
|
||||
assert not detector.concat_tensors
|
||||
|
||||
detector.init_weights()
|
||||
|
||||
input_shape = (2, 3, 64, 64)
|
||||
num_frames = 2
|
||||
mm_inputs = _demo_mm_inputs(input_shape, None, num_frames)
|
||||
|
||||
imgs = mm_inputs.pop('imgs')
|
||||
target = mm_inputs.pop('target')
|
||||
target_weight = mm_inputs.pop('target_weight')
|
||||
img_metas = mm_inputs.pop('img_metas')
|
||||
|
||||
# Test forward train
|
||||
losses = detector.forward(
|
||||
imgs, target, target_weight, img_metas, return_loss=True)
|
||||
assert isinstance(losses, dict)
|
||||
|
||||
# Test forward test
|
||||
with torch.no_grad():
|
||||
_ = detector.forward(imgs, img_metas=img_metas, return_loss=False)
|
||||
_ = detector.forward_dummy(imgs)
|
||||
|
||||
# flip test
|
||||
model_cfg_copy = copy.deepcopy(model_cfg)
|
||||
model_cfg_copy['test_cfg']['flip_test'] = True
|
||||
|
||||
detector = PoseWarper(model_cfg_copy['backbone'], model_cfg_copy['neck'],
|
||||
model_cfg_copy['keypoint_head'],
|
||||
model_cfg_copy['train_cfg'],
|
||||
model_cfg_copy['test_cfg'],
|
||||
model_cfg_copy['pretrained'], None,
|
||||
model_cfg_copy['concat_tensors'])
|
||||
|
||||
detector.init_weights()
|
||||
|
||||
input_shape = (1, 3, 64, 64)
|
||||
num_frames = 2
|
||||
mm_inputs = _demo_mm_inputs(input_shape, None, num_frames)
|
||||
|
||||
imgs = mm_inputs.pop('imgs')
|
||||
target = mm_inputs.pop('target')
|
||||
target_weight = mm_inputs.pop('target_weight')
|
||||
img_metas = mm_inputs.pop('img_metas')
|
||||
|
||||
# Test forward train
|
||||
losses = detector.forward(
|
||||
imgs, target, target_weight, img_metas, return_loss=True)
|
||||
assert isinstance(losses, dict)
|
||||
|
||||
# Test forward test
|
||||
with torch.no_grad():
|
||||
_ = detector.forward(imgs, img_metas=img_metas, return_loss=False)
|
||||
_ = detector.forward_dummy(imgs)
|
||||
|
||||
# test different number of dilations
|
||||
model_cfg_copy = copy.deepcopy(model_cfg)
|
||||
model_cfg_copy['neck']['dilations'] = (3, 6, 12)
|
||||
|
||||
detector = PoseWarper(model_cfg_copy['backbone'], model_cfg_copy['neck'],
|
||||
model_cfg_copy['keypoint_head'],
|
||||
model_cfg_copy['train_cfg'],
|
||||
model_cfg_copy['test_cfg'],
|
||||
model_cfg_copy['pretrained'], None,
|
||||
model_cfg_copy['concat_tensors'])
|
||||
|
||||
detector.init_weights()
|
||||
|
||||
input_shape = (2, 3, 64, 64)
|
||||
num_frames = 2
|
||||
mm_inputs = _demo_mm_inputs(input_shape, None, num_frames)
|
||||
|
||||
imgs = mm_inputs.pop('imgs')
|
||||
target = mm_inputs.pop('target')
|
||||
target_weight = mm_inputs.pop('target_weight')
|
||||
img_metas = mm_inputs.pop('img_metas')
|
||||
|
||||
# Test forward train
|
||||
losses = detector.forward(
|
||||
imgs, target, target_weight, img_metas, return_loss=True)
|
||||
assert isinstance(losses, dict)
|
||||
|
||||
# Test forward test
|
||||
with torch.no_grad():
|
||||
_ = detector.forward(imgs, img_metas=img_metas, return_loss=False)
|
||||
_ = detector.forward_dummy(imgs)
|
||||
|
||||
# test different backbone, change head accordingly
|
||||
model_cfg_copy = copy.deepcopy(model_cfg)
|
||||
model_cfg_copy['backbone'] = dict(type='ResNet', depth=18)
|
||||
model_cfg_copy['neck']['in_channels'] = 512
|
||||
model_cfg_copy['keypoint_head'] = dict(
|
||||
type='TopdownHeatmapSimpleHead',
|
||||
in_channels=17,
|
||||
out_channels=17,
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
|
||||
detector = PoseWarper(model_cfg_copy['backbone'], model_cfg_copy['neck'],
|
||||
model_cfg_copy['keypoint_head'],
|
||||
model_cfg_copy['train_cfg'],
|
||||
model_cfg_copy['test_cfg'],
|
||||
model_cfg_copy['pretrained'], None,
|
||||
model_cfg_copy['concat_tensors'])
|
||||
|
||||
detector.init_weights()
|
||||
|
||||
input_shape = (1, 3, 64, 64)
|
||||
num_frames = 2
|
||||
mm_inputs = _demo_mm_inputs(input_shape, None, num_frames)
|
||||
|
||||
imgs = mm_inputs.pop('imgs')
|
||||
target = mm_inputs.pop('target')
|
||||
target_weight = mm_inputs.pop('target_weight')
|
||||
img_metas = mm_inputs.pop('img_metas')
|
||||
|
||||
# Test forward train
|
||||
losses = detector.forward(
|
||||
imgs, target, target_weight, img_metas, return_loss=True)
|
||||
assert isinstance(losses, dict)
|
||||
|
||||
# Test forward test
|
||||
with torch.no_grad():
|
||||
_ = detector.forward(imgs, img_metas=img_metas, return_loss=False)
|
||||
_ = detector.forward_dummy(imgs)
|
||||
|
||||
|
||||
def _demo_mm_inputs(
|
||||
input_shape=(1, 3, 256, 256), num_outputs=None, num_frames=1):
|
||||
"""Create a superset of inputs needed to run test or train batches.
|
||||
|
||||
Args:
|
||||
input_shape (tuple):
|
||||
input batch dimensions
|
||||
num_frames (int):
|
||||
number of frames for each sample, default: 1,
|
||||
if larger than 1, return a list of tensors
|
||||
"""
|
||||
(N, C, H, W) = input_shape
|
||||
|
||||
rng = np.random.RandomState(0)
|
||||
|
||||
imgs = rng.rand(*input_shape)
|
||||
if num_outputs is not None:
|
||||
target = np.zeros([N, num_outputs, 17, H // 4, W // 4],
|
||||
dtype=np.float32)
|
||||
target_weight = np.ones([N, num_outputs, 17, 1], dtype=np.float32)
|
||||
else:
|
||||
target = np.zeros([N, 17, H // 4, W // 4], dtype=np.float32)
|
||||
target_weight = np.ones([N, 17, 1], dtype=np.float32)
|
||||
|
||||
img_metas = [{
|
||||
'img_shape': (H, W, C),
|
||||
'center': np.array([W / 2, H / 2]),
|
||||
'scale': np.array([0.5, 0.5]),
|
||||
'bbox_score': 1.0,
|
||||
'bbox_id': 0,
|
||||
'flip_pairs': [],
|
||||
'inference_channel': np.arange(17),
|
||||
'image_file': '<demo>.png',
|
||||
'frame_weight': np.random.uniform(0, 1, num_frames),
|
||||
} for _ in range(N)]
|
||||
|
||||
mm_inputs = {
|
||||
'target': torch.FloatTensor(target),
|
||||
'target_weight': torch.FloatTensor(target_weight),
|
||||
'img_metas': img_metas
|
||||
}
|
||||
|
||||
if num_frames == 1:
|
||||
imgs = torch.FloatTensor(rng.rand(*input_shape)).requires_grad_(True)
|
||||
else:
|
||||
|
||||
imgs = [
|
||||
torch.FloatTensor(rng.rand(*input_shape)).requires_grad_(True)
|
||||
for _ in range(num_frames)
|
||||
]
|
||||
|
||||
mm_inputs['imgs'] = imgs
|
||||
return mm_inputs
|
||||
+518
@@ -0,0 +1,518 @@
|
||||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
import numpy as np
|
||||
import pytest
|
||||
import torch
|
||||
|
||||
from mmpose.models import (DeepposeRegressionHead, TopdownHeatmapMSMUHead,
|
||||
TopdownHeatmapMultiStageHead,
|
||||
TopdownHeatmapSimpleHead, ViPNASHeatmapSimpleHead)
|
||||
|
||||
|
||||
def test_vipnas_simple_head():
|
||||
"""Test simple head."""
|
||||
with pytest.raises(TypeError):
|
||||
# extra
|
||||
_ = ViPNASHeatmapSimpleHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
extra=[],
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
head = ViPNASHeatmapSimpleHead(
|
||||
out_channels=3, in_channels=512, extra={'final_conv_kernel': 1})
|
||||
|
||||
# test num deconv layers
|
||||
with pytest.raises(ValueError):
|
||||
_ = ViPNASHeatmapSimpleHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
num_deconv_layers=-1,
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
|
||||
_ = ViPNASHeatmapSimpleHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
num_deconv_layers=0,
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
# the number of layers should match
|
||||
_ = ViPNASHeatmapSimpleHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
num_deconv_layers=3,
|
||||
num_deconv_filters=(256, 256),
|
||||
num_deconv_kernels=(4, 4),
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
# the number of kernels should match
|
||||
_ = ViPNASHeatmapSimpleHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
num_deconv_layers=3,
|
||||
num_deconv_filters=(256, 256, 256),
|
||||
num_deconv_kernels=(4, 4),
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
# the deconv kernels should be 4, 3, 2
|
||||
_ = ViPNASHeatmapSimpleHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
num_deconv_layers=3,
|
||||
num_deconv_filters=(256, 256, 256),
|
||||
num_deconv_kernels=(3, 2, 0),
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
# the deconv kernels should be 4, 3, 2
|
||||
_ = ViPNASHeatmapSimpleHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
num_deconv_layers=3,
|
||||
num_deconv_filters=(256, 256, 256),
|
||||
num_deconv_kernels=(4, 4, -1),
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
|
||||
# test final_conv_kernel
|
||||
head = ViPNASHeatmapSimpleHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
extra={'final_conv_kernel': 3},
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
head.init_weights()
|
||||
assert head.final_layer.padding == (1, 1)
|
||||
head = ViPNASHeatmapSimpleHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
extra={'final_conv_kernel': 1},
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
assert head.final_layer.padding == (0, 0)
|
||||
_ = ViPNASHeatmapSimpleHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
extra={'final_conv_kernel': 0},
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
|
||||
head = ViPNASHeatmapSimpleHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True),
|
||||
extra=dict(
|
||||
final_conv_kernel=1, num_conv_layers=1, num_conv_kernels=(1, )))
|
||||
assert len(head.final_layer) == 4
|
||||
|
||||
head = ViPNASHeatmapSimpleHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
input_shape = (1, 512, 32, 32)
|
||||
inputs = _demo_inputs(input_shape)
|
||||
out = head(inputs)
|
||||
assert out.shape == torch.Size([1, 3, 256, 256])
|
||||
|
||||
head = ViPNASHeatmapSimpleHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
num_deconv_layers=0,
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
input_shape = (1, 512, 32, 32)
|
||||
inputs = _demo_inputs(input_shape)
|
||||
out = head(inputs)
|
||||
assert out.shape == torch.Size([1, 3, 32, 32])
|
||||
|
||||
head = ViPNASHeatmapSimpleHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
num_deconv_layers=0,
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
input_shape = (1, 512, 32, 32)
|
||||
inputs = _demo_inputs(input_shape)
|
||||
out = head([inputs])
|
||||
assert out.shape == torch.Size([1, 3, 32, 32])
|
||||
|
||||
head.init_weights()
|
||||
|
||||
|
||||
def test_top_down_simple_head():
|
||||
"""Test simple head."""
|
||||
with pytest.raises(TypeError):
|
||||
# extra
|
||||
_ = TopdownHeatmapSimpleHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
extra=[],
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
head = TopdownHeatmapSimpleHead(
|
||||
out_channels=3, in_channels=512, extra={'final_conv_kernel': 1})
|
||||
|
||||
# test num deconv layers
|
||||
with pytest.raises(ValueError):
|
||||
_ = TopdownHeatmapSimpleHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
num_deconv_layers=-1,
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
|
||||
_ = TopdownHeatmapSimpleHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
num_deconv_layers=0,
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
# the number of layers should match
|
||||
_ = TopdownHeatmapSimpleHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
num_deconv_layers=3,
|
||||
num_deconv_filters=(256, 256),
|
||||
num_deconv_kernels=(4, 4),
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
# the number of kernels should match
|
||||
_ = TopdownHeatmapSimpleHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
num_deconv_layers=3,
|
||||
num_deconv_filters=(256, 256, 256),
|
||||
num_deconv_kernels=(4, 4),
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
# the deconv kernels should be 4, 3, 2
|
||||
_ = TopdownHeatmapSimpleHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
num_deconv_layers=3,
|
||||
num_deconv_filters=(256, 256, 256),
|
||||
num_deconv_kernels=(3, 2, 0),
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
# the deconv kernels should be 4, 3, 2
|
||||
_ = TopdownHeatmapSimpleHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
num_deconv_layers=3,
|
||||
num_deconv_filters=(256, 256, 256),
|
||||
num_deconv_kernels=(4, 4, -1),
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
|
||||
# test final_conv_kernel
|
||||
head = TopdownHeatmapSimpleHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
extra={'final_conv_kernel': 3},
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
head.init_weights()
|
||||
assert head.final_layer.padding == (1, 1)
|
||||
head = TopdownHeatmapSimpleHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
extra={'final_conv_kernel': 1},
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
assert head.final_layer.padding == (0, 0)
|
||||
_ = TopdownHeatmapSimpleHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
extra={'final_conv_kernel': 0},
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
|
||||
head = TopdownHeatmapSimpleHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True),
|
||||
extra=dict(
|
||||
final_conv_kernel=1, num_conv_layers=1, num_conv_kernels=(1, )))
|
||||
assert len(head.final_layer) == 4
|
||||
|
||||
head = TopdownHeatmapSimpleHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
input_shape = (1, 512, 32, 32)
|
||||
inputs = _demo_inputs(input_shape)
|
||||
out = head(inputs)
|
||||
assert out.shape == torch.Size([1, 3, 256, 256])
|
||||
|
||||
head = TopdownHeatmapSimpleHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
num_deconv_layers=0,
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
input_shape = (1, 512, 32, 32)
|
||||
inputs = _demo_inputs(input_shape)
|
||||
out = head(inputs)
|
||||
assert out.shape == torch.Size([1, 3, 32, 32])
|
||||
|
||||
head = TopdownHeatmapSimpleHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
num_deconv_layers=0,
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
input_shape = (1, 512, 32, 32)
|
||||
inputs = _demo_inputs(input_shape)
|
||||
out = head([inputs])
|
||||
assert out.shape == torch.Size([1, 3, 32, 32])
|
||||
|
||||
head.init_weights()
|
||||
|
||||
|
||||
def test_top_down_multistage_head():
|
||||
"""Test multistage head."""
|
||||
with pytest.raises(TypeError):
|
||||
# the number of layers should match
|
||||
_ = TopdownHeatmapMultiStageHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
num_stages=1,
|
||||
extra=[],
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
|
||||
# test num deconv layers
|
||||
with pytest.raises(ValueError):
|
||||
_ = TopdownHeatmapMultiStageHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
num_deconv_layers=-1,
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
|
||||
_ = TopdownHeatmapMultiStageHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
num_deconv_layers=0,
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
# the number of layers should match
|
||||
_ = TopdownHeatmapMultiStageHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
num_stages=1,
|
||||
num_deconv_layers=3,
|
||||
num_deconv_filters=(256, 256),
|
||||
num_deconv_kernels=(4, 4),
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
# the number of kernels should match
|
||||
_ = TopdownHeatmapMultiStageHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
num_stages=1,
|
||||
num_deconv_layers=3,
|
||||
num_deconv_filters=(256, 256, 256),
|
||||
num_deconv_kernels=(4, 4),
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
# the deconv kernels should be 4, 3, 2
|
||||
_ = TopdownHeatmapMultiStageHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
num_stages=1,
|
||||
num_deconv_layers=3,
|
||||
num_deconv_filters=(256, 256, 256),
|
||||
num_deconv_kernels=(3, 2, 0),
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
# the deconv kernels should be 4, 3, 2
|
||||
_ = TopdownHeatmapMultiStageHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
num_deconv_layers=3,
|
||||
num_deconv_filters=(256, 256, 256),
|
||||
num_deconv_kernels=(4, 4, -1),
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
|
||||
with pytest.raises(AssertionError):
|
||||
# inputs should be list
|
||||
head = TopdownHeatmapMultiStageHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
input_shape = (1, 512, 32, 32)
|
||||
inputs = _demo_inputs(input_shape)
|
||||
out = head(inputs)
|
||||
|
||||
# test final_conv_kernel
|
||||
head = TopdownHeatmapMultiStageHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
extra={'final_conv_kernel': 3},
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
head.init_weights()
|
||||
assert head.multi_final_layers[0].padding == (1, 1)
|
||||
head = TopdownHeatmapMultiStageHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
extra={'final_conv_kernel': 1},
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
assert head.multi_final_layers[0].padding == (0, 0)
|
||||
_ = TopdownHeatmapMultiStageHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
extra={'final_conv_kernel': 0},
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
|
||||
head = TopdownHeatmapMultiStageHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
input_shape = (1, 512, 32, 32)
|
||||
inputs = _demo_inputs(input_shape)
|
||||
out = head([inputs])
|
||||
assert len(out) == 1
|
||||
assert out[0].shape == torch.Size([1, 3, 256, 256])
|
||||
|
||||
head = TopdownHeatmapMultiStageHead(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
num_deconv_layers=0,
|
||||
loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True))
|
||||
input_shape = (1, 512, 32, 32)
|
||||
inputs = _demo_inputs(input_shape)
|
||||
out = head([inputs])
|
||||
assert out[0].shape == torch.Size([1, 3, 32, 32])
|
||||
|
||||
head.init_weights()
|
||||
|
||||
|
||||
def test_top_down_msmu_head():
|
||||
"""Test multi-stage multi-unit head."""
|
||||
with pytest.raises(AssertionError):
|
||||
# inputs should be list
|
||||
head = TopdownHeatmapMSMUHead(
|
||||
out_shape=(64, 48),
|
||||
unit_channels=256,
|
||||
num_stages=2,
|
||||
num_units=2,
|
||||
loss_keypoint=(
|
||||
[dict(type='JointsMSELoss', use_target_weight=True)] * 2 +
|
||||
[dict(type='JointsOHKMMSELoss', use_target_weight=True)]) * 2)
|
||||
input_shape = (1, 256, 32, 32)
|
||||
inputs = _demo_inputs(input_shape)
|
||||
_ = head(inputs)
|
||||
|
||||
with pytest.raises(AssertionError):
|
||||
# inputs should be list[list, ...]
|
||||
head = TopdownHeatmapMSMUHead(
|
||||
out_shape=(64, 48),
|
||||
unit_channels=256,
|
||||
num_stages=2,
|
||||
num_units=2,
|
||||
loss_keypoint=(
|
||||
[dict(type='JointsMSELoss', use_target_weight=True)] * 2 +
|
||||
[dict(type='JointsOHKMMSELoss', use_target_weight=True)]) * 2)
|
||||
input_shape = (1, 256, 32, 32)
|
||||
inputs = _demo_inputs(input_shape)
|
||||
inputs = [inputs] * 2
|
||||
_ = head(inputs)
|
||||
|
||||
with pytest.raises(AssertionError):
|
||||
# len(inputs) should equal to num_stages
|
||||
head = TopdownHeatmapMSMUHead(
|
||||
out_shape=(64, 48),
|
||||
unit_channels=256,
|
||||
num_stages=2,
|
||||
num_units=2,
|
||||
loss_keypoint=(
|
||||
[dict(type='JointsMSELoss', use_target_weight=True)] * 2 +
|
||||
[dict(type='JointsOHKMMSELoss', use_target_weight=True)]) * 2)
|
||||
input_shape = (1, 256, 32, 32)
|
||||
inputs = _demo_inputs(input_shape)
|
||||
inputs = [[inputs] * 2] * 3
|
||||
_ = head(inputs)
|
||||
|
||||
with pytest.raises(AssertionError):
|
||||
# len(inputs[0]) should equal to num_units
|
||||
head = TopdownHeatmapMSMUHead(
|
||||
out_shape=(64, 48),
|
||||
unit_channels=256,
|
||||
num_stages=2,
|
||||
num_units=2,
|
||||
loss_keypoint=(
|
||||
[dict(type='JointsMSELoss', use_target_weight=True)] * 2 +
|
||||
[dict(type='JointsOHKMMSELoss', use_target_weight=True)]) * 2)
|
||||
input_shape = (1, 256, 32, 32)
|
||||
inputs = _demo_inputs(input_shape)
|
||||
inputs = [[inputs] * 3] * 2
|
||||
_ = head(inputs)
|
||||
|
||||
with pytest.raises(AssertionError):
|
||||
# input channels should equal to param unit_channels
|
||||
head = TopdownHeatmapMSMUHead(
|
||||
out_shape=(64, 48),
|
||||
unit_channels=256,
|
||||
num_stages=2,
|
||||
num_units=2,
|
||||
loss_keypoint=(
|
||||
[dict(type='JointsMSELoss', use_target_weight=True)] * 2 +
|
||||
[dict(type='JointsOHKMMSELoss', use_target_weight=True)]) * 2)
|
||||
input_shape = (1, 128, 32, 32)
|
||||
inputs = _demo_inputs(input_shape)
|
||||
inputs = [[inputs] * 2] * 2
|
||||
_ = head(inputs)
|
||||
|
||||
head = TopdownHeatmapMSMUHead(
|
||||
out_shape=(64, 48),
|
||||
unit_channels=256,
|
||||
out_channels=17,
|
||||
num_stages=2,
|
||||
num_units=2,
|
||||
loss_keypoint=(
|
||||
[dict(type='JointsMSELoss', use_target_weight=True)] * 2 +
|
||||
[dict(type='JointsOHKMMSELoss', use_target_weight=True)]) * 2)
|
||||
input_shape = (1, 256, 32, 32)
|
||||
inputs = _demo_inputs(input_shape)
|
||||
inputs = [[inputs] * 2] * 2
|
||||
out = head(inputs)
|
||||
assert len(out) == 2 * 2
|
||||
assert out[0].shape == torch.Size([1, 17, 64, 48])
|
||||
|
||||
head.init_weights()
|
||||
|
||||
|
||||
def test_fc_head():
|
||||
"""Test fc head."""
|
||||
head = DeepposeRegressionHead(
|
||||
in_channels=2048,
|
||||
num_joints=17,
|
||||
loss_keypoint=dict(type='SmoothL1Loss', use_target_weight=True))
|
||||
|
||||
head.init_weights()
|
||||
|
||||
input_shape = (1, 2048)
|
||||
inputs = _demo_inputs(input_shape)
|
||||
out = head(inputs)
|
||||
assert out.shape == torch.Size([1, 17, 2])
|
||||
|
||||
loss = head.get_loss(out, out, torch.ones_like(out))
|
||||
assert torch.allclose(loss['reg_loss'], torch.tensor(0.))
|
||||
|
||||
_ = head.inference_model(inputs)
|
||||
_ = head.inference_model(inputs, [])
|
||||
|
||||
acc = head.get_accuracy(out, out, torch.ones_like(out))
|
||||
assert acc['acc_pose'] == 1.
|
||||
|
||||
|
||||
def _demo_inputs(input_shape=(1, 3, 64, 64)):
|
||||
"""Create a superset of inputs needed to run backbone.
|
||||
|
||||
Args:
|
||||
input_shape (tuple): input batch dimensions.
|
||||
Default: (1, 3, 64, 64).
|
||||
Returns:
|
||||
Random input tensor with the size of input_shape.
|
||||
"""
|
||||
inps = np.random.random(input_shape)
|
||||
inps = torch.FloatTensor(inps)
|
||||
return inps
|
||||
Reference in New Issue
Block a user