代码之家  ›  专栏  ›  技术社区  ›  therealmitchconnors

用张量流求局部极大值

  •  0
  • therealmitchconnors  · 技术社区  · 7 年前

    我正在寻找一种方法,专门使用TensorFlow获得张量局部极大值的指数。

    tl;博士

    我不是数据科学家。我对计算机视觉背后的理论知之甚少,但我正在尝试使用TensorFlow构建一个计算机视觉应用程序。我计划保存我的模型,并使用TF Serving将其作为服务调用,因此我不能依赖于外部库,如numpy、scipy等。我想要实现的算法与scipy的信号相同。argrelextrema,但可以使用我的模型保存并重新运行。已经显示了用于此的其他算法 here ,但没有一个在TensorFlow中执行。有人能给我指出正确的方向吗?

    3 回复  |  直到 7 年前
        1
  •  1
  •   therealmitchconnors    7 年前

    编辑

    我的第一个解决方案很实用,但效率很低。它需要张量的五次迭代(零轨迹,反向,零轨迹,反向,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')))
    

    结束编辑

    好吧,我已经找到了一个解决方案,但它并不漂亮。以下函数采用1D张量,并将所有非局部极大值的点减少到零。这只适用于正数,需要修改除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
  •  1
  •   claverru    5 年前

    伪:

    input_matrix == max_pool(input_matrix)
    

    说明:

    当输入值与max\u pooling获取的值相同时,这意味着它们是最大的。

        3
  •  0
  •   jmlipman    7 年前

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