示例代码
ii=tf.constant(0,dtype=tf.int32) loop__cond=lambda a: tf.less(a,sentence_length) loop__vars=[ii] def __recurrence(ii): #前面的0到sentence_length-1的下标,存储的就是最原始的词向量,但是我们也要将其转变为Tensor new_column_tensor=tf.expand_dims(sentence_embeddings[:,ii],1) self.nodes_tensor=self.modify_one_column(self.nodes_tensor,new_column_tensor,ii,numlines_tensor,numcolunms_tensor) ii=tf.add(ii,1) return ii ii=tf.while_loop(loop__cond,__recurrence,loop__vars,parallel_iterations=1)
我是将nodes_tensor直接通过self.nodes_tensor的方式使得其成为类的成员变量。然后类调用自身方法的时候,执行上面的循环对nodes_tensor进行操作。
但是,如果此时外层还嵌套有另外一层循环,此时,再使用self.nodes_tensor,比如(tf.reduce_sum(self.nodes_tensor))或者(tf.identity(self.nodes_tensor))就会报错。
会提示类似于如下的信息:
ValueError: Cannot use 'while/Sum' as input to 'while/while_1/concat_3' because they are in different while loops. See info log for more details.
也就是说,self.nodes_tensor是一个对象的引用,其指向的实体是处于一个while loop中。如果在另外一while loop中使用它的话,就会报错。
但是,我们可以将上述代码进行修正,修正后代码如下:
ii=tf.constant(0,dtype=tf.int32) loop__cond=lambda a,b: tf.less(a,sentence_length) loop__vars=[ii,nodes_tensor] def __recurrence(ii,nodes_tensor): #前面的0到sentence_length-1的下标,存储的就是最原始的词向量,但是我们也要将其转变为Tensor new_column_tensor=tf.expand_dims(sentence_embeddings[:,ii],1) nodes_tensor=self.modify_one_column(nodes_tensor,new_column_tensor,ii,numlines_tensor,numcolunms_tensor) ii=tf.add(ii,1) return ii,nodes_tensor ii,nodes_tensor=tf.while_loop(loop__cond,__recurrence,loop__vars,parallel_iterations=1)
此时,通过内层循环返回的nodes_tensor就可以在外层循环中继续使用。
这种错误比较小众。最好的就是用return在__recurrence中返回你想使用的tensor节点。
另一种错误形式
在循环内部产生的tensor,不能直接在循环外部使用。
比如:
self.batch_constructionError=tf.reduce_sum(self.batch_trees_total_cost)[0]
self.batch_trees_total_cost是在循环内部产生的。在循环外部继续加上tf的op操作,会提示如下错误结论:
*** ValueError: Cannot use 'while/concat' as input to 'loss/Sum' because 'while/concat' is in a while loop. See info log for more details.