代码(操纵全局变量)

  1. xiaojie=1
  2. i=tf.constant(0,dtype=tf.int32)
  3. batch_len=tf.constant(10,dtype=tf.int32)
  4. loop_cond = lambda a,b: tf.less(a,batch_len)
  5. #yy=tf.Print(batch_len,[batch_len],"batch_len:")
  6. yy=tf.constant(0)
  7. loop_vars=[i,yy]
  8. def _recurrence(i,yy):
  9. c=tf.constant(2,dtype=tf.int32)
  10. x=tf.multiply(i,c)
  11. global xiaojie
  12. xiaojie=xiaojie+1
  13. print_info=tf.Print(x,[x],"x:")
  14. yy=yy+print_info
  15. i=tf.add(i,1)
  16. # print (xiaojie)
  17. return i,yy
  18. i,yy=tf.while_loop(loop_cond,_recurrence,loop_vars,parallel_iterations=1)#可以批处理
  19. sess = tf.Session()
  20. print (sess.run(i))
  21. print (xiaojie)

输出的是10和2。

也就是xiaojie只被修改了一次。

这个时候,在_recurrence循环体中添加语句

  1. print (xiaojie)

会输出2。而且只输出一次。具体为什么,最后总结的时候再解释。

代码(操纵类成员变量)class RNN_Model():

  1. def __init__(self):
  2. self.xiaojie=1
  3. def test_RNN(self):
  4. i=tf.constant(0,dtype=tf.int32)
  5. batch_len=tf.constant(10,dtype=tf.int32)
  6. loop_cond = lambda a,b: tf.less(a,batch_len)
  7. #yy=tf.Print(batch_len,[batch_len],"batch_len:")
  8. yy=tf.constant(0)
  9. loop_vars=[i,yy]
  10. def _recurrence(i,yy):
  11. c=tf.constant(2,dtype=tf.int32)
  12. x=tf.multiply(i,c)
  13. self.xiaojie=self.xiaojie+1
  14. print_info=tf.Print(x,[x],"x:")
  15. yy=yy+print_info
  16. i=tf.add(i,1)
            print ("_recurrence:",self.xiaojie)
  17. return i,yy
  18. i,yy=tf.while_loop(loop_cond,_recurrence,loop_vars,parallel_iterations=1)#可以批处理
  19. sess = tf.Session()
  20. sess.run(yy)
  21. print (self.xiaojie)
  22. if __name__ == "__main__":
  23. model = RNN_Model()#构建树,并且构建词典
  24. model.test_RNN()

输出是:

  1. _recurrence: 2
  2. 10
  3. 2

tf.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中变量有依赖关系,但是并没有真正被修改。

  1. #IIII通过计算将非叶子节点的词向量也放入nodes_tensor中。
  2. iiii=tf.constant(0,dtype=tf.int32)
  3. loop____cond = lambda a,b,c,d,e: tf.less(a,self.sentence_length-1)#iiii的范围是0sl-2。注意,不包括sl-1。这是因为只需要计算sentence_length-1次,就能构建出一颗树
  4. loop____vars=[iiii,columnLinesOfL,node_tensors_cost_tensor,nodes_tensor,tfPrint]
  5. def ____recurrence(iiii,columnLinesOfL,node_tensors_cost_tensor,nodes_tensor,tfPrint):#循环的目的是实现Greedy算法
  6. ###
  7. #Greedy的主要目标就是确立树结构。
  8. ###
  9. c1 = self.L[:,0:columnLinesOfL-1]#这段代码是从RvNNmatlab的源码中复制过来的,但是Matlab的下标是从1开始,并且Matlab1:2就是12,而python1:2表示的是1,不包括2,所以,有很大的不同。
  10. c2 = self.L[:,1:columnLinesOfL]
  11. c=tf.concat([c1,c2],axis=0)
  12. p=tf.tanh(tf.matmul(self.W1,c)+tf.tile(self.b1,[1,columnLinesOfL-1]))
  13. p_normalization=self.normalization(p)
  14. y=tf.tanh(tf.matmul(self.U,p_normalization)+tf.tile(self.bs,[1,columnLinesOfL-1]))#根据Matlab中的源码来的,即重构后,也有一个激活的过程。
  15. #将Y矩阵拆分成上下部分之后,再分别进行标准化。
  16. columnlines_y=columnLinesOfL-1
  17. (y1,y2)=self.split_by_row(y,columnlines_y)
  18. y1_normalization=self.normalization(y1)
  19. y2_normalization=self.normalization(y2)
  20. #论文中提出一种计算重构误差时要考虑的权重信息。具体见论文,这里暂时不实现。
  21. #这个权重是可以修改的。
  22. alpha_cat=1
  23. bcat=1
  24. #计算重构误差矩阵
  25. ## constant1=tf.constant([[1.0,2.0,3.0],[4.0,5.0,6.0],[7.0,8.0,9.0]])
  26. ## constant2=tf.constant([[1.0,2.0,3.0],[1.0,4.0,2.0],[1.0,6.0,1.0]])
  27. ## constructionErrorMatrix=self.constructionError(constant1,constant2,alpha_cat,bcat)
  28. y1c1=tf.subtract(y1_normalization,c1)
  29. y2c2=tf.subtract(y2_normalization,c2)
  30. constructionErrorMatrix=self.constructionError(y1c1,y2c2,alpha_cat,bcat)
  31. ################################################################################
  32. print_info=tf.Print(iiii,[iiii],"\niiii:")#专门为了调试用,输出相关信息。
  33. tfPrint=print_info+tfPrint
  34. print_info=tf.Print(columnLinesOfL,[columnLinesOfL],"\nbefore modify. columnLinesOfL:")#专门为了调试用,输出相关信息。
  35. tfPrint=print_info+tfPrint
  36. print_info=tf.Print(constructionErrorMatrix,[constructionErrorMatrix],"\nbefore modify. constructionErrorMatrix:",summarize=100)#专门为了调试用,输出相关信息。
  37. tfPrint=tf.to_int32(print_info[0])+tfPrint#一种不断输出tf.Print的方式,注意tf.Print的返回值。
  38. ################################################################################
  39. J_minpos=tf.to_int32(tf.argmin(constructionErrorMatrix))#如果不转换的话,下面调用delete_one_column中,会调用tf.slice,之后tf.slice的参数中的类型必须是一样的。
  40. J_min=constructionErrorMatrix[J_minpos]
  41. #一共要进行sl-1次循环。因为是从sl个叶子节点,两两结合sl-1次,才能形成一颗完整的树,而且是采用Greedy的方式。
  42. #所以,需要为下次循环做准备。
  43. #第一步,从该sentence的词向量矩阵中删除第J_minpos+1列,因为第J_minpos和第J_minpos+1列对应的单词要合并为一个新的节点,这里就是修改L
  44. ################################################################################
  45. print_info=tf.Print(self.L,[self.L[0]],"\nbefore modify. L row 0:",summarize=100)#专门为了调试用,输出相关信息。
  46. tfPrint=tf.to_int32(print_info[0][0])+tfPrint
  47. print_info=tf.Print(self.L,[tf.shape(self.L)],"\nbefore modify. L shape:")#专门为了调试用,输出相关信息。
  48. tfPrint=tf.to_int32(print_info[0][0])+tfPrint
  49. ################################################################################
  50. deleteColumnIndex=J_minpos+1
  51. self.L=self.delete_one_column(self.L,deleteColumnIndex,self.numlinesOfL,columnLinesOfL)
  52. columnLinesOfL=tf.subtract(columnLinesOfL,1) #列数减去1.
  53. ################################################################################
  54. print_info=tf.Print(deleteColumnIndex,[deleteColumnIndex],"\nbefore modify. deleteColumnIndex:")#专门为了调试用,输出相关信息。
  55. tfPrint=print_info+tfPrint
  56. print_info=tf.Print(self.L,[self.L[0]],"\nafter modify. L row 0:",summarize=100)#专门为了调试用,输出相关信息。
  57. tfPrint=tf.to_int32(print_info[0][0])+tfPrint
  58.  
  59. print_info=tf.Print(self.L,[tf.shape(self.L)],"\nafter modify. L shape:")#专门为了调试用,输出相关信息。
  60. tfPrint=tf.to_int32(print_info[0][0])+tfPrint
  61. print_info=tf.Print(columnLinesOfL,[columnLinesOfL],"\nafter modify. columnLinesOfL:")#专门为了调试用,输出相关信息。
  62. tfPrint=print_info+tfPrint
  63. ################################################################################
  64.  
  65. #第二步,将新的词向量赋值给第J_minpos列
  66. columnTensor=p_normalization[:,J_minpos]
  67. new_column_tensor=tf.expand_dims(columnTensor,1)
  68. self.L=self.modify_one_column(self.L,new_column_tensor,J_minpos,self.numlinesOfL,columnLinesOfL)
  69. #第三步,同时将新的非叶子节点的词向量存入nodes_tensor
  70. modified_index_tensor=tf.to_int32(tf.add(iiii,self.sentence_length))
  71. nodes_tensor=self.modify_one_column(nodes_tensor,new_column_tensor,modified_index_tensor,self.numlines_tensor,self.numcolunms_tensor)
  72. #第四步:记录合并节点的最小损失,存入node_tensors_cost_tensor
  73. J_min_tensor=tf.expand_dims(tf.expand_dims(J_min,0),1)
  74. node_tensors_cost_tensor=self.modify_one_column(node_tensors_cost_tensor,J_min_tensor,iiii,self.numlines_tensor2,self.numcolunms_tensor2)
  75. ####进入下一次循环
  76. iiii=tf.add(iiii,1)
  77. print_info=tf.Print(J_minpos,[J_minpos,J_minpos+1],"node:")#专门为了调试用,输出相关信息。
  78. tfPrint=tfPrint+print_info
  79. # columnLinesOfL=tf.subtract(columnLinesOfL,1) #在上面的循环体中已经执行了,没有必要再执行。
  80. return iiii,columnLinesOfL,node_tensors_cost_tensor,nodes_tensor,tfPrint
  81. iiii,columnLinesOfL,node_tensors_cost_tensor,nodes_tensor,tfPrint=tf.while_loop(loop____cond,____recurrence,loop____vars,parallel_iterations=1)
  82. pass

上述代码是Greedy算法,递归构建神经网络树结构。

但是程序出错了,后来不断的调试,才发现self.L虽然跟循环loop____vars中的变量有依赖关系,也就是在tf.while_loop进行循环的时候,也可以输出它的值。

但是,它每一次都无法真正意义上对self.L进行修改。会发现,每一次循环结束之后,进入下一次循环时,self.L仍然没有变化。

执行结果如下:

  1. before modify. columnLinesOfL:[31]
  2. iiii:[0]
  3.  
  4. after modify. columnLinesOfL:[30]
  5.  
  6. before modify. L shape:[300 31]
  7.  
  8. before modify. L row 0:[0.126693 -0.013654 -0.166731 -0.13703 -0.261395 0.11459 0.016001 0.016001 0.144603 0.05588 0.171787 0.016001 1.064545 0.144603 0.130615 -0.13703 -0.261395 1.064545 -0.261395 0.144603 0.036626 1.064545 0.188871 0.201198 0.05588 0.203795 0.201198 0.03536 0.089345 0.083778 0.103635]
  9. node:[0][1]
  10.  
  11. before modify. constructionErrorMatrix:[3.0431733686706206 11.391056715427794 19.652819956115856 13.713453313903868 11.625973829805879 12.827533320819564 9.7513513723204746 13.009151292890811 13.896089243289065 10.649829109971648 9.45239374745086 15.704486086921641 18.274065790781862 12.447866299915024 15.302996103637689 13.713453313903868 14.295549844738751 13.779406175789358 11.625212314259059 16.340507223201449 19.095964364689717 15.10149194936319 11.989443162329437 13.436654650354058 11.120373311110505 12.39345317975002 13.568052800712424 10.998430341124633 8.3223909323599869 6.8896857405641851]
  12.  
  13. after modify. L shape:[300 30]
  14.  
  15. after modify. L row 0:[0.126693 -0.166731 -0.13703 -0.261395 0.11459 0.016001 0.016001 0.144603 0.05588 0.171787 0.016001 1.064545 0.144603 0.130615 -0.13703 -0.261395 1.064545 -0.261395 0.144603 0.036626 1.064545 0.188871 0.201198 0.05588 0.203795 0.201198 0.03536 0.089345 0.083778 0.103635]
  16.  
  17. before modify. deleteColumnIndex:[1]
  18.  
  19. before modify. columnLinesOfL:[30]
  20.  
  21. iiii:[1]
  22.  
  23. before modify. L shape:[300 31]
  24.  
  25. after modify. columnLinesOfL:[29]
  26.  
  27. before modify. L row 0:[0.126693 -0.013654 -0.166731 -0.13703 -0.261395 0.11459 0.016001 0.016001 0.144603 0.05588 0.171787 0.016001 1.064545 0.144603 0.130615 -0.13703 -0.261395 1.064545 -0.261395 0.144603 0.036626 1.064545 0.188871 0.201198 0.05588 0.203795 0.201198 0.03536 0.089345 0.083778 0.103635]
  28.  
  29. before modify. deleteColumnIndex:[1]
  30. node:[0][1]
  31.  
  32. before modify. constructionErrorMatrix:[3.0431733686706206 11.391056715427794 19.652819956115856 13.713453313903868 11.625973829805879 12.827533320819564 9.7513513723204746 13.009151292890811 13.896089243289065 10.649829109971648 9.45239374745086 15.704486086921641 18.274065790781862 12.447866299915024 15.302996103637689 13.713453313903868 14.295549844738751 13.779406175789358 11.625212314259059 16.340507223201449 19.095964364689717 15.10149194936319 11.989443162329437 13.436654650354058 11.120373311110505 12.39345317975002 13.568052800712424 10.998430341124633 8.3223909323599869]
  33.  
  34. after modify. L shape:[300 29]
  35.  
  36. after modify. L row 0:[0.126693 -0.166731 -0.13703 -0.261395 0.11459 0.016001 0.016001 0.144603 0.05588 0.171787 0.016001 1.064545 0.144603 0.130615 -0.13703 -0.261395 1.064545 -0.261395 0.144603 0.036626 1.064545 0.188871 0.201198 0.05588 0.203795 0.201198 0.03536 0.089345 0.083778]
  37.  
  38. before modify. columnLinesOfL:[29]
  39.  
  40. iiii:[2]

后面那个after modify时L shape为[300 29]的原因是:执行

  1. self.L=self.modify_one_column(self.L,new_column_tensor,J_minpos,self.numlinesOfL,columnLinesOfL)
    时,columnLinesOfL是循环loop____vars中的变量,因此会随着每次循环发生变化,我写的modify_one_column见我的博文“修改tensor张量矩阵的某一列”。它决定了
    修改后tensor的维度。
    但是,无论如何,每一次循环,都是
  1. before modify. L shape:[300 31]
    说明self.L在循环体中虽然被修改了。但是下次循环又会被重置为初始值。

11 tensorflow在tf.while_loop循环(非一般循环)中使用操纵变量该怎么做的更多相关文章

  1. tf.while_loop

    tf.while_loop(cond, body, loop_vars, shape_invariants=None, parallel_iterations=10, back_prop=True, ...

  2. TensorFlow之tf.nn.dropout():防止模型训练过程中的过拟合问题

    一:适用范围: tf.nn.dropout是TensorFlow里面为了防止或减轻过拟合而使用的函数,它一般用在全连接层 二:原理: dropout就是在不同的训练过程中随机扔掉一部分神经元.也就是让 ...

  3. Tensorflow函数——tf.variable_scope()

    Tensorflow函数——tf.variable_scope()详解 https://blog.csdn.net/yuan0061/article/details/80576703 2018年06月 ...

  4. TensorFlow笔记-02-Windows下搭建TensorFlow环境(win版非虚拟机)

    TensorFlow笔记-02-Windows下搭建TensorFlow环境(win版非虚拟机) 本篇介绍的是在windows系统下,使用 Anaconda+PyCharm,不使用虚拟机,也不使用 L ...

  5. 【TensorFlow】tf.nn.conv2d是怎样实现卷积的?

    tf.nn.conv2d是TensorFlow里面实现卷积的函数,参考文档对它的介绍并不是很详细,实际上这是搭建卷积神经网络比较核心的一个方法,非常重要 tf.nn.conv2d(input, fil ...

  6. TensorFlow2.0(11):tf.keras建模三部曲

    .caret, .dropup > .btn > .caret { border-top-color: #000 !important; } .label { border: 1px so ...

  7. [Tensorflow] 使用 tf.train.Checkpoint() 保存 / 加载 keras subclassed model

    在 subclassed_model.py 中,通过对 tf.keras.Model 进行子类化,设计了两个自定义模型. import tensorflow as tf tf.enable_eager ...

  8. tensorflow队列tf.FIFOQueue | enqueue | enqueue_many | dequeue | dequeue_many

    关于队列的相关知识,盗用一张https://blog.csdn.net/HowardWood/article/details/79406891的动态图 import tensorflow as tf ...

  9. 【Tensorflow】tf.nn.atrous_conv2d如何实现空洞卷积?膨胀卷积

    介绍关于空洞卷积的理论可以查看以下链接,这里我们不详细讲理论: 1.Long J, Shelhamer E, Darrell T, et al. Fully convolutional network ...

随机推荐

  1. Netty核心概念(4)之Bootstrap

    1.前言 第三节介绍了Netty的一些基本概念,此节介绍Netty的第一个概念Bootstrap——启动类.Netty中服务端和客户端的启动类是不一样的,这个不要搞错了,类都在bootstrap包下. ...

  2. OpenGL12-shader(GLSL)着色语言1(代码已上传)

    OpenGL着色语言(GLSL――OpenGL Shading Language)是用来在OpenGL中着色编程的语言, 也即开发人员写的短小的自定义程序,他们是在图形卡的GPU (Graphic P ...

  3. android学习-LocationManager(一)-

    Location Provider是不同位置信息来源的抽象 Location封装了从位置提供者提供给应用的位置数据(经纬度) Criteria提供了查询获取包含特定特征的位置提供者(accuracy精 ...

  4. expect安装和使用

    Expect是一个我们常在shell交互时常用到的工具,它主要由expect-send组成.Expect是等待输出内容中的特定字符.然后由send发送特定的相应.Expect的工作流程类似于:小明和小 ...

  5. HTML引入CSS样式的四种方法

    在HTML中引入CSS的方法主要有四种,它们分别是行内式.内嵌式.链接式和导入式. 1.行内式          行内式是在标记的style属性中设定CSS样式.这种方式没有体现出CSS的优势,不推荐 ...

  6. SpringBoot入门 (五) 数据库访问之spring data jpa

    本文记录学习使用spring data jpa访问数据库 一 什么是Spring Data JPA JPA(Java Persistence API)是Sun官方提出的Java持久化规范.它为Java ...

  7. Java 注解实例

    package com.annotation; import java.lang.annotation.Retention; import java.lang.annotation.Target; i ...

  8. EF的小知识

    关于EF多表提交保存的问题,同理,修改也适用,用EF不久,总是每张表提交都SaveChanges()一下,后面查看了点资料,其实直接可以add到每张表,直接最后提交就行了,这样操作起来和性能上都要好很 ...

  9. Maven - dependency那些事儿

    身边有几位刚使用Maven的同学表示——在一个叫"pom.xml"的文件里声明一个依赖就不用去手动添加jar了,感觉这东西和自己手动管理依赖没太大区别. 当然,并不是这样,在此记录 ...

  10. static关键字的内存分析

    通常情况下,Java把内存分为栈内存.堆内存和方法区 栈内存用来存放一些基本类型的变量和数组(数组也是一种引用类型)及对象的引用变量 堆内存主要是来放置对象的,即我们在程序中new出来的对象. sta ...