• Integral Human Pose Regression论文阅读



    Integral Human Pose Regression

    一. 论文简介

    原论文地址

    中文一篇博文

    这篇论文比较通俗易懂,这里随便说一下

    • non-differentiable

      • 网络输出heatmap,我们得通过argmax获取坐标,这里是无法进行反向计算的。
    • quantization error

      • heatmap得缩小计算,使用hourglass得到的heatmap是原图的1/4或1/8,那么我们的误差范围也就是四个或八个像素了。
    • resolution

      • 直接回归坐标位置:原始论文做法,效果很差。
      • 替换argmax,使得整个步骤可以积分。
    • example

    使用本文的方法,去除one-hot编码。假设种类编码:(x=[0,1,2,3]) 分类网络输出(已经求取softmax):(out_a = [0.1,0.2,0.3,0.4]),正常做法直接argmax求取(index=3) 即可。现在我们使用期望去求:(out_b = x*out) ,得到的结果(out_c=[0,0.2,0.6,1.2]),求和得到最终结果:(2)

    发现一个问题,两种求解方法得到的结果不一致?

    1. 因为Loss求解方法不同,传统使用(out_a)直接计算,后者使用(out_c)计算。
    2. 期望和最大概率有所不同,期望会权衡其它值的存在,最大概率只考虑当下。

    二. 代码计算

    2.1 原始代码

    代码来源

    import torch.nn.functional as F
    import torch
    from torch.autograd import Variable
    import torch.nn as nn
    import numpy as np
    import os
    
    
    def makeGaussian(height, width, sigma=3, center=None):
        """ Make a square gaussian kernel.
        size is the length of a side of the square
        sigma is full-width-half-maximum, which
        can be thought of as an effective radius.
        """
        x = np.arange(0, width, 1, float)
        y = np.arange(0, height, 1, float)[:, np.newaxis]
        if center is None:
            x0 = width // 2
            y0 = height // 2
        else:
            x0 = center[0]
            y0 = center[1]
        return 10 * np.exp(-4 * np.log(2) * ((x - x0) ** 2 + (y - y0) ** 2) / sigma ** 2)
    def generate_hm(height, width, joints, maxlenght):
        """ Generate a full Heap Map for every joints in an array
        Args:
            height          : Wanted Height for the Heat Map
            width           : Wanted Width for the Heat Map
            joints          : Array of Joints 15*2
            maxlenght       : Lenght of the Bounding Box
        """
        num_joints = joints.shape[0]
        hm = np.zeros((num_joints, height, width), dtype=np.float32)
        for i in range(num_joints):
            s = int(np.sqrt(maxlenght) * maxlenght * 10 / 4096) + 3
            hm[i, :, :] = makeGaussian(height, width, sigma=s, center=(joints[i, 0], joints[i, 1]))
        return hm
    def generate_3d_integral_preds_tensor_init(heatmaps, num_joints, x_dim, y_dim):
        assert isinstance(heatmaps, torch.Tensor)
        '''
        heatmap: [B, numJoint, H, W]
        '''
        heatmap = heatmaps.reshape((heatmaps.shape[0], 3, -1))
        heatmap = F.softmax(heatmap, 2)
    
        heatmaps = heatmaps.reshape((heatmaps.shape[0], num_joints, y_dim, x_dim))
    
        accu_x = heatmaps.sum(dim=2)  # [1, 2, x_dim]
    
        accu_y = heatmaps.sum(dim=3)
    
        accu_x = accu_x * torch.arange(x_dim).type(torch.cuda.FloatTensor)
        accu_y = accu_y * torch.arange(y_dim).type(torch.cuda.FloatTensor)
    
        accu_x = accu_x.sum(dim=2, keepdim=True)
        accu_y = accu_y.sum(dim=2, keepdim=True)
        return accu_x, accu_y
      
    if __name__ == '__main__':
        x = torch.from_numpy(np.array([[1,2,3,4],[1,2,3,4]])).type(torch.float32)
    
        GT_xy = np.array([[10, 10], [3, 8], [16, 18]])
        heatmap = generate_hm(64, 32, GT_xy, 64)  # [numJoint, 64, 64]
    
        heatmap = torch.unsqueeze(torch.from_numpy(heatmap), 0).cuda()  # [1, numJoint, 64, 64]
    
        x, y = generate_3d_integral_preds_tensor_init(heatmaps=heatmap, num_joints=3, x_dim=32, y_dim=64)  #
    
    

    2.2 修改代码

    先使用softmax和后使用softmax计算的结果不同,且笔者修改的代码和输入值一样,不知道在训练中有多少差别

    import torch.nn.functional as F
    import torch
    from torch.autograd import Variable
    import torch.nn as nn
    import numpy as np
    import os
    
    
    def makeGaussian(height, width, sigma=3, center=None):
        """ Make a square gaussian kernel.
        size is the length of a side of the square
        sigma is full-width-half-maximum, which
        can be thought of as an effective radius.
        """
        x = np.arange(0, width, 1, float)
        y = np.arange(0, height, 1, float)[:, np.newaxis]
        if center is None:
            x0 = width // 2
            y0 = height // 2
        else:
            x0 = center[0]
            y0 = center[1]
        return 10 * np.exp(-4 * np.log(2) * ((x - x0) ** 2 + (y - y0) ** 2) / sigma ** 2)
    
    
    def generate_hm(height, width, joints, maxlenght):
        """ Generate a full Heap Map for every joints in an array
        Args:
            height          : Wanted Height for the Heat Map
            width           : Wanted Width for the Heat Map
            joints          : Array of Joints 15*2
            maxlenght       : Lenght of the Bounding Box
        """
        num_joints = joints.shape[0]
        hm = np.zeros((num_joints, height, width), dtype=np.float32)
        for i in range(num_joints):
            s = int(np.sqrt(maxlenght) * maxlenght * 10 / 4096) + 3
            hm[i, :, :] = makeGaussian(height, width, sigma=s, center=(joints[i, 0], joints[i, 1]))
        return hm
    
    def generate_3d_integral_preds_tensor_modify(heatmaps):
        assert isinstance(heatmaps, torch.Tensor)
        '''
        heatmap: [B, numJoint, H, W]
        '''
        accu_x = heatmaps.sum(dim=2)  # [1, 2, x_dim]
        accu_y = heatmaps.sum(dim=3)
    
        accu_x = F.softmax(accu_x, 2)
        accu_y = F.softmax(accu_y, 2)
    
        accu_x = accu_x * torch.arange(heatmaps.shape[-1]).type(torch.cuda.FloatTensor)
        accu_y = accu_y * torch.arange(heatmaps.shape[-2]).type(torch.cuda.FloatTensor)
    
        accu_x = accu_x.sum(dim=2, keepdim=True)
        accu_y = accu_y.sum(dim=2, keepdim=True)
        return accu_x, accu_y
    
    if __name__ == '__main__':
        x = torch.from_numpy(np.array([[1,2,3,4],[1,2,3,4]])).type(torch.float32)
    
        GT_xy = np.array([[10, 10], [3, 8], [16, 18]])
        heatmap = generate_hm(64, 32, GT_xy, 64)  # [numJoint, 64, 64]
    
        heatmap = torch.unsqueeze(torch.from_numpy(heatmap), 0).cuda()  # [1, numJoint, 64, 64]
    
        x, y = generate_3d_integral_preds_tensor_modify(heatmaps=heatmap)  #
    
        print("////")
    
    

    三. 参考文献

    • 文章已给出
  • 相关阅读:
    firewalld
    autossh反向隧道
    SSH端口转发
    yii2.0 控制器加载不同的user组件
    php笔记整理
    mysql绿色版安装问题解决(ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061))
    mysql笔记整理
    深入PHP EOF(heredoc)用法详解
    php中const与define的使用区别 详解
    phpstorm8 设置及license key
  • 原文地址:https://www.cnblogs.com/wjy-lulu/p/12891403.html
Copyright © 2020-2023  润新知