Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Tensorflow:计算标签的反向计数_Python_Tensorflow - Fatal编程技术网

Python Tensorflow:计算标签的反向计数

Python Tensorflow:计算标签的反向计数,python,tensorflow,Python,Tensorflow,我有一个张量标签,形状为(b,n),数值为[0,1,2,3,4,5]的整数。 我想创建一个形状(b,n)的张量权重,它在位置(I,j)处携带整数标签[I,j]在标签中出现的次数的倒数 工作示例代码: import tensorflow as tf import numpy as np tf.InteractiveSession() labels=tf.convert_to_tensor(np.array([[1,0,0,1,2,4],[2,2,2,4,2,1]]), dtype=tf.int32

我有一个张量
标签
,形状为(b,n),数值为[0,1,2,3,4,5]的整数。 我想创建一个形状(b,n)的张量
权重
,它在位置(I,j)处携带整数
标签[I,j]
在标签中出现的次数的倒数

工作示例代码:

import tensorflow as tf
import numpy as np
tf.InteractiveSession()
labels=tf.convert_to_tensor(np.array([[1,0,0,1,2,4],[2,2,2,4,2,1]]), dtype=tf.int32)
weights=tf.ones_like(labels, dtype=tf.float32)
bc=tf.bincount(labels, minlength=6, maxlength=6)
for i in range(6):
    cur_count = 1.0/(1e-10+tf.cast(bc[i], tf.float32))
    count_tensor = tf.ones_like(labels, dtype=tf.float32)*cur_count
    weights = tf.where(tf.equal(labels,i), count_tensor, weights)
weights.eval()
# array([[0.3333, 0.5, 0.5, 0.3333, 0.2, 0.5],
#        [0.2, 0.2, 0.2, 0.5, 0.2, 0.3333]], dtype=float32)
例如,标签
1
labels
张量中出现三次,因此在
权重中,值1/3出现在每个位置,其中
1
标签中

现在我不喜欢这段代码的地方是tf.bincount在我的tensorflow版本(1.4.0)的GPU上不工作,我无法更新。 另外,我不确定tensorflow是如何处理for循环的,以及由此产生了多少开销


我想有一个更优雅的办法来解决我的问题。有什么想法吗?

关于循环,你可以调用
tf.gather来代替它:

import tensorflow as tf
import numpy as np

tf.InteractiveSession()
labels = tf.convert_to_tensor(
    np.array([[1, 0, 0, 1, 2, 4], [2, 2, 2, 4, 2, 1]]), dtype=tf.int32)
bc = tf.bincount(labels, minlength=6, maxlength=6)
weights = tf.gather(1.0 / (1e-10 + tf.cast(bc, tf.float32)), labels)
print(weights.eval())
输出:

[[0.33333334 0.5 0.5 0.33333334 0.2 0.5]
[0.2        0.2        0.2        0.5        0.2        0.33333334]]
关于
tf.bincount
仅作为CPU,目前似乎并非如此。事实上,GPU实现似乎已经可用

如果您想要一个替代实现,您可以这样做:

import tensorflow as tf
import numpy as np

tf.InteractiveSession()
labels = tf.convert_to_tensor(
    np.array([[1, 0, 0, 1, 2, 4], [2, 2, 2, 4, 2, 1]]), dtype=tf.int32)
eq = tf.equal(labels[:, :, tf.newaxis], tf.range(6, dtype=labels.dtype))
bc = tf.reduce_sum(tf.cast(eq, tf.float32), axis=[0, 1])
weights = tf.gather(1.0 / (1e-10 + tf.cast(bc, tf.float32)), labels)
print(weights.eval())
# Same output

但是
tf.bincount
可能比这更有效。

由于一些CUDA依赖关系,我目前只能使用tensorflow 1.4.0,因此我无法使用bincount的gpu版本。您是否认为bincount的CPU版本比您建议的另一个使用
tf.equal
的解决方案快?@Merlin1896 Ah在问题中没有正确理解这一点。老实说,我说不出来。除了实际实现的算法外,还取决于许多因素,如实际硬件、张量大小等。混合的GPU/CPU图形将有将数据从一个设备移动到另一个设备的开销,但我的第二个解决方案肯定也需要更多内存。制作一个小基准(具有实际尺寸)来了解它们之间的比较应该不会太难。。。