aliyun/Self-Evolving-Keypoint-Demo

关于det_loss的设计

Opened this issue · 13 comments

foxkw commented

你好,感谢你的工作。想请教2个问题:
1)检测器loss为什么选择分类来做,选择focal loss,而不是直接最小化原图和变换图的L2loss呢
2)KLD的loss使用:请问是直接把对应点的概率送入 F.kl_div(torch.log(y_pred), y_true, reduction='none') 其中吗? 我尝试这样做,但发现它的值只有10^-4级别(是否因为点太多了,然后对这些点的概率再使用softmax,导致值很小呢),请问您在KLD loss设计时,有什么经验可以分享吗,谢谢

yoffie commented
  1. 置信度图里面有很多低confidence 的非零点,l2 loss会受到这些点的影响,并且local feature是稀疏的,所以选择了focal loss。我们也实现了l2_loss,你可以对比下实验结果。
  2. 我push我们的大部分训练代码,你可以参考sekd_em/update_detector.py 里的128行。
foxkw commented
  1. 置信度图里面有很多低confidence 的非零点,l2 loss会受到这些点的影响,并且local feature是稀疏的,所以选择了focal loss。我们也实现了l2_loss,你可以对比下实验结果。

    1. 我push我们的大部分训练代码,你可以参考sekd_em/update_detector.py 里的128行。

多谢。我还想请教一个问题,我采用superpoint作为我的框架,当我只对一张图像做单应变换(旋转,缩放等),我发现当loss收敛到0.1时,原图可以很好收敛,预测点和gt点完全重合,但在warped_img上,预测点和gt点存在像素差,不完全重合,请问这合理吗,我看您的论文中也使用了这一方法。
image

yoffie commented

我没有理解你具体是怎么做的?训练的时候只使用了一张图?是不是过拟合了

foxkw commented

我没有理解你具体是怎么做的?训练的时候只使用了一张图?是不是过拟合了

我会先用一个检测特征点的模型在图像上检测到特征点当作gt,然后对这幅图像和gt都作单应变换;单应变换后的图像和gt计算对应的交叉熵loss。 一张图像都不能很好收敛,这是过拟合吗?

yoffie commented

我复述一下你的训练过程:1. 你有一个已有的local feature方法(比如SIFT、ORB、DISK之类的),和一张图像;2. 使用已有方法在图像上(仅仅在原图上)检测了特征点,并将其作为gt;3. 使用原图,以及2中得到的gt,训练detector,并使训练收敛;4. 将原图仿射变换,并在变换后的图上进行检测,检测结果和gt比较,发现位置有偏差。

如果是这样的话,一个原因是训练数据太少,detector会overfit到原图上,在仿射变换图上推广能力不好;令一个原因是,这个过程中并没有设计detector 对仿射变换的鲁棒性,所以在仿射变换下,检测结果的一致性也不好。针对这个,SEKD借鉴了superpoint里的affine adaption方法,你可以具体看一下。SEKD和superpoint不同的地方是,superpoint是对预设角点,多次变换后融合得到最终结果,SEKD是通过计算reliability,自动发现local feature,多次变换后融合得到最终结果。

foxkw commented

我复述一下你的训练过程:1. 你有一个已有的local feature方法(比如SIFT、ORB、DISK之类的),和一张图像;2. 使用已有方法在图像上(仅仅在原图上)检测了特征点,并将其作为gt;3. 使用原图,以及2中得到的gt,训练detector,并使训练收敛;4. 将原图仿射变换,并在变换后的图上进行检测,检测结果和gt比较,发现位置有偏差。

如果是这样的话,一个原因是训练数据太少,detector会overfit到原图上,在仿射变换图上推广能力不好;令一个原因是,这个过程中并没有设计detector 对仿射变换的鲁棒性,所以在仿射变换下,检测结果的一致性也不好。针对这个,SEKD借鉴了superpoint里的affine adaption方法,你可以具体看一下。SEKD和superpoint不同的地方是,superpoint是对预设角点,多次变换后融合得到最终结果,SEKD是通过计算reliability,自动发现local feature,多次变换后融合得到最终结果。

我在原图得到的检测点gt,也会做仿射变换,这样我的仿射变换图像也有了对应的gt, 然后原图和仿射变换图像分别与对应的gt训练,但都是同一个交叉熵Loss。现在的现象是仿射变换固定一个旋转角度训练,可以收敛,如果仿射变换是旋转+缩放+平移等,就不能很好的收敛

yoffie commented

你选的做gt的方法定位精度高不高,是不是sub-pixel的,如果精度不高,缩放之后,在变换后的图像上gt可能就差的比较多。还有,从你可视化的图上看,你的图本身质量不太高,和这个可能也有关系。你把变换图的gt可视化一下看看,再多试试不同的图像和设置,看看能不能找出来准确的原因。

foxkw commented

你选的做gt的方法定位精度高不高,是不是sub-pixel的,如果精度不高,缩放之后,在变换后的图像上gt可能就差的比较多。还有,从你可视化的图上看,你的图本身质量不太高,和这个可能也有关系。你把变换图的gt可视化一下看看,再多试试不同的图像和设置,看看能不能找出来准确的原因。

好的,谢谢您这么晚回复我;我会尝试您的建议。 我的gt是像素级别的,的确存在变换后的像素损失,但是我也想过用亚像素,gt如果是亚像素级,变换图还能做交叉熵分类损失吗, 它貌似是像素级别的概率计算呀

yoffie commented

在变换图上可以对 gt位置做 round() ,就可以用分类loss。得到sub-pixel的检测结果,可以参考 nets/sekd.py 的代码

foxkw commented

在变换图上可以对 gt位置做 round() ,就可以用分类loss。得到sub-pixel的检测结果,可以参考 nets/sekd.py 的代码

好的,谢谢。我还想请教一个问题,我借鉴了您的思路,在代码中使用了KL loss,但是我发现KL loss有些奇怪,初始的时候很快下降(这应该可以理解为初始时期预测为背景的概率更大,,所以差异较小),但随后loss迅速又上升了, 并且我的KL loss都是10^-5级别,这似乎很难对梯度反传产生影响,请问您在设计KL loss的时候遇到过这种情况吗,谢谢

image

yoffie commented

我看了一下之前的实验,kl loss 确实很小,在 10^-5 级别,不过我们记录每个batch iteration 的loss,所以不确定是不是kl loss有反复。从结果看,你的 total loss是降低趋势的,这样的话,kl loss和其他loss应该存在一定的冲突的。你可以试试分别用单个loss,和loss的组合,观察结果,看看各个loss的作用和相互影响。

foxkw commented

我看了一下之前的实验,kl loss 确实很小,在 10^-5 级别,不过我们记录每个batch iteration 的loss,所以不确定是不是kl loss有反复。从结果看,你的 total loss是降低趋势的,这样的话,kl loss和其他loss应该存在一定的冲突的。你可以试试分别用单个loss,和loss的组合,观察结果,看看各个loss的作用和相互影响。

图像做完变换后,会有一些非图像像素的区域,在superpoint中计算分类loss时,用了mask的方法,防止交界的边缘区域预测出特征点。我看您用focal loss时似乎没有用mask,是直接整张变换图都去做分类loss,在您看来,对于模型整体的学习是不存在影响的是吗

image

yoffie commented

你看一下通过descriptor计算keypoint的代码,在计算keypoint的gt的时候,我们也使用了mask避免使用这些边缘处的点作为gt的