基于tensorflow for循环 while循环案例
我就废话不多说了,大家还是直接看代码吧~
importtensorflowastf n1=tf.constant(2) n2=tf.constant(3) n3=tf.constant(4) defcond1(i,a,b): returniprint结果:
2 1 1 - 3 1 2 - 4 2 3可见body函数返回的三个变量又传给了body
补充知识:tensorflow在tf.while_loop循环(非一般循环)中使用操纵变量该怎么做
代码(操纵全局变量)
xiaojie=1 i=tf.constant(0,dtype=tf.int32) batch_len=tf.constant(10,dtype=tf.int32) loop_cond=lambdaa,b:tf.less(a,batch_len) #yy=tf.Print(batch_len,[batch_len],"batch_len:") yy=tf.constant(0) loop_vars=[i,yy] def_recurrence(i,yy): c=tf.constant(2,dtype=tf.int32) x=tf.multiply(i,c) globalxiaojie xiaojie=xiaojie+1 print_info=tf.Print(x,[x],"x:") yy=yy+print_info i=tf.add(i,1) #print(xiaojie) returni,yy i,yy=tf.while_loop(loop_cond,_recurrence,loop_vars,parallel_iterations=1)#可以批处理 sess=tf.Session() print(sess.run(i)) print(xiaojie)输出的是10和2。
也就是xiaojie只被修改了一次。
这个时候,在_recurrence循环体中添加语句
print(xiaojie)
会输出2。而且只输出一次。具体为什么,最后总结的时候再解释。
代码(操纵类成员变量)classRNN_Model():
def__init__(self): self.xiaojie=1 deftest_RNN(self): i=tf.constant(0,dtype=tf.int32) batch_len=tf.constant(10,dtype=tf.int32) loop_cond=lambdaa,b:tf.less(a,batch_len) #yy=tf.Print(batch_len,[batch_len],"batch_len:") yy=tf.constant(0) loop_vars=[i,yy] def_recurrence(i,yy): c=tf.constant(2,dtype=tf.int32) x=tf.multiply(i,c) self.xiaojie=self.xiaojie+1 print_info=tf.Print(x,[x],"x:") yy=yy+print_info i=tf.add(i,1)print("_recurrence:",self.xiaojie) returni,yy i,yy=tf.while_loop(loop_cond,_recurrence,loop_vars,parallel_iterations=1)#可以批处理 sess=tf.Session() sess.run(yy) print(self.xiaojie) if__name__=="__main__": model=RNN_Model()#构建树,并且构建词典 model.test_RNN()输出是:
_recurrence:2 10 2tf.while_loop操纵全局变量和类成员变量总结
为什么_recurrence中定义的print操作只执行一次呢,这是因为_recurrence中的print相当于一种对代码的定义,直接在定义的过程中就执行了。所以,可以看到输出是在sess.run之前的。但是,定义的其它操作就是数据流图中的操作,需要在sess.run中执行。
就必须在sess.run中执行。但是,全局变量xiaojie也好,还是类成员变量xiaojie也好。其都不是图中的内容。因此,tf.while_loop执行的是tensorflow计算图中的循环,对于不是在计算图中的,就不会参与循环。注意:而且必须是与loop_vars中指定的变量存在数据依赖关系的tensor才可以!此外,即使是依赖关系,也必须是_recurrence循环体中return出的变量,才会真正的变化。比如,见下面的self.L。总之,想操纵变量,就要传入loop_vars!
如果对一个变量没有修改,就可以直接在循环中以操纵类成员变量或者全局变量的方式只读。
self.L与loop_vars中变量有依赖关系,但是并没有真正被修改。
#IIII通过计算将非叶子节点的词向量也放入nodes_tensor中。 iiii=tf.constant(0,dtype=tf.int32) loop____cond=lambdaa,b,c,d,e:tf.less(a,self.sentence_length-1)#iiii的范围是0到sl-2。注意,不包括sl-1。这是因为只需要计算sentence_length-1次,就能构建出一颗树 loop____vars=[iiii,columnLinesOfL,node_tensors_cost_tensor,nodes_tensor,tfPrint] def____recurrence(iiii,columnLinesOfL,node_tensors_cost_tensor,nodes_tensor,tfPrint):#循环的目的是实现Greedy算法 ### #Greedy的主要目标就是确立树结构。 ### c1=self.L[:,0:columnLinesOfL-1]#这段代码是从RvNN的matlab的源码中复制过来的,但是Matlab的下标是从1开始,并且Matlab中1:2就是1和2,而python中1:2表示的是1,不包括2,所以,有很大的不同。 c2=self.L[:,1:columnLinesOfL] c=tf.concat([c1,c2],axis=0) p=tf.tanh(tf.matmul(self.W1,c)+tf.tile(self.b1,[1,columnLinesOfL-1])) p_normalization=self.normalization(p) y=tf.tanh(tf.matmul(self.U,p_normalization)+tf.tile(self.bs,[1,columnLinesOfL-1]))#根据Matlab中的源码来的,即重构后,也有一个激活的过程。 #将Y矩阵拆分成上下部分之后,再分别进行标准化。 columnlines_y=columnLinesOfL-1 (y1,y2)=self.split_by_row(y,columnlines_y) y1_normalization=self.normalization(y1) y2_normalization=self.normalization(y2) #论文中提出一种计算重构误差时要考虑的权重信息。具体见论文,这里暂时不实现。 #这个权重是可以修改的。 alpha_cat=1 bcat=1 #计算重构误差矩阵 ##constant1=tf.constant([[1.0,2.0,3.0],[4.0,5.0,6.0],[7.0,8.0,9.0]]) ##constant2=tf.constant([[1.0,2.0,3.0],[1.0,4.0,2.0],[1.0,6.0,1.0]]) ##constructionErrorMatrix=self.constructionError(constant1,constant2,alpha_cat,bcat) y1c1=tf.subtract(y1_normalization,c1) y2c2=tf.subtract(y2_normalization,c2) constructionErrorMatrix=self.constructionError(y1c1,y2c2,alpha_cat,bcat) ################################################################################ print_info=tf.Print(iiii,[iiii],"\niiii:")#专门为了调试用,输出相关信息。 tfPrint=print_info+tfPrint print_info=tf.Print(columnLinesOfL,[columnLinesOfL],"\nbeforemodify.columnLinesOfL:")#专门为了调试用,输出相关信息。 tfPrint=print_info+tfPrint print_info=tf.Print(constructionErrorMatrix,[constructionErrorMatrix],"\nbeforemodify.constructionErrorMatrix:",summarize=100)#专门为了调试用,输出相关信息。 tfPrint=tf.to_int32(print_info[0])+tfPrint#一种不断输出tf.Print的方式,注意tf.Print的返回值。 ################################################################################ J_minpos=tf.to_int32(tf.argmin(constructionErrorMatrix))#如果不转换的话,下面调用delete_one_column中,会调用tf.slice,之后tf.slice的参数中的类型必须是一样的。 J_min=constructionErrorMatrix[J_minpos] #一共要进行sl-1次循环。因为是从sl个叶子节点,两两结合sl-1次,才能形成一颗完整的树,而且是采用Greedy的方式。 #所以,需要为下次循环做准备。 #第一步,从该sentence的词向量矩阵中删除第J_minpos+1列,因为第J_minpos和第J_minpos+1列对应的单词要合并为一个新的节点,这里就是修改L ################################################################################ print_info=tf.Print(self.L,[self.L[0]],"\nbeforemodify.Lrow0:",summarize=100)#专门为了调试用,输出相关信息。 tfPrint=tf.to_int32(print_info[0][0])+tfPrint print_info=tf.Print(self.L,[tf.shape(self.L)],"\nbeforemodify.Lshape:")#专门为了调试用,输出相关信息。 tfPrint=tf.to_int32(print_info[0][0])+tfPrint ################################################################################ deleteColumnIndex=J_minpos+1 self.L=self.delete_one_column(self.L,deleteColumnIndex,self.numlinesOfL,columnLinesOfL) columnLinesOfL=tf.subtract(columnLinesOfL,1)#列数减去1. ################################################################################ print_info=tf.Print(deleteColumnIndex,[deleteColumnIndex],"\nbeforemodify.deleteColumnIndex:")#专门为了调试用,输出相关信息。 tfPrint=print_info+tfPrint print_info=tf.Print(self.L,[self.L[0]],"\naftermodify.Lrow0:",summarize=100)#专门为了调试用,输出相关信息。 tfPrint=tf.to_int32(print_info[0][0])+tfPrint print_info=tf.Print(self.L,[tf.shape(self.L)],"\naftermodify.Lshape:")#专门为了调试用,输出相关信息。 tfPrint=tf.to_int32(print_info[0][0])+tfPrint print_info=tf.Print(columnLinesOfL,[columnLinesOfL],"\naftermodify.columnLinesOfL:")#专门为了调试用,输出相关信息。 tfPrint=print_info+tfPrint ################################################################################ #第二步,将新的词向量赋值给第J_minpos列 columnTensor=p_normalization[:,J_minpos] new_column_tensor=tf.expand_dims(columnTensor,1) self.L=self.modify_one_column(self.L,new_column_tensor,J_minpos,self.numlinesOfL,columnLinesOfL) #第三步,同时将新的非叶子节点的词向量存入nodes_tensor modified_index_tensor=tf.to_int32(tf.add(iiii,self.sentence_length)) nodes_tensor=self.modify_one_column(nodes_tensor,new_column_tensor,modified_index_tensor,self.numlines_tensor,self.numcolunms_tensor) #第四步:记录合并节点的最小损失,存入node_tensors_cost_tensor J_min_tensor=tf.expand_dims(tf.expand_dims(J_min,0),1) node_tensors_cost_tensor=self.modify_one_column(node_tensors_cost_tensor,J_min_tensor,iiii,self.numlines_tensor2,self.numcolunms_tensor2) ####进入下一次循环 iiii=tf.add(iiii,1) print_info=tf.Print(J_minpos,[J_minpos,J_minpos+1],"node:")#专门为了调试用,输出相关信息。 tfPrint=tfPrint+print_info #columnLinesOfL=tf.subtract(columnLinesOfL,1)#在上面的循环体中已经执行了,没有必要再执行。 returniiii,columnLinesOfL,node_tensors_cost_tensor,nodes_tensor,tfPrint iiii,columnLinesOfL,node_tensors_cost_tensor,nodes_tensor,tfPrint=tf.while_loop(loop____cond,____recurrence,loop____vars,parallel_iterations=1) pass上述代码是Greedy算法,递归构建神经网络树结构。
但是程序出错了,后来不断的调试,才发现self.L虽然跟循环loop____vars中的变量有依赖关系,也就是在tf.while_loop进行循环的时候,也可以输出它的值。
但是,它每一次都无法真正意义上对self.L进行修改。会发现,每一次循环结束之后,进入下一次循环时,self.L仍然没有变化。
执行结果如下:
beforemodify.columnLinesOfL:[31] iiii:[0] aftermodify.columnLinesOfL:[30] beforemodify.Lshape:[30031] beforemodify.Lrow0:[0.126693-0.013654-0.166731-0.13703-0.2613950.114590.0160010.0160010.1446030.055880.1717870.0160011.0645450.1446030.130615-0.13703-0.2613951.064545-0.2613950.1446030.0366261.0645450.1888710.2011980.055880.2037950.2011980.035360.0893450.0837780.103635] node:[0][1] beforemodify.constructionErrorMatrix:[3.043173368670620611.39105671542779419.65281995611585613.71345331390386811.62597382980587912.8275333208195649.751351372320474613.00915129289081113.89608924328906510.6498291099716489.4523937474508615.70448608692164118.27406579078186212.44786629991502415.30299610363768913.71345331390386814.29554984473875113.77940617578935811.62521231425905916.34050722320144919.09596436468971715.1014919493631911.98944316232943713.43665465035405811.12037331111050512.3934531797500213.56805280071242410.9984303411246338.32239093235998696.8896857405641851] aftermodify.Lshape:[30030] aftermodify.Lrow0:[0.126693-0.166731-0.13703-0.2613950.114590.0160010.0160010.1446030.055880.1717870.0160011.0645450.1446030.130615-0.13703-0.2613951.064545-0.2613950.1446030.0366261.0645450.1888710.2011980.055880.2037950.2011980.035360.0893450.0837780.103635] beforemodify.deleteColumnIndex:[1] beforemodify.columnLinesOfL:[30] iiii:[1] beforemodify.Lshape:[30031] aftermodify.columnLinesOfL:[29] beforemodify.Lrow0:[0.126693-0.013654-0.166731-0.13703-0.2613950.114590.0160010.0160010.1446030.055880.1717870.0160011.0645450.1446030.130615-0.13703-0.2613951.064545-0.2613950.1446030.0366261.0645450.1888710.2011980.055880.2037950.2011980.035360.0893450.0837780.103635] beforemodify.deleteColumnIndex:[1] node:[0][1] beforemodify.constructionErrorMatrix:[3.043173368670620611.39105671542779419.65281995611585613.71345331390386811.62597382980587912.8275333208195649.751351372320474613.00915129289081113.89608924328906510.6498291099716489.4523937474508615.70448608692164118.27406579078186212.44786629991502415.30299610363768913.71345331390386814.29554984473875113.77940617578935811.62521231425905916.34050722320144919.09596436468971715.1014919493631911.98944316232943713.43665465035405811.12037331111050512.3934531797500213.56805280071242410.9984303411246338.3223909323599869] aftermodify.Lshape:[30029] aftermodify.Lrow0:[0.126693-0.166731-0.13703-0.2613950.114590.0160010.0160010.1446030.055880.1717870.0160011.0645450.1446030.130615-0.13703-0.2613951.064545-0.2613950.1446030.0366261.0645450.1888710.2011980.055880.2037950.2011980.035360.0893450.083778] beforemodify.columnLinesOfL:[29] iiii:[2]后面那个aftermodify时Lshape为[30029]的原因是:执行
self.L=self.modify_one_column(self.L,new_column_tensor,J_minpos,self.numlinesOfL,columnLinesOfL)
时,columnLinesOfL是循环loop____vars中的变量,因此会随着每次循环发生变化,我写的modify_one_column见我的博文“修改tensor张量矩阵的某一列”。它决定了
修改后tensor的维度。
但是,无论如何,每一次循环,都是
beforemodify.Lshape:[30031]
说明self.L在循环体中虽然被修改了。但是下次循环又会被重置为初始值。
以上这篇基于tensorflowfor循环while循环案例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。