tensorflow mean_iou - 如何获得一致的结果

时间:2018-01-26 03:19:25

标签: python tensorflow keras image-segmentation

我被张量流量度量mean_iou()所困扰。我尝试使用导致相同数据的结果不一致,我无法在任何地方找到有用的示例。

这篇博文讲述了这个问题......但我无法解决我在这里提出的问题。 http://ronny.rest/blog/post_2017_09_11_tf_metrics/

最终目标是让validation_func(y_true, y_pred)以arg'metric'的形式传递给Keras Model.compile()方法。

结束目标

类似......

def my_iou(y_true, y_pred):
  num_classes = 2
  score, update_op = tf.metrics.mean_iou(tf.argmax(y_true, axis=3), tf.argmax(y_pred, axis=3), num_classes)
  K.get_session().run(tf.local_variables_initializer())
  # K.get_session().run(tf.global_variables_initializer())
  with tf.control_dependencies([update_op]):
    final_score = tf.identity(score)
  return final_score

虚假数据

  • 尺寸为:(批次,高度,宽度,num_classes)
  • 第1类 - 前景对象;我想要分割的内容
  • 0级 - 背景

我真正关心的是第1课的IOU。在这种情况下应该是7/9 = 0.778。我希望这会吐出来的是每个班级的平均值...

  • iou 0:0/2 = 0
  • iou class 1:7/9 = 0.778
  • 整体:平均(iou_0,iou_1)= 0.3889

数据

from keras import backend as K
import tensorflow as tf
import numpy as np

y_true = np.zeros(18, dtype='int32').reshape((1,3,3,2))
y_true[:,:,:,1] = 1
y_true[:,0,0,1] = 0
y_true[:,0,0,0] = 1

y_pred = np.zeros(18, dtype='float32').reshape((1,3,3,2))
y_pred[:,:,:,1] = 1.0
y_pred[:,-1,-1,1] = 0.1
y_pred[:,-1,-1,0] = 0.9

如果我使用以下内容进行模拟,我大部分时间都会得到预期的0.3889 ...但我偶尔也会得到3.5或0.0,而我无法找出原因?

results = []
for i in range(20):
  with tf.Session() as sess:
    y_t = tf.convert_to_tensor(y_true)
    y_p = tf.convert_to_tensor(y_pred)
    results.append(my_iou(y_t, y_p).eval())

最近的一次运行

[0.3888889,
 0.3888889,
 0.3888889,
 0.3888889,
 3.5,
 0.3888889,
 0.3888889,
 0.3888889,
 0.3888889,
 0.3888889,
 0.3888889,
 0.3888889,
 0.3888889,
 3.5,
 0.3888889,
 0.3888889,
 0.3888889,
 3.5,
 0.3888889,
 0.3888889]

任何帮助?

编辑

现在我正在使用专门用于二进制分类的硬编码,但我不喜欢它。不可推广,可能太简单,也许是完全错误的。 (同样值得注意的是......在这段代码中,0级是前景,不像我的示例设置,其中类1是前景)

def my_iou_binary(self, y_true, y_pred):
  yt0 = y_true[:,:,:,0]
  yp0 = K.cast(y_pred[:,:,:,0] > 0.5, 'float32')

  inter = tf.count_nonzero(tf.logical_and(tf.equal(yt0, 1), tf.equal(yp0, 1)))
  union = tf.count_nonzero(tf.add(yt0, yp0))
  iou = tf.where(tf.equal(union, 0), 1., tf.cast(inter/union, 'float32'))

  return iou

0 个答案:

没有答案