Skip to content

Commit

Permalink
add fp16 cfg and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jin-s13 committed Nov 23, 2020
1 parent 92bfd09 commit 2394a40
Show file tree
Hide file tree
Showing 5 changed files with 308 additions and 0 deletions.
199 changes: 199 additions & 0 deletions configs/bottom_up/hrnet/coco/hrnet_w32_coco_512x512_fp16.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
log_level = 'INFO'
load_from = None
resume_from = None
# fp16 settings
fp16 = dict()
# runtime settings
dist_params = dict(backend='nccl')
workflow = [('train', 1)]
checkpoint_config = dict(interval=50)
evaluation = dict(interval=50, metric='mAP', key_indicator='AP')

optimizer = dict(
type='Adam',
lr=0.0015,
)
optimizer_config = dict(grad_clip=None)
# learning policy
lr_config = dict(
policy='step',
warmup='linear',
warmup_iters=500,
warmup_ratio=0.001,
step=[200, 260])
total_epochs = 300
log_config = dict(
interval=50,
hooks=[
dict(type='TextLoggerHook'),
# dict(type='TensorboardLoggerHook')
])

channel_cfg = dict(
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
])

data_cfg = dict(
image_size=512,
base_size=256,
base_sigma=2,
heatmap_size=[128],
num_joints=channel_cfg['dataset_joints'],
dataset_channel=channel_cfg['dataset_channel'],
inference_channel=channel_cfg['inference_channel'],
num_scales=1,
scale_aware_sigma=False,
)

# model settings
model = dict(
type='BottomUp',
pretrained='models/pytorch/imagenet/hrnet_w32-36af842e.pth',
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=(32, 64)),
stage3=dict(
num_modules=4,
num_branches=3,
block='BASIC',
num_blocks=(4, 4, 4),
num_channels=(32, 64, 128)),
stage4=dict(
num_modules=3,
num_branches=4,
block='BASIC',
num_blocks=(4, 4, 4, 4),
num_channels=(32, 64, 128, 256))),
),
keypoint_head=dict(
type='BottomUpSimpleHead',
in_channels=32,
num_joints=17,
num_deconv_layers=0,
tag_per_joint=True,
with_ae_loss=[True],
extra=dict(final_conv_kernel=1, )),
train_cfg=dict(
num_joints=channel_cfg['dataset_joints'],
img_size=data_cfg['image_size']),
test_cfg=dict(
num_joints=channel_cfg['dataset_joints'],
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,
flip_test=True),
loss_pose=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_pipeline = [
dict(type='LoadImageFromFile'),
dict(
type='BottomUpRandomAffine',
rot_factor=30,
scale_factor=[0.75, 1.5],
scale_type='short',
trans_factor=40),
dict(type='BottomUpRandomFlip', flip_prob=0.5),
dict(type='ToTensor'),
dict(
type='NormalizeTensor',
mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225]),
dict(
type='BottomUpGenerateTarget',
sigma=2,
max_num_people=30,
),
dict(
type='Collect',
keys=['img', 'joints', 'targets', 'masks'],
meta_keys=[]),
]

val_pipeline = [
dict(type='LoadImageFromFile'),
dict(type='BottomUpGetImgSize', test_scale_factor=[1]),
dict(
type='BottomUpResizeAlign',
transforms=[
dict(type='ToTensor'),
dict(
type='NormalizeTensor',
mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225]),
]),
dict(
type='Collect',
keys=[
'img',
],
meta_keys=[
'image_file', 'aug_data', 'test_scale_factor', 'base_size',
'center', 'scale', 'flip_index'
]),
]

test_pipeline = val_pipeline

data_root = 'data/coco'
data = dict(
samples_per_gpu=24,
workers_per_gpu=1,
train=dict(
type='BottomUpCocoDataset',
ann_file=f'{data_root}/annotations/person_keypoints_train2017.json',
img_prefix=f'{data_root}/train2017/',
data_cfg=data_cfg,
pipeline=train_pipeline),
val=dict(
type='BottomUpCocoDataset',
ann_file=f'{data_root}/annotations/person_keypoints_val2017.json',
img_prefix=f'{data_root}/val2017/',
data_cfg=data_cfg,
pipeline=val_pipeline),
test=dict(
type='BottomUpCocoDataset',
ann_file=f'{data_root}/annotations/person_keypoints_val2017.json',
img_prefix=f'{data_root}/val2017/',
data_cfg=data_cfg,
pipeline=val_pipeline),
)
2 changes: 2 additions & 0 deletions mmpose/models/detectors/bottom_up.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ def __init__(self,
self.loss = build_loss(loss_pose)
self.init_weights(pretrained=pretrained)

self.fp16_enabled = False

@property
def with_keypoint(self):
"""Check if has keypoint_head."""
Expand Down
2 changes: 2 additions & 0 deletions mmpose/models/detectors/mesh.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ def __init__(self,
self.loss_mesh = builder.build_loss(loss_mesh)
self.init_weights(pretrained=pretrained)

self.fp16_enabled = False

def init_weights(self, pretrained=None):
"""Weight initialization for model."""
self.backbone.init_weights(pretrained)
Expand Down
2 changes: 2 additions & 0 deletions mmpose/models/detectors/top_down.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ def __init__(self,
self.loss = builder.build_loss(loss_pose)
self.init_weights(pretrained=pretrained)

self.fp16_enabled = False

@property
def with_keypoint(self):
"""Check if has keypoint_head."""
Expand Down
103 changes: 103 additions & 0 deletions tests/test_api/test_train.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import tempfile

import pytest
import torch
import torch.nn as nn
from mmcv import Config
from torch.utils.data import Dataset

from mmpose.apis import train_model
from mmpose.datasets.registry import DATASETS


@DATASETS.register_module()
class ExampleDataset(Dataset):

def __init__(self, test_mode=False):
self.test_mode = test_mode

def evaluate(self, results, work_dir=None, logger=None):
eval_results = dict()
eval_results['acc'] = 1
return eval_results

def __getitem__(self, idx):
results = dict(imgs=torch.tensor([1]))
return results

def __len__(self):
return 1


class ExampleModel(nn.Module):

def __init__(self):
super().__init__()
self.test_cfg = None
self.conv1 = nn.Conv2d(3, 8, kernel_size=1)
self.norm1 = nn.BatchNorm1d(2)

def forward(self, imgs, return_loss=False):
self.norm1(torch.rand(3, 2).cuda())
losses = dict()
losses['test_loss'] = torch.tensor([0.5], requires_grad=True)
return losses

def train_step(self, data_batch, optimizer, **kwargs):
imgs = data_batch['imgs']
losses = self.forward(imgs, True)
loss = torch.tensor([0.5], requires_grad=True)
outputs = dict(loss=loss, log_vars=losses, num_samples=3)
return outputs

def val_step(self, data_batch, optimizer, **kwargs):
imgs = data_batch['imgs']
self.forward(imgs, False)
outputs = dict(results=0.5)
return outputs


@pytest.mark.skipif(
not torch.cuda.is_available(), reason='requires CUDA support')
def test_train_model():
model = ExampleModel()
dataset = ExampleDataset()
cfg = dict(
seed=0,
gpus=1,
gpu_ids=[0],
resume_from=None,
load_from=None,
workflow=[('train', 1)],
total_epochs=5,
evaluation=dict(interval=1, key_indicator='acc'),
data=dict(
samples_per_gpu=1,
workers_per_gpu=0,
val=dict(type='ExampleDataset')),
optimizer=dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0001),
optimizer_config=dict(grad_clip=dict(max_norm=40, norm_type=2)),
lr_config=dict(policy='step', step=[40, 80]),
checkpoint_config=dict(interval=1),
log_level='INFO',
log_config=dict(interval=20, hooks=[dict(type='TextLoggerHook')]))

with tempfile.TemporaryDirectory() as tmpdir:
# normal train
cfg['work_dir'] = tmpdir
config = Config(cfg)
train_model(model, dataset, config)

with tempfile.TemporaryDirectory() as tmpdir:
# train with validation
cfg['work_dir'] = tmpdir
config = Config(cfg)
train_model(model, dataset, config, validate=True)

with tempfile.TemporaryDirectory() as tmpdir:
# train with Fp16OptimizerHook
cfg['work_dir'] = tmpdir
cfg['fp16'] = dict()
config = Config(cfg)
model.fp16_enabled = None
train_model(model, dataset, config)

0 comments on commit 2394a40

Please sign in to comment.