【问题标题】:Finding local maxima with TensorFlow使用 TensorFlow 寻找局部最大值
【发布时间】:2018-01-09 23:42:43
【问题描述】:

我正在寻找一种专门使用 TensorFlow 获取张量局部最大值索引的方法。

tl;dr

我不是数据科学家。我对很多计算机视觉背后的理论了解不多,但我正在尝试使用 TensorFlow 构建计算机视觉应用程序。我计划保存我的模型并使用 TF Serving 将其作为服务调用,因此我不能依赖 numpy、scipy 等外部库。我想要完成的在算法上与 scipy 的 signal.argrelextrema 相同,但在一种可以用我的模型保存并重新运行的方法。 here 显示了其他算法,但没有在 TensorFlow 中执行。谁能指出我正确的方向?

【问题讨论】:

    标签: python tensorflow computer-vision signal-processing data-science


    【解决方案1】:

    编辑

    我的第一个解决方案很实用,但效率低下。它需要张量的五次迭代(零轨迹、反向、零轨迹、反向、where)。我现在有一个只需要两次迭代的解决方案,而且还足够灵活,可以快速识别局部最小值......

    def get_slope(prev, cur):
        # A: Ascending
        # D: Descending
        # P: PEAK (on previous node)
        # V: VALLEY (on previous node)
        return tf.cond(prev[0] < cur, lambda: (cur, ascending_or_valley(prev, cur)), lambda: (cur, descending_or_peak(prev, cur)))
    
    def ascending_or_valley(prev, cur):
        return tf.cond(tf.logical_or(tf.equal(prev[1], 'A'), tf.equal(prev[1], 'V')), lambda: np.array('A'), lambda: np.array('V'))
    
    def descending_or_peak(prev, cur):
        return tf.cond(tf.logical_or(tf.equal(prev[1], 'A'), tf.equal(prev[1], 'V')), lambda: np.array('P'), lambda: np.array('D'))
    
    def label_local_extrema(tens):
        """Return a vector of chars indicating ascending, descending, peak, or valley slopes"""
        # initializer element values don't matter, just the type.
        initializer = (np.array(0, dtype=np.float32), np.array('A'))
        # First, get the slope for each element
        slope = tf.scan(get_slope, tens, initializer)
        # shift by one, since each slope indicator is the slope
        # of the previous node (necessary to identify peaks and valleys)
        return slope[1][1:]
    
    def find_local_maxima(tens):
        """Return the indices of the local maxima of the first dimension of the tensor"""
        return tf.squeeze(tf.where(tf.equal(label_local_extrema(blur_x_tf), 'P')))
    

    结束编辑

    好的,我设法找到了解决方案,但它并不漂亮。以下函数采用一维张量,并将所有非局部最大值的点减少为零。这仅适用于正数,并且需要对 float32 以外的数据类型进行修改,但它满足我的需求。

    不过,必须有更好的方法来做到这一点。

    def zero_descent(prev, cur):
        """reduces all descent steps to zero"""
        return tf.cond(prev[0] < cur, lambda: (cur, cur), lambda: (cur, 0.0))
    
    def skeletonize_1d(tens):
        """reduces all point other than local maxima to zero"""
        # initializer element values don't matter, just the type.
        initializer = (np.array(0, dtype=np.float32), np.array(0, dtype=np.float32))
        # First, zero out the trailing side
        trail = tf.scan(zero_descent, tens, initializer)
        # Next, let's make the leading side the trailing side
        trail_rev = tf.reverse(trail[1], [0])
        # Now zero out the leading (now trailing) side
        lead = tf.scan(zero_descent, trail_rev, initializer)
        # Finally, undo the reversal for the result
        return tf.reverse(lead[1], [0])
    
    def find_local_maxima(tens):
        return tf.where(skeletonize_1d >0)
    

    【讨论】:

      【解决方案2】:

      我认为您没有提供足够的信息来澄清太多。首先,我不确定你想获得张量的最大元素(tf 中有一个函数)或者你想找到一个函数的局部最大值(不是张量)。在这种情况下,您可以还原函数并找到局部最小值,这将导致您正在寻找的结果。

      【讨论】:

      • 我正在寻找局部最大值,而不是绝对最大值。换句话说,我想知道所有峰的指数。每当张量的斜率从正变为负时,就会出现一个峰值。有关图形示例,请参阅 i.stack.imgur.com/5cRng.png
      【解决方案3】:

      伪:

      input_matrix == max_pool(input_matrix)
      

      说明:

      当输入值与max_pooling取值相同时,表示它们是最大的。

      【讨论】:

        猜你喜欢
        • 2021-09-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多