- 2020-2-23更新
网友芒果和小猫通过评论分享了解释行列式的对角线元素+1的原因,参见该网址,我们将原文引用如下,并简单翻译解释:
原文如下:
Note that the determinant of a zero vector field is also zero, whereas the Jacobian determinant of the corresponding identity warp transformation is 1.0. In order to compute the effective deformation Jacobian determinant 1.0 must be added to the diagonal elements of Jacobian prior to taking the derivative. i.e. det([ (1.0+dx/dx) dx/dy dx/dz ; dy/dx (1.0+dy/dy) dy/dz; dz/dx dz/dy (1.0+dz/dz) ])
解释如下:
值得注意的是,零位移矢量场的行列式的值为0,然而相应的恒等变换(即对原图进行变形后的图像,仍与原图相同)的雅克比行列式的值为1。因此,为了计算出有效的变形场的雅克比行列式,在求导之前要再雅克比式的对角线元素上加1,使得数学计算的结果与实际相符。
- 2019-5-14更新
最近两天我研究了一下雅可比行列式的问题,重新检查了别人的公开代码与可视化,发现了一些问题,现总结如下:
- 检查雅可比行列式的计算原理与其代码实现,我发现之前的代码存在问题,现在进行更新纠正;
- 关于其代码实现,我还有一个疑问没有解答,这可能与其数学原理有关,需要进一步的验证;
- 对雅可比行列式的计算结果进行可视化,本文提供了代码参考,并进行了解释,但还没解决。
1.正确的代码实现
用代码来计算雅可比行列式,实际上就是将这个三阶行列式进行展开。参照行列式展开的结果,我检查github上的公开代码(参见更新前的代码),发现其中存在一个错误和两个问题。首先小错误是在D2的计算中,D_x[...,0]实际上应该为D_z[...,0];其中一个问题是在计算最终结果时,它取了绝对值(np.abs()),也就是说,它完全忽视了负值的情况,这就减少了其可视化的工作量,但也损失了最重要的信息。另外一个问题参见第二小节(2.代码实现的一个疑问)。
如下是我修改后的代码,以及注释:
def Get_Jac(displacement):
'''
the expected input: displacement of shape(batch, H, W, D, channel),
obtained in TensorFlow.
'''
D_y = (displacement[:,1:,:-1,:-1,:] -