Tensorflow:将张量中的所有值替换为最小值或最大值

时间:2018-05-23 12:41:09

标签: tensorflow

我想用最小的条目替换张量中的所有值:

[1,-2,3,4,-4] -> [-4,-4,-4,-4,-4]

现在我正在做

x = tf.random_normal([1,5], mean=0.0, stddev=1.0, dtype=tf.float32)
y = tf.reduce_min(x) + 0.0*x

有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

嗯,如果您使用tf.fill()进行显式初始化而不是通过添加进行隐式广播,那么它在CPU和GPU上的效率都会更高。见下面的基准。此代码(已测试):

import tensorflow as tf

x = tf.random_normal([1,5], mean=0.0, stddev=1.0, dtype=tf.float32)
y = tf.fill( tf.shape( x ), tf.reduce_min(x) )

with tf.Session() as sess:
    res = sess.run( [ x, y ] )
    for v in res:
        print( v )

将输出

  

[[ - 1.9890205 -0.20791222 0.6901897 0.5605381 0.93578804]]
  [[-1.9890205 -1.9890205 -1.9890205 -1.9890205 -1.9890205]]

根据需要(数字是随机的,但第二行具有相同形状重复的第一行的最小值。)

基准

在我的本地计算机上,tf.fill()版本花费了0.305秒而GPU上的原始版本为1.479,而CPU上的0.191与1.923相比,张量为[ 10000, 10000 ]

tf.fill()版本占用了0.082秒,而原始版本在CPU上为https://colab.research.google.com时为0.610秒,在GPU上分别为0.287和0.874秒。

以下是我用于基准测试的代码:

import tensorflow as tf
import time

with tf.device( "/gpu:0"):
    # x and m are in variables and calculated first so that the timing only measures
    # the fill vs. broadcast operation
    x = tf.Variable( tf.random_normal( [ 10000, 10000 ], mean=0.0, stddev=1.0, dtype=tf.float32 ) )
    m = tf.Variable( 0. )
    m_calc_op = tf.assign( m, tf.reduce_min( x ) )
    y1 = tf.fill( tf.shape( x ), m )
    y2 = m + 0.0 * x

with tf.Session() as sess:
    sess.run( tf.global_variables_initializer() )
    sess.run( m_calc_op ) 
    #res = sess.run( [ y1, y2 ] ) # run it once

    start = time.clock()
    #for i in xrange( 10 ):
    res = sess.run( [ m, y1 ] )
    end = time.clock()
    print ( end - start, "m=", res[ 0 ] )

    start = time.clock()
    #for i in xrange( 10 ):
    res = sess.run( [ m, y2 ] )
    end = time.clock()
    print ( end - start, "m=", res[ 0 ] )

请注意,我注释了10倍重复,因为它开始给出了不合理的低值,可能有一些优化,如果输入没有改变,计算不会重新运行。我反而放大了张量。