Initial snapshot: hand motion pipeline (Dyn-HaMR + dex-retargeting + SPIDER)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
import numpy as np
|
||||
import pytest
|
||||
import torch
|
||||
|
||||
from mmpose.models.necks import GlobalAveragePooling
|
||||
|
||||
|
||||
def test_gap():
|
||||
"""Test GlobalAveragePooling neck."""
|
||||
gap = GlobalAveragePooling()
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
gap(1)
|
||||
|
||||
x0_shape = (32, 1024, 4, 4)
|
||||
x1_shape = (32, 2048, 2, 2)
|
||||
x0 = _demo_inputs(x0_shape)
|
||||
x1 = _demo_inputs(x1_shape)
|
||||
|
||||
y = gap(x0)
|
||||
assert y.shape == torch.Size([32, 1024])
|
||||
|
||||
y = gap([x0, x1])
|
||||
assert y[0].shape == torch.Size([32, 1024])
|
||||
assert y[1].shape == torch.Size([32, 2048])
|
||||
|
||||
y = gap((x0, x1))
|
||||
assert y[0].shape == torch.Size([32, 1024])
|
||||
assert y[1].shape == torch.Size([32, 2048])
|
||||
|
||||
|
||||
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).
|
||||
"""
|
||||
imgs = np.random.random(input_shape)
|
||||
imgs = torch.FloatTensor(imgs)
|
||||
|
||||
return imgs
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
import numpy as np
|
||||
import pytest
|
||||
import torch
|
||||
|
||||
from mmpose.models.necks import PoseWarperNeck
|
||||
|
||||
|
||||
def test_posewarper_neck():
|
||||
"""Test PoseWarperNeck."""
|
||||
with pytest.raises(AssertionError):
|
||||
# test value of trans_conv_kernel
|
||||
_ = PoseWarperNeck(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
inner_channels=128,
|
||||
trans_conv_kernel=2)
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
# test type of res_blocks_cfg
|
||||
_ = PoseWarperNeck(
|
||||
out_channels=3,
|
||||
in_channels=512,
|
||||
inner_channels=128,
|
||||
res_blocks_cfg=2)
|
||||
|
||||
with pytest.raises(AssertionError):
|
||||
# test value of dilations
|
||||
neck = PoseWarperNeck(
|
||||
out_channels=3, in_channels=512, inner_channels=128, dilations=[])
|
||||
|
||||
in_channels = 48
|
||||
out_channels = 17
|
||||
inner_channels = 128
|
||||
|
||||
neck = PoseWarperNeck(
|
||||
in_channels=in_channels,
|
||||
out_channels=out_channels,
|
||||
inner_channels=inner_channels)
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
# the forward require two arguments: inputs and frame_weight
|
||||
_ = neck(1)
|
||||
|
||||
with pytest.raises(AssertionError):
|
||||
# the inputs to PoseWarperNeck must be list or tuple
|
||||
_ = neck(1, [0.1])
|
||||
|
||||
# test the case when num_frames * batch_size if larger than
|
||||
# the default value of 'im2col_step' but can not be divided
|
||||
# by it in mmcv.ops.deform_conv
|
||||
b_0 = 8 # batch_size
|
||||
b_1 = 16
|
||||
h_0 = 4 # image height
|
||||
h_1 = 2
|
||||
|
||||
num_frame_0 = 2
|
||||
num_frame_1 = 5
|
||||
|
||||
# test input format
|
||||
# B, C, H, W
|
||||
x0_shape = (b_0, in_channels, h_0, h_0)
|
||||
x1_shape = (b_1, in_channels, h_1, h_1)
|
||||
|
||||
# test concat_tensors case
|
||||
# at the same time, features output from backbone like ResNet is Tensors
|
||||
x0_shape = (b_0 * num_frame_0, in_channels, h_0, h_0)
|
||||
x0 = _demo_inputs(x0_shape, length=1)
|
||||
frame_weight_0 = np.random.uniform(0, 1, num_frame_0)
|
||||
|
||||
# test forward
|
||||
y = neck(x0, frame_weight_0)
|
||||
assert y.shape == torch.Size([b_0, out_channels, h_0, h_0])
|
||||
|
||||
# test concat_tensors case
|
||||
# this time, features output from backbone like HRNet
|
||||
# is list of Tensors rather than Tensors
|
||||
x0_shape = (b_0 * num_frame_0, in_channels, h_0, h_0)
|
||||
x0 = _demo_inputs(x0_shape, length=2)
|
||||
x0 = [x0]
|
||||
frame_weight_0 = np.random.uniform(0, 1, num_frame_0)
|
||||
|
||||
# test forward
|
||||
y = neck(x0, frame_weight_0)
|
||||
assert y.shape == torch.Size([b_0, out_channels, h_0, h_0])
|
||||
|
||||
# test not concat_tensors case
|
||||
# at the same time, features output from backbone like ResNet is Tensors
|
||||
x1_shape = (b_1, in_channels, h_1, h_1)
|
||||
x1 = _demo_inputs(x1_shape, length=num_frame_1)
|
||||
frame_weight_1 = np.random.uniform(0, 1, num_frame_1)
|
||||
|
||||
# test forward
|
||||
y = neck(x1, frame_weight_1)
|
||||
assert y.shape == torch.Size([b_1, out_channels, h_1, h_1])
|
||||
|
||||
# test not concat_tensors case
|
||||
# this time, features output from backbone like HRNet
|
||||
# is list of Tensors rather than Tensors
|
||||
x1_shape = (b_1, in_channels, h_1, h_1)
|
||||
x1 = _demo_inputs(x1_shape, length=2)
|
||||
x1 = [x1 for _ in range(num_frame_1)]
|
||||
frame_weight_1 = np.random.uniform(0, 1, num_frame_1)
|
||||
|
||||
# test forward
|
||||
y = neck(x1, frame_weight_1)
|
||||
assert y.shape == torch.Size([b_1, out_channels, h_1, h_1])
|
||||
|
||||
# test special case that when in concat_tensors case,
|
||||
# batch_size * num_frames is larger than the default value
|
||||
# 'im2col_step' in mmcv.ops.deform_conv, but can not be divided by it
|
||||
# see https://github.com/open-mmlab/mmcv/issues/1440
|
||||
x1_shape = (b_1 * num_frame_1, in_channels, h_1, h_1)
|
||||
x1 = _demo_inputs(x1_shape, length=2)
|
||||
x1 = [x1]
|
||||
frame_weight_0 = np.random.uniform(0, 1, num_frame_1)
|
||||
|
||||
y = neck(x1, frame_weight_1)
|
||||
assert y.shape == torch.Size([b_1, out_channels, h_1, h_1])
|
||||
|
||||
# test the inappropriate value of `im2col_step`
|
||||
neck = PoseWarperNeck(
|
||||
in_channels=in_channels,
|
||||
out_channels=out_channels,
|
||||
inner_channels=inner_channels,
|
||||
im2col_step=32)
|
||||
with pytest.raises(AssertionError):
|
||||
_ = neck(x1, frame_weight_1)
|
||||
|
||||
|
||||
def _demo_inputs(input_shape=(80, 48, 4, 4), length=1):
|
||||
"""Create a superset of inputs needed to run backbone.
|
||||
|
||||
Args:
|
||||
input_shape (tuple): input batch dimensions.
|
||||
Default: (1, 3, 64, 64).
|
||||
length (int): the length of output list
|
||||
nested (bool): whether the output Tensor is double-nested list.
|
||||
"""
|
||||
imgs = [
|
||||
torch.FloatTensor(np.random.random(input_shape)) for _ in range(length)
|
||||
]
|
||||
return imgs
|
||||
Reference in New Issue
Block a user