Softmax矩阵到0/1(OneHot)编码矩阵?

时间:2016-07-29 08:53:54

标签: python tensorflow softmax

假设我有以下张量t作为softmax函数的输出:

t = tf.constant(value=[[0.2,0.8], [0.6, 0.4]])
>> [ 0.2,  0.8]
   [ 0.6,  0.4]

现在我想将此矩阵t转换为类似于OneHot编码矩阵的矩阵:

Y.eval()
>> [   0,    1]
   [   1,    0]

我熟悉c = tf.argmax(t)会给我t每行应该为1的索引。但是从c转到Y似乎相当困难。

我已经尝试过使用ttf.SparseTensor转换为c,然后使用tf.sparse_tensor_to_dense()获取Y。但是这种转换涉及相当多的步骤并且对于任务来说似乎有点过头了 - 我甚至还没有完成它,但我确信它可以工作。

有没有更合适/简单的方法来进行我失踪的转换。

我之所以需要这个,是因为我在Python中有一个自定义的OneHot编码器,我可以在其中提供Ytf.one_hot()不够广泛 - 不允许自定义编码。

相关问题:

2 个答案:

答案 0 :(得分:6)

为什么不将tf.argmax()与tf.one_hot()结合使用。

client.rb:224: syntax error, unexpected tLABEL ... fetch_grid_ids.first, mapping: mapping, csv_options: csv_op... ... ^ client.rb:452: syntax error, unexpected keyword_end, expecting $end

答案 1 :(得分:0)

我比较了TensorFlow 2.1.0中使用输入形状(20、256、256、4)进行转换的五种方法,并比较了Quadro RTX 8000中每次转换的平均时间。

one_hot-argmax(0.802 us):

    y = tf.one_hot(tf.argmax(x, axis=3), x.shape[3])

cast-reduce_max(0.719美元):

y = tf.cast(tf.equal(x, tf.reduce_max(x, axis=3, keepdims=True)),
            tf.float32)

cast-tile-reduce_max(0.862 us)

y = tf.cast(tf.equal(x, tf.tile(tf.reduce_max(x, axis=3, keepdims=True),
                                [1, 1, 1, x.shape[3]])),
            tf.float32)

where-reduce_max(1.850 us):

y = tf.where(tf.equal(x, tf.reduce_max(x, axis=3, keepdims=True)),
             tf.constant(1., shape=x.shape),
             tf.constant(0., shape=x.shape))

where-tile-reduce_max(1.691 us):

y = tf.where(tf.equal(x, tf.tile(tf.reduce_max(x, axis=3, keepdims=True),
                                 [1, 1, 1, x.shape[3]])),
             tf.constant(1., shape=x.shape),
             tf.constant(0., shape=x.shape))

用于生成这些结果的代码如下:

import time
import tensorflow as tf

shape = (20, 256, 256, 4)
N = 1000

def one_hot():
    for i in range(N):
        x = tf.random.normal(shape)
        x = tf.nn.softmax(tf.random.normal(shape), axis=3)
        x = tf.one_hot(tf.argmax(x, axis=3), x.shape[3])
    return None
    
def cast_reduce_max():
    for i in range(N):
        x = tf.random.normal(shape)
        x = tf.nn.softmax(tf.random.normal(shape), axis=3)
        x = tf.cast(tf.equal(x, tf.reduce_max(x, axis=3, keepdims=True)),
                    tf.float32)
    return None

def cast_tile():
    for i in range(N):
        x = tf.random.normal(shape)
        x = tf.nn.softmax(tf.random.normal(shape), axis=3)
        x = tf.cast(tf.equal(x, tf.tile(tf.reduce_max(x, axis=3, keepdims=True), [1, 1, 1, x.shape[3]])),
                    tf.float32)
    return None    
    
def where_reduce_max():
    for i in range(N):
        x = tf.random.normal(shape)
        x = tf.nn.softmax(tf.random.normal(shape), axis=3)
        x = tf.where(tf.equal(x, tf.reduce_max(x, axis=3, keepdims=True)),
                     tf.constant(1., shape=x.shape),
                     tf.constant(0., shape=x.shape))
    return None

def where_tile():
    for i in range(N):
        x = tf.random.normal(shape)
        x = tf.nn.softmax(tf.random.normal(shape), axis=3)
        x = tf.where(tf.equal(x, tf.tile(tf.reduce_max(x, axis=3, keepdims=True), [1, 1, 1, x.shape[3]])),
                     tf.constant(1., shape=x.shape),
                     tf.constant(0., shape=x.shape))
    return None

def blank():
    for i in range(N):
        x = tf.random.normal(shape)
        x = tf.nn.softmax(tf.random.normal(shape), axis=3)
    return None

t0 = time.time()
one_hot()
print(f"one_hot:\t{time.time()-t0}")    

t0 = time.time()
cast_reduce_max()
print(f"cast_reduce_max:\t{time.time()-t0}")

t0 = time.time()
cast_tile()
print(f"cast_tile:\t{time.time()-t0}")

t0 = time.time()
where_reduce_max()
print(f"where_reduce_max:\t{time.time()-t0}")

t0 = time.time()
where_tile()
print(f"where_tile:\t{time.time()-t0}")

t0 = time.time()
blank()
print(f"blank:\t{time.time()-t0}")