使用 TensorFlow 寻找局部最大值
Finding local maxima with TensorFlow
我正在寻找一种方法来专门使用 TensorFlow 获取张量的局部最大值的索引。
tl;dr
我不是数据科学家。我不太了解计算机视觉背后的理论,但我正在尝试使用 TensorFlow 构建计算机视觉应用程序。我计划保存我的模型并使用 TF Serving 将其作为服务调用,因此我不能依赖外部库,例如 numpy、scipy 等。我想要完成的算法在算法上与 [=21 相同=] 的 signal.argrelextrema,但可以与我的模型一起保存并重新运行。 here 显示了其他算法,但 none 在 TensorFlow 中执行。谁能指出我正确的方向?
我认为您提供的信息不足以澄清很多问题。首先,我不确定你是想获取 Tensor 的最大元素(tf 中有一个函数用于此)还是想找到函数(不是 Tensor)的局部最大值。在这种情况下,您可以还原函数并找到局部最小值,这将导致您正在寻找的结果。
编辑
我的第一个解决方案是可行的,但效率低下。它需要张量的五次迭代(零轨迹、反向、零轨迹、反向、哪里)。我现在有一个只需要两次迭代的解决方案,而且也足够灵活,可以快速识别局部最小值...
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)
伪:
input_matrix == max_pool(input_matrix)
解释:
当输入值与max_pooling取的值相同时,表示它们是周围最大的。
我正在寻找一种方法来专门使用 TensorFlow 获取张量的局部最大值的索引。
tl;dr
我不是数据科学家。我不太了解计算机视觉背后的理论,但我正在尝试使用 TensorFlow 构建计算机视觉应用程序。我计划保存我的模型并使用 TF Serving 将其作为服务调用,因此我不能依赖外部库,例如 numpy、scipy 等。我想要完成的算法在算法上与 [=21 相同=] 的 signal.argrelextrema,但可以与我的模型一起保存并重新运行。 here 显示了其他算法,但 none 在 TensorFlow 中执行。谁能指出我正确的方向?
我认为您提供的信息不足以澄清很多问题。首先,我不确定你是想获取 Tensor 的最大元素(tf 中有一个函数用于此)还是想找到函数(不是 Tensor)的局部最大值。在这种情况下,您可以还原函数并找到局部最小值,这将导致您正在寻找的结果。
编辑
我的第一个解决方案是可行的,但效率低下。它需要张量的五次迭代(零轨迹、反向、零轨迹、反向、哪里)。我现在有一个只需要两次迭代的解决方案,而且也足够灵活,可以快速识别局部最小值...
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)
伪:
input_matrix == max_pool(input_matrix)
解释:
当输入值与max_pooling取的值相同时,表示它们是周围最大的。