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.