使用 Earth Mover 的距离作为 Tensorflow 中的损失函数

zhe*_* xu 5 python numpy tensorflow

我想计算两个点云之间的地球移动器距离作为 Tensorflow 中的损失函数。

pointclouds1 = tf.placeholder(tf.float32, shape=(batch_size, num_point, 3))
pointclouds2 = tf.placeholder(tf.float32, shape=(batch_size, num_point, 3))
//'3' means xyz coordinate

def get_loss(pointclouds1, pointclouds2):
    loss = EMD.getEMD(pointclouds1,pointclouds2)
    return loss
Run Code Online (Sandbox Code Playgroud)

不幸的是,我收到错误:

File "F:\pointclouds\utils\EMD.py", line 71, in groundDistance
return np.linalg.norm(x1 - x2, norm)
File "C:\Users\xu\Anaconda3\lib\site-packages\numpy\linalg\linalg.py", line 2257, in norm
raise ValueError("Improper number of dimensions to norm.")
ValueError: Improper number of dimensions to norm.
Run Code Online (Sandbox Code Playgroud)

EMD.py 来自https://github.com/chalmersgit/EMD/blob/master/EMD.py

但我可以使用该文件直接操作numpy数组:

>>python EMD.py
EMD
We got: 160.542759771
C example got 160.54277
Success
Run Code Online (Sandbox Code Playgroud)

我猜这意味着我无法直接操作Tensor,那么我该怎么办?

Dav*_*rks 1

该函数EMD.getEMD实际上在进行计算吗?情况似乎确实如此,如果我的假设是正确的,那么您就误解了张量流。

Tensorflow 开发分两个阶段进行,首先构建操作图,我们通常将所有这些代码分离到一个build_graph()函数中。此时没有数据传入,我们只是定义我们将要执行的操作。

其次,创建一个会话,传入变量,并要求张量流计算某些值,例如损失。实际上,您将使用以下调用在张量流中进行计算

sess.run([ops_to_compute], feed_dict={placeholder_1:input_1, placeholder_2:input_2, ...})
Run Code Online (Sandbox Code Playgroud)

为了使用自定义损失函数,您需要在张量流中定义损失函数。如果你曾经在损失函数的定义中使用过 numpy 函数,你就知道你做错了。您必须使用张量流运算定义损失函数。

这样做通常非常简单。通常,您只需查看当前代码中的 numpy 操作,然后重新创建相同的张量流操作。

  • 对于任何在 tf 中寻找实现的人:https://github.com/master/nima/blob/master/nima.py#L58 (2认同)