栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

centernet代码解读-mutipose

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

centernet代码解读-mutipose

前言:

        centernet可实现目标检测,人体姿态估计,3D检测,本文针对人体姿态估计代码进行解读。文章核心思想,使用热力图表示物体关键点及中心点,及使用中心点到关键点的矢量对检测结果进行双重保障。

1、数据集

        数据集使用coco2017中的person_keypoints_{}2017.json,目标检测使用的是image_info_test-dev2017.json,同一个coco数据集有不同类型的标注文件,根据标注文件中的不同图片id可以在同一个图片文件夹中找到图片。

coco_hp.py

        在init函数中定义一些 a、在datasets/sample/multi_pose.py中会用到的变量及值;b、读取标注文件的路径及名称 (self._eig_val self._eig_vec不知道是何作用)

multi_pose.py  制作真值

        a、根据图片及标注文件路径进行读取  b、在getitem中将标注文件中的真值处理成我们需要的数据存储方式,c、做了一些数据增强操作,如翻转及仿射变换 d、将图片除255使得图片值变为0到1之间的数值 e、归一化,减均值,除方差

    ret = {'input': inp, 'hm': hm, 'reg_mask': reg_mask, 'ind': ind, 'wh': wh
           'hps': kps, 'hps_mask': kps_mask}
 #图片,热力图,int_float回归mask,index,物体宽高,关键点热力图,关键点

inp:图片通过cv2.imread()读取图片,并对图片进行除255,减均值除方差操作

hm : 建立一个和输入图片同样宽高的数组,里面的数值是物体中心点的热力图。热力图是怎么来的呢?1、通过物体宽高算的高斯半径,根据高斯半径,物体中心点,hm及函数draw_gaussian画出属于这个物体的热力图。

reg_mask:#第k个物体的偏差mask=1,初始值为0 reg为物体中心点int到float的偏差

ind:中心点所在的宽高拉成1维后的索引

wh:物体宽高

kps:中心点到关键点间的距离

kps_mask:初始值为0,在有关键点的地方值为1

2、模型

        根据opt.py配置文件中配置的--arch,决定本任务使用哪种网络结构作为backbone,共有“res_18 | res_101 | resdcn_18 | resdcn_101 |''dlav0_34 | dla_34 | hourglass'”七种。

        以resnet101为例,在main.py中,调用了createmodel,在createmodel中又调用了_model_factory及getmodel。在_model_factory中传入opt中写的模型名称,通过_model_factory的getmodel调用真正的构建模型方法,如get_pose_net。在get_pose_net中构建PoseResNet类的实例,构建网络模型,同时在get_pose_net中对模型参数进行初始化。

        初始化:如果模型层是卷积,使用正态分布初始化,如果是偏置,使用常数0初始化;如果是BN层,weight使用常数1初始化,bias使用0初始化……

def init_weights(self, num_layers, pretrained=True):
        if pretrained:
            # print('=> init resnet deconv weights from normal distribution')
            for _, m in self.deconv_layers.named_modules():
                if isinstance(m, nn.ConvTranspose2d):
                    # print('=> init {}.weight as normal(0, 0.001)'.format(name))
                    # print('=> init {}.bias as 0'.format(name))
                    nn.init.normal_(m.weight, std=0.001)
                    if self.deconv_with_bias:
                        nn.init.constant_(m.bias, 0)
                elif isinstance(m, nn.BatchNorm2d):
                    # print('=> init {}.weight as 1'.format(name))
                    # print('=> init {}.bias as 0'.format(name))
                    nn.init.constant_(m.weight, 1)
                    nn.init.constant_(m.bias, 0)
           ……

3、训练

        在for epoch中开始循环训练。使用trainer.train(),MutiposeTrainer继承BaseTrainer,BaseTrainer.train.调用runepoch,在runepoch中主要调用model_with_loss(batch)得到模型的检测结果与loss

        得到模型结果与计算loss

        得到模型结果与loss使用这一句话

output, loss, loss_stats = model_with_loss(batch)

loss调用 MultiPoseTrainer中的__get_losses,在该函数中又调用 MultiPoseLoss类完成整个loss的计算。ModelWithLoss中在BaseTrainer中初始化得到模型及配置参数opt,调用ModelWithLoss类,在该类中对模型进行输入,并将得到的结果送入loss得到loss。

class BaseTrainer(object):
  def __init__(
    self, opt, model, optimizer=None):
    self.opt = opt
    self.optimizer = optimizer
    self.loss_stats, self.loss = self._get_losses(opt)
    self.model_with_loss = ModelWithLoss(model, self.loss)
class ModelWithLoss(torch.nn.Module):
  def __init__(self, model, loss):
    super(ModelWithLoss, self).__init__()
    self.model = model
    self.loss = loss
  
  def forward(self, batch):
    outputs = self.model(batch['input'])
    loss, loss_stats = self.loss(outputs, batch)
    return outputs[-1], loss, loss_stats
class MultiPoseLoss(torch.nn.Module):
  def __init__(self, opt):
    super(MultiPoseLoss, self).__init__()
    self.crit = FocalLoss()
    self.crit_hm_hp = torch.nn.MSELoss() if opt.mse_loss else FocalLoss()
    self.crit_kp = RegWeightedL1Loss() if not opt.dense_hp else 
                   torch.nn.L1Loss(reduction='sum')
    self.crit_reg = RegL1Loss() if opt.reg_loss == 'l1' else 
                    RegLoss() if opt.reg_loss == 'sl1' else None
    self.opt = opt
    
  def forward(self, outputs, batch): 
    …………………………………………
    ………………………………
    loss = opt.hm_weight * hm_loss + opt.wh_weight * wh_loss + 
           opt.off_weight * off_loss + opt.hp_weight * hp_loss + 
           opt.hm_hp_weight * hm_hp_loss + opt.off_weight * hp_offset_loss
    loss_stats = {'loss': loss, 'hm_loss': hm_loss, 'hp_loss': hp_loss, 
                  'hm_hp_loss': hm_hp_loss, 'hp_offset_loss': hp_offset_loss,
                  'wh_loss': wh_loss, 'off_loss': off_loss}
    return loss, loss_stats

class MultiPoseTrainer(BaseTrainer):
  def __init__(self, opt, model, optimizer=None):
    super(MultiPoseTrainer, self).__init__(opt, model, optimizer=optimizer)
  
  def _get_losses(self, opt):
    loss_states = ['loss', 'hm_loss', 'hp_loss', 'hm_hp_loss', 
                   'hp_offset_loss', 'wh_loss', 'off_loss']
    loss = MultiPoseLoss(opt)
    return loss_states, loss

4、decode

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1030198.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号