Learning to Estimate 3D Hand Pose from Single RGB Images论文理解

概括:以往很多论文借助深度信息将2D上升到3D,这篇论文则是想要用网络训练代替深度数据(设备成本比较高),提高他的泛性,诠释了只要合成数据集足够大和网络足够强,我就可以不用深度信息。

一、论文结构

这篇论文的思路很清晰,主要分为三个部分:

1、HandSegNet
2、PoseNet
3、the PosePrior network
在这里插入图片描述
第1、2个网络主要是借助 Convolutional Pose Machines 这篇论文的网络进行设置, 通过卷积图层表达纹理信息和空间信息提取出手的位置(只是对第一个网络添加了二值化处理形成了handmask 的中间输出),由于手势比较小,因此对手的位置进行裁剪成为第二个网络的输入,以类似的方式提取关节的位置(score map)。
本论文的核心是第三个网络,该网络以score map 作为输入,进行网络的训练估计正则化框架WC内的三维坐标,并分别估计旋转矩阵R(Wrel),根据公式反求出wc (rel)。
在这里插入图片描述

数据集:

1、Stereo Hand Pose Tracking Benchmark
an evaluation set of 3000 images(S-val) and a training set with 15000 images (S-train)
2、自制数据集:(引擎)
a validation set (R-val) and a training set (R-train)


其中,GT是指通过ground truth 进行分割,Net是指通过网络进行分割,可以发现Net效果比GT差一点,

为什么2D数据可以直接通过网络进行3D的估计?

关键在于方法用的是合成数据集(synthetic dataset (R-val) ),什么是合成数据集呢?Unity大家一定不陌生。通过类似Unity的引擎我们可以模拟各种场景、光线下的人物,根据自己的需要去制作大量的数据集,解决计算机视觉领域缺少数据集的短板。但是,这只是合成数据集的其中一个好处,最大的好处在于由于我们通过引擎模拟人物,那么这个人物的数据我们是有的,即我们可以知道人物三维手势各个关节的相对位置和绝对位置(ground truth),因此我们可以通过这些数据进行训练,从而达到不用深度数据就可以3D训练的效果。

为什么要用一个canonical frame呢?

论文中这样定义:

给定一个颜色图像I∈RN×M3显示一只手,我们想推断它的三维姿态。 我们用一组坐标wi=(xi,yi,zi)来定义手姿,它描述了J关键点在三维空间中的位置,即在我们的情况下,用J=21来∈[1,J]。
在这里插入图片描述
在这里插入图片描述
s将某对关键点之间的距离归一化为单位长度。
在这里插入图片描述
深度数据限制了我们可以脱离整个图像,如果不用深度数据,我们的目光就只需要针对一只手,以手建立对象来研究他的属性。论文中,作者将关节之间的距离归一化,并且手心关节这一个关键点作为标志(land mark),计算其他关节到手心关节点的距离,从而构成一个canonical frame。第三层网络则是不断将canonical frame测量值和ground truth 采用L2 损失对两个估计值WC内的三维坐标和旋转矩阵R(Wrel)进行训练。

为什么要用旋转矩阵将视角统一?

我的理解是如果将视角统一,那么手势的所有可能形式将大大地减少,这样子网络训练准确率将提高。

二、代码框架

在这里插入图片描述

这里是看代码过程的一些小问题和自我消化

论文学习知识补充(之后迁移到其他地方)

ill-posed problems

定义:满足以下条件称为适定问题(well-posed problem):1. a solution exists 解必须存在2. the solution is unique 解必须唯一3. the solution’s behavior changes continuously with the initial conditions. 解能根据初始条件连续变化,不会发生跳变,即解必须稳定

理解:病态问题简单来说就是结果不唯一,比如a*b=5,求解a和b的值就是病态问题。实际应用上很多问题都是病态问题,比如如果一个高温的东西,你不能直接去测量他,你只能间接去测量他,间接可以构成一个模型等式y=f(x,h…),那么我们得到测量值y,求解x,可见由于间接测量我们会受到其他无法测量的因素所影响,反向求x存在多个解,这就叫病态问题以对于病态问题,我们需要做各种先验假设来约束他,让他变成well-posed problem。

正则化与过拟合

#摘录整理
基本定义:对于大量的训练数据,如果我们单纯最小化误差,那么模型的复杂度就会上升(联想一下maltab 的表达式很长很长),这样子会让模型泛化程度很小,所以我们定义规则函数,让他不要过拟合,保持模型较为简单(模型误差小)。
还有另一种理解:规则函数就是拿前人的经验让你少走弯路。
还有第三种理解:规则化符合奥卡姆剃刀原理,从从贝叶斯估计的角度来看,规则化项对应于模型的先验概率。民间还有个说法就是,规则化是结构风险最小化策略的实现,是在经验风险上加一个正则化项(regularizer)或惩罚项(penalty term)。

对于最小化的目标函数:
Obj(Θ)=L(Θ)+Ω(Θ)
常用的损失函数:损失函数链接

训练集上的损失定义为:L=∑ni=1l(yi,y^i)
1.0-1损失函数 (0-1 loss function): L(Y,f(X))={1,Y≠f(X)0,Y=f(X)
2.平方损失函数 (quadratic loss function) : L(Y,f(X))=(Y−f(x))2
3.绝对值损失函数 (absolute loss function) : L(Y,f(x))=|Y−f(X)|
4.对数损失函数 (logarithmic loss function) : L(Y,P(Y∣X))=−logP(Y∣X)
5.Logistic 损失:l(yi,yi)=yiln(1+eyi)+(1−yi)ln(1+eyi)
6.Hinge 损失:hinge(xi)=max(0,1−yi(w⊤xi+b)) ,SVM 损失函数,如果点正确分类且在间隔外,则损失为 0;如果点正确分类且在间隔内,则损失在 (0,1);如果点错误分类,则损失在 (1,+∞)
7.负对数损失 (negative log-likelihood, NLL):Li=−log(pyi),某一类的正确预测的失望程度 (>0),其值越小,说明正确预测的概率越大,表示预测输出与 y 的差距越小
8.交叉熵损失 (cross entropy):首先是 softmax 定义为 pk=efk/∑jefj,其中 fk=Wx+b 表示某一类的预测输出值,则某类的交叉熵损失为该类的输出指数值除所有类之和。基于交叉熵和 softmax 归一化的 loss
L=−1N∑i=1Nyi log ef(xi)∑ef(xi)

condition number

##摘录
如果一个系统是ill-conditioned病态的,我们就会对它的结果产生怀疑。那到底要相信它多少呢?我们得找个标准来衡量,因为有些系统的病没那么重,它的结果还是可以相信的,不能一刀切。终于回来了,上面的condition number就是拿来衡量ill-condition系统的可信度的。condition number衡量的是输入发生微小变化的时候,输出会发生多大的变化。也就是系统对微小变化的敏感度。condition number值小的就是well-conditioned的,大的就是ill-conditioned的。

低秩

#摘录整理
X是低秩矩阵。低秩矩阵每行或每列都可以用其他的行或列线性表出,可见它包含大量的冗余信息。利用这种冗余信息,可以对缺失数据进行恢复,也可以对数据进行特征提取。
L1是L0的凸近似。因为rank()是非凸的,在优化问题里面很难求解,那么就需要寻找它的凸近似来近似它了。对,你没猜错,rank(w)的凸近似就是核范数||W||*。

L0和L1的关系

L1可以使矩阵稀疏化,可以提取特征
L2可以防止过拟合,使得无关的参数更加小。

凸优化问题

为什么不能用MSE作为训练二元分类的损失函数呢?

因为用MSE作为二元分类的损失函数会有梯度消失的问题。在这里插入图片

one hot编码

在这里插入图片描述

摘录

我们继续之前,你可以想一下为什么不直接提供标签编码给模型训练就够了?为什么需要one hot编码?

标签编码的问题是它假定类别值越高,该类别更好。“等等,什么!”

让我解释一下:根据标签编码的类别值,我们的迷你数据集中VW > Acura > Honda。比方说,假设模型内部计算平均值(神经网络中有大量加权平均运算),那么1 + 3 = 4,4 / 2 = 2. 这意味着:VW和Honda平均一下是Acura。毫无疑问,这是一个糟糕的方案。该模型的预测会有大量误差。

我们使用one hot编码器对类别进行“二进制化”操作,然后将其作为模型训练的特征,原因正在于此。

当然,如果我们在设计网络的时候考虑到这点,对标签编码的类别值进行特别处理,那就没问题。不过,在大多数情况下,使用one hot编码是一个更简单直接的方案。

OpenCV双目视觉之立体校正

立体校正就是,把实际中非共面行对准的两幅图像,校正成共面行对准。因为理想情况下计算距离需要两个摄像机需要在同一水平上,但是现实生活中我们有时候多视角的照片不是在同一个水平上拍的,所以需要立体校正将图片变成类似两个摄像机在同一水平上拍摄出来的效果。

双目立体视觉数据集 Stereo dataset

xx对,每一对可以通过立体校正后进行测距。

图像的先验特征

直观的理解就是你对图像的了解,比如手势估计中的手的大小其他已知的信息。
这些先验在很多图像task中可以作为loss中的正则化项,来迫使处理后的图像不会过于拟合。

梯度爆炸和梯度消失

还没细看

@看【25】论文 与深度数据的区别
@@怎样用STB去训练的?

深度学习:
@为什么神经细胞模型后面要有一个激活函数,可以理解为什么要非线性

而人类对外界的认知一般是从局部到全局、从片面到全面,先对局部有感知的认识,再逐步对全体有认知,这是人类的认识模式。类似的,在机器识别图像时也没有必要把整张图像按像素全部都连接到神经网络中,局部范围内的像素之间联系较为紧密,而距离较远的像素则 相关性较弱。因而,每个神经元其实没有必要对全局图像进行感知,只需要对局部进行感知,然后在更高层将局部的信息综合起来就得到了全局的信息。这种模式就是卷积神经网络中降低参数数目的重要神器:局部感受野,节省了内存。

@@@到底训练的是什么?
学习前的卷积核是随机进行初始化的,使用截断的正态分布或者其他的。
不同卷积核经过学习,改变了自身对不同特征的响应程度,如边缘(颜色变化的分界线)和斑块(局部的块状区域)等,其中第2个卷积核对垂直边缘响应,第5个卷积核对水平边缘响应,第9个对倾斜边缘响应,第13个对中心斑块响应。
上面的结果是针对第1层的卷积层得出的。第1层的卷积层中提取了边缘或斑块等“低级”信息,而在堆叠了多层的CNN中,随着层次加深,提取的信息(准确说,是响应强烈的神经元))也越来越抽象。如图6.2所示,第1层的神经元对边缘或斑块有响应,第3层对纹理有响应,第5层对物体部件有响应,最后的全连接层对物体的类别(狗或车)有响应。

多层网络,提供了逐层抽象的通道。如今,图像识别系统正是这么做的:底层识别边缘,而后识别特定形状,再高层识别某种特征……卷积,提供了获得「恒定表征」的手段。
@@隐藏层是什么?
隐藏层的意义就是把输入数据的特征,抽象到另一个维度空间,来展现其更抽象化的特征,这些特征能更好的进行线性划分。
举个例子,MNIST分类。
输出图片经过隐藏层加工, 变成另一种特征代表 (3个神经元输出3个特征), 将这3个特征可视化出来。就有了下面这张图, 我们发现中间的隐藏层对于"1"的图片数据有了清晰的认识,能将"1"的特征区分开来。
在这里插入图片描述

在这里插入图片描述

@@怎么实现参数(权值)共享?
说的再直白一些,就是用一个卷积核不改变其内权系数的情况下卷积处理整张图片(当然CNN中每一层不会只有一个卷积核的,这样说只是为了方便解释而已)。

这是一个最典型的卷积网络,由卷积层、池化层、全连接层组成,通过巧妙的设计,利用卷积、参数共享、池化等操作 提取特征,避免了大量的计算成本,最后再使用全连接神经网络进行 分类识别,这个网络也是最近大量神经网络架构的起点,给这个领域带来了许多灵感。

不同的卷积核

def compute_cost(A2, Y, parameters):
m = Y.shape[1] #样例的数量
#计算交叉熵损失
logprobs = np.multiply(np.log(A2), Y) + np.multiply(np.log(1 - A2), 1 - Y)
cost = -1 / m * np.sum(logprobs)
cost = np.squeeze(cost) #确保损失函数是我们期望的维度
确保损失函数是我们期望的维度为什么呢????
https://www.cnblogs.com/fuhua/p/12799534.html

session 的理解
init 在哪里有用到??
trainning_seg 为什么要添加噪声?
见识
为什么42?
左手和右手
怎么知道他到底是一张图片还是所有图片集

subtract mean 减去平均!数据增强

    image = image / 255.0 - 0.5
    if self.hue_aug:
        # 随机调整图像色调
        image = tf.image.random_hue(image, self.hue_aug_max)
    data_dict['image'] = image
  
如果是image - mean 则是减去平均亮度,这里好像只是为了输入的值不要太大,使得处理比较方便。
这种归一化可以移除图像的平均亮度值 (intensity)。很多情况下我们对图像的照度并不感兴趣,而更多地关注其内容,比如在对象识别任务中,图像的整体明亮程度并不会影响图像中存在的是什么物体。这时对每个数据点移除像素的均值是有意义的。
如果输入层 x 很大,在反向传播时候传递到输入层的梯度就会变得很大。梯度大,学习率就得非常小,否则会越过最优。在这种情况下,学习率的选择需要参考输入层数值大小,而直接将数据归一化操作,能很方便的选择学习率。

with tf.variable_scope(‘bone_rel_transformation’):这句话的意思!
为什么可以实现关节的链接?通过字典!

kinematic_chain_dict = {0: ‘root’,

                    4: 'root',
                    3: 4,
                    2: 3,
                    1: 2,

                    8: 'root',
                    7: 8,
                    6: 7,
                    5: 6,

                    12: 'root',
                    11: 12,
                    10: 11,
                    9: 10,

                    16: 'root',
                    15: 16,
                    14: 15,
                    13: 14,

                    20: 'root',
                    19: 20,
                    18: 19,
                    17: 18}

kinematic_chain_list = [0,
4, 3, 2, 1,
8, 7, 6, 5,
12, 11, 10, 9,
16, 15, 14, 13,
20, 19, 18, 17]

tf.Variable

论文中scoremap是一个关节点21个输出还是一个图片21个关节一个输出?
第二种

vis.shape 是什么?

AUC:
如果要计算accuracy,需要先把概率转化成类别,这就需要手动设置一个阈值,如果对一个样本的预测概率高于这个预测,就把这个样本放进一个类别里面,低于这个阈值,放进另一个类别里面。所以这个阈值很大程度上影响了accuracy的计算。使用AUC或者logloss可以避免把预测概率转换成类别。
AUC是Area under curve的首字母缩写。这个曲线有个名字,叫ROC曲线。
AUC对样本类别是否均衡并不敏感,这也是不均衡样本通常用AUC评价分类器性能的一个原因。

话说真的所有评价只能通过手动调整阈值吗?

@@每一张图片在网络中进行训练,但是下面的输入怎么知道序号的??
data.get()的数据格式

任务一@@
1、把反向传播推导一遍(https://blog.csdn.net/TeFuirnever/article/details/88955455) 怎么去更新他的权重!

对于噪声能够避免过拟合,提出质疑? 需要去看代码中噪声是否放在网络中,达到一个噪声把训练值拉出局部最优,达到一个避免过拟合的效果。
对于这个问题,还有一个疑惑就是如果噪声放在了scoremap,那么加了噪声就会使gt不准确,那么后面的预测不就是不准确了嘛?想问泛性和loss最小是不是一个权衡量?因为我认为如果泛性越强的话,那么loss应该会大,或者这么说,就是对于不同物体的训练值,大家最优提取特征强度是不同的,那么就是要不断的去调节参数,目前的发展到什么地步了呢?
[B, H, W, 3]

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值