您好,登錄后才能下訂單哦!
小編給大家分享一下關于tensorflow中for循環while循環案例分析,希望大家閱讀完這篇文章后大所收獲,下面讓我們一起去探討方法吧!
我就廢話不多說了,大家還是直接看代碼吧~
import tensorflow as tf n1 = tf.constant(2) n2 = tf.constant(3) n3 = tf.constant(4) def cond1(i, a, b): return i < n1 def cond2(i, a, b): return i < n2 def cond3(i, a, b): return i < n3 def body(i, a, b): return i + 1, b, a + b i1, a1, b1 = tf.while_loop(cond1, body, (2, 1, 1)) i2, a2, b2 = tf.while_loop(cond2, body, (2, 1, 1)) i3, a3, b3 = tf.while_loop(cond3, body, (2, 1, 1)) sess = tf.Session() print(sess.run(i1)) print(sess.run(a1)) print(sess.run(b1)) print("-") print(sess.run(i2)) print(sess.run(a2)) print(sess.run(b2)) print("-") print(sess.run(i3)) print(sess.run(a3)) print(sess.run(b3))
print結果:
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 = lambda a,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) global xiaojie xiaojie=xiaojie+1 print_info=tf.Print(x,[x],"x:") yy=yy+print_info i=tf.add(i,1) # print (xiaojie) return i,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。而且只輸出一次。具體為什么,最后總結的時候再解釋。
代碼(操縱類成員變量)class RNN_Model():
def __init__(self): self.xiaojie=1 def test_RNN(self): i=tf.constant(0,dtype=tf.int32) batch_len=tf.constant(10,dtype=tf.int32) loop_cond = lambda a,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) return i,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 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中變量有依賴關系,但是并沒有真正被修改。
#IIII通過計算將非葉子節點的詞向量也放入nodes_tensor中。 iiii=tf.constant(0,dtype=tf.int32) loop____cond = lambda a,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],"\nbefore modify. columnLinesOfL:")#專門為了調試用,輸出相關信息。 tfPrint=print_info+tfPrint print_info=tf.Print(constructionErrorMatrix,[constructionErrorMatrix],"\nbefore modify. 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]],"\nbefore modify. L row 0:",summarize=100)#專門為了調試用,輸出相關信息。 tfPrint=tf.to_int32(print_info[0][0])+tfPrint print_info=tf.Print(self.L,[tf.shape(self.L)],"\nbefore modify. L shape:")#專門為了調試用,輸出相關信息。 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],"\nbefore modify. deleteColumnIndex:")#專門為了調試用,輸出相關信息。 tfPrint=print_info+tfPrint print_info=tf.Print(self.L,[self.L[0]],"\nafter modify. L row 0:",summarize=100)#專門為了調試用,輸出相關信息。 tfPrint=tf.to_int32(print_info[0][0])+tfPrint print_info=tf.Print(self.L,[tf.shape(self.L)],"\nafter modify. L shape:")#專門為了調試用,輸出相關信息。 tfPrint=tf.to_int32(print_info[0][0])+tfPrint print_info=tf.Print(columnLinesOfL,[columnLinesOfL],"\nafter modify. 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) #在上面的循環體中已經執行了,沒有必要再執行。 return iiii,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仍然沒有變化。
執行結果如下:
before modify. columnLinesOfL:[31] iiii:[0] after modify. columnLinesOfL:[30] before modify. L shape:[300 31] 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] node:[0][1] 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] after modify. L shape:[300 30] 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] before modify. deleteColumnIndex:[1] before modify. columnLinesOfL:[30] iiii:[1] before modify. L shape:[300 31] after modify. columnLinesOfL:[29] 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] before modify. deleteColumnIndex:[1] node:[0][1] 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] after modify. L shape:[300 29] 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] before modify. columnLinesOfL:[29] iiii:[2]
后面那個after modify時L shape為[300 29]的原因是:執行
self.L=self.modify_one_column(self.L,new_column_tensor,J_minpos,self.numlinesOfL,columnLinesOfL)
時,columnLinesOfL是循環loop____vars中的變量,因此會隨著每次循環發生變化,我寫的modify_one_column見我的博文“修改tensor張量矩陣的某一列”。它決定了
修改后tensor的維度。
但是,無論如何,每一次循環,都是
before modify. L shape:[300 31]
說明self.L在循環體中雖然被修改了。但是下次循環又會被重置為初始值。
看完了這篇文章,相信你對關于tensorflow中for循環while循環案例分析有了一定的了解,想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。