我想用最小的条目替换张量中的所有值:
[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
有更好的方法吗?
答案 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倍重复,因为它开始给出了不合理的低值,可能有一些优化,如果输入没有改变,计算不会重新运行。我反而放大了张量。