我在Python脚本中有多次调用的函数(https://github.com/sankhaMukherjee/NNoptExpt/blob/dev/src/lib/NNlib/NNmodel.py):为此,我已大大简化了该函数例。
def errorValW(self, X, y, weights): errVal = None with tf.Session() as sess: sess.run(tf.global_variables_initializer()) nW = len(self.allW) W = weights[:nW] B = weights[nW:] for i in range(len(W)): sess.run(tf.assign( self.allW[i], W[i] )) for i in range(len(B)): sess.run(tf.assign( self.allB[i], B[i] )) errVal = sess.run(self.err, feed_dict = {self.Inp: X, self.Op: y}) return errVal
我从另一个函数多次调用此函数。当我看到程序日志时,似乎此功能花费的时间越来越长。显示了部分日志:
21:37:12,634 - ... .errorValW ... - Finished the function [errorValW] in 1.477610e+00 seconds 21:37:14,116 - ... .errorValW ... - Finished the function [errorValW] in 1.481470e+00 seconds 21:37:15,608 - ... .errorValW ... - Finished the function [errorValW] in 1.490914e+00 seconds 21:37:17,113 - ... .errorValW ... - Finished the function [errorValW] in 1.504651e+00 seconds 21:37:18,557 - ... .errorValW ... - Finished the function [errorValW] in 1.443876e+00 seconds 21:37:20,183 - ... .errorValW ... - Finished the function [errorValW] in 1.625608e+00 seconds 21:37:21,719 - ... .errorValW ... - Finished the function [errorValW] in 1.534915e+00 seconds ... many lines later 22:59:26,524 - ... .errorValW ... - Finished the function [errorValW] in 9.576592e+00 seconds 22:59:35,991 - ... .errorValW ... - Finished the function [errorValW] in 9.466405e+00 seconds 22:59:45,708 - ... .errorValW ... - Finished the function [errorValW] in 9.716456e+00 seconds 22:59:54,991 - ... .errorValW ... - Finished the function [errorValW] in 9.282923e+00 seconds 23:00:04,407 - ... .errorValW ... - Finished the function [errorValW] in 9.415035e+00 seconds
有没有其他人经历过这样的事情?这完全让我感到困惑…
编辑 :这是供参考…
作为参考,该类的初始化器如下所示。我怀疑result变量的图的大小正在逐渐增加。我尝试保存模型时看到了这个问题,tf.train.Saver(tf.trainable_variables())并且此文件的大小一直在增加。我不确定在以任何方式定义模型时是否犯了错误…
result
tf.train.Saver(tf.trainable_variables())
def __init__(self, inpSize, opSize, layers, activations): self.inpSize = inpSize self.Inp = tf.placeholder(dtype=tf.float32, shape=inpSize, name='Inp') self.Op = tf.placeholder(dtype=tf.float32, shape=opSize, name='Op') self.allW = [] self.allB = [] self.result = None prevSize = inpSize[0] for i, l in enumerate(layers): tempW = tf.Variable( 0.1*(np.random.rand(l, prevSize) - 0.5), dtype=tf.float32, name='W_{}'.format(i) ) tempB = tf.Variable( 0, dtype=tf.float32, name='B_{}'.format(i) ) self.allW.append( tempW ) self.allB.append( tempB ) if i == 0: self.result = tf.matmul( tempW, self.Inp ) + tempB else: self.result = tf.matmul( tempW, self.result ) + tempB prevSize = l if activations[i] is not None: self.result = activations[i]( self.result ) self.err = tf.sqrt(tf.reduce_mean((self.Op - self.result)**2)) return
您正在tf.assign会话上下文中进行呼叫。每次执行errorValW函数时,都会在图表上不断添加操作,随着图表的变大,执行速度会变慢。根据经验,在对数据执行模型时,应避免调用Tensorflow操作(因为这通常会在循环内,从而导致图形不断增长)。根据我的个人经验,即使您在执行期间仅添加“几个”操作,也可能导致极慢的运行速度。
tf.assign
errorValW
请注意,这tf.assign是任何其他操作。您应该事先定义一次(在创建模型/构建图形时),然后在启动会话后重复运行相同的op。
我不知道您在代码段中到底要实现什么,但是请考虑以下几点:
... with tf.Session() as sess: sess.run(tf.assign(some_var, a_value))
可以替换为
a_placeholder = tf.placeholder(type_for_a_value, shape_for_a_value) assign_op = tf.assign(some_var, a_placeholder) ... with tf.Session() as sess: sess.run(assign_op, feed_dict={a_placeholder: a_value})
其中a_placeholder应具有相同的D型/形状some_var。我必须承认我还没有测试过此代码段,所以如果有问题,请告诉我,但这应该是正确的。
a_placeholder
some_var