绕过tf.argmax是不可区分的

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了绕过tf.argmax是不可区分的相关的知识,希望对你有一定的参考价值。

我为我的神经网络编写了一个自定义丢失函数,但它无法计算任何渐变。我认为这是因为我需要最高值的索引,因此使用argmax来获取此索引。

由于argmax不可区分,我可以解决这个问题,但我不知道它是如何可行的。

有人可以帮忙吗?

答案

如果你很酷,近似,

import tensorflow as tf
import numpy as np

sess = tf.Session()
x = tf.placeholder(dtype=tf.float32, shape=(None,))
beta = tf.placeholder(dtype=tf.float32)

# Pseudo-math for the below
# y = sum( i * exp(beta * x[i]) ) / sum( exp(beta * x[i]) )
y = tf.reduce_sum(tf.cumsum(tf.ones_like(x)) * tf.exp(beta * x) / tf.reduce_sum(tf.exp(beta * x))) - 1

print("I can compute the gradient", tf.gradients(y, x))

for run in range(10):
    data = np.random.randn(10)
    print(data.argmax(), sess.run(y, feed_dict={x:data/np.linalg.norm(data), beta:1e2}))

这是使用一种技巧,即在低温环境中计算均值可以得出概率空间的近似最大值。在这种情况下,低温与beta非常大相关。

事实上,当beta接近无穷大时,我的算法将收敛到最大值(假设最大值是唯一的)。不幸的是,在你遇到数字错误并获得NaN之前,测试版不能太大,但有一些技巧可以解决,如果你关心我可以进入。

输出看起来像,

0 2.24459
9 9.0
8 8.0
4 4.0
4 4.0
8 8.0
9 9.0
6 6.0
9 8.99995
1 1.0

所以你可以看到它在某些地方搞砸了,但经常得到正确的答案。根据您的算法,这可能没问题。

另一答案

正如艾达安建议的那样,这只是一个softargmax被β延伸到极限。我们可以使用tf.nn.softmax解决数值问题:

def softargmax(x, beta=1e10):
  x = tf.convert_to_tensor(x)
  x_range = tf.range(x.shape.as_list()[-1], dtype=x.dtype)
  return tf.reduce_sum(tf.nn.softmax(x*beta) * x_range, axis=-1)
另一答案

如果输入的值范围是正的并且您不需要最大值的精确索引但是它的单热表格就足够了,您可以使用sign函数:

import tensorflow as tf
import numpy as np

sess = tf.Session()
x = tf.placeholder(dtype=tf.float32, shape=(None,))

y = tf.sign(tf.reduce_max(x,axis=-1,keepdims=True)-x)
y = (y-1)*(-1)

print("I can compute the gradient", tf.gradients(y, x))

for run in range(10):
    data = np.random.random(10)
    print(data.argmax(), sess.run(y, feed_dict={x:data}))
另一答案

tf.argmax不可区分,因为它返回一个整数索引。 tf.reduce_max和tf.maximum是可区分的

以上是关于绕过tf.argmax是不可区分的的主要内容,如果未能解决你的问题,请参考以下文章

张量流:tf.argmax 和切片

tf.argmax用法

tf.argmax()以及axis解析

TFboy养成记 tf.cast,tf.argmax,tf.reduce_sum

TensorFlow argmax函数

TensorFlow函数 tf.argmax()