只有光頭才能變強。html
文本已收錄至個人GitHub倉庫,歡迎Star:https://github.com/ZhongFuCheng3y/3ypython
回顧前面:git
這篇文章主要講講TensorBoard的基本使用以及name_scope和variable_scope
的區別github
首先來說講TensorBoard是什麼吧,我當時是在官方文檔裏學習的,官網也放出了介紹TensorBoard的視頻。我在b站搜了一把,發現也有,你們能夠先去看看視頻瞭解一下(其實已經說得很好了):shell
爲了更方便 TensorFlow 程序的理解、調試與優化,因而就有了TensorBoard 這樣的的可視化工具網絡
由於咱們編寫出來的TensorFlow程序,建好一個神經網絡,其實咱們也不知道神經網絡裏頭具體細節到底作了什麼,要人工調試十分困難(就比如你沒法想象出遞歸的全部步驟同樣)。有了TensorBoard,能夠將TensorFlow程序的執行步驟都顯示出來,很是直觀。而且,咱們能夠對訓練的參數(好比loss值)進行統計,用圖的方式來查看變化的趨勢。dom
在視頻中其實也有提到,咱們想要TensorBoard的圖可以更好地展現(更加有條理),那通常咱們須要對其用name_scope
取名。ide
那除了name_scope
,還有一個叫作variable_scope
。那他們有什麼區別呢?顧名思義,name_scope
是一個名稱做用域,variable_scope
是變量做用域。工具
在前面文章中,建立變量有兩種方式,一種是用tf.get_variable()
來建立,一種是用tf.Variable()
來建立。這兩種建立方式也是有區別的。oop
tf.name_scope
下時,tf.get_variable()
建立的變量名不受name_scope
的影響,並且在未指定共享變量時,若是重名就會報錯。tf.Variable()
會自動檢測有沒有變量重名,若是有則會自行處理(自動建立一個)好比下面的代碼:
with tf.name_scope('name_sp1') as scp1: with tf.variable_scope('var_scp2') as scp2: with tf.name_scope('name_scp3') as scp3: a = tf.Variable('a') b = tf.get_variable('b')
等同於:
with tf.name_scope('name_sp1') as scp1: with tf.name_scope('name_sp2') as scp2: with tf.name_scope('name_scp3') as scp3: a = tf.Variable('a') with tf.variable_scope('var_scp2') as scp2: b = tf.get_variable('b')
這裏體現的是若是用get_variable
的方式來建立對象,是不受name_scope
所影響的。
要注意的是,下面的代碼會報錯。由於在scp做用域下壓根就沒有a這個變量,同時又設置成reuse=True
。這裏由於的是找不到共享變量而出錯!
with tf.variable_scope('scp', reuse=True) as scp: a = tf.get_varialbe('a') #報錯
一樣地,下面的代碼也會報錯,由於明明已經有共享變量了,但設置成reuse=false
。因此就會報錯。
with tf.variable_scope('scp', reuse=False) as scp: a = tf.get_varialbe('a') a = tf.get_varialbe('a') #報錯
最後,咱們再來看這個例子,應該就能夠看懂了。
with tf.variable_scope('variable_scope_y') as scope: var1 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32) scope.reuse_variables() # 設置共享變量 var1_reuse = tf.get_variable(name='var1') var2 = tf.Variable(initial_value=[2.], name='var2', dtype=tf.float32) var2_reuse = tf.Variable(initial_value=[2.], name='var2', dtype=tf.float32) with tf.Session() as sess: sess.run(tf.global_variables_initializer()) print(var1.name, sess.run(var1)) print(var1_reuse.name, sess.run(var1_reuse)) print(var2.name, sess.run(var2)) print(var2_reuse.name, sess.run(var2_reuse)) # 輸出結果: # variable_scope_y/var1:0 [-1.59682846] # variable_scope_y/var1:0 [-1.59682846] 能夠看到變量var1_reuse重複使用了var1 # variable_scope_y/var2:0 [ 2.] # variable_scope_y/var2_1:0 [ 2.]
參考資料:
下面咱們來看一個TensorBoard簡單的入門例子,感覺一下:
def learn_tensor_board_2(): # prepare the original data with tf.name_scope('data'): x_data = np.random.rand(100).astype(np.float32) y_data = 0.3 * x_data + 0.1 ##creat parameters with tf.name_scope('parameters'): with tf.name_scope('weights'): weight = tf.Variable(tf.random_uniform([1], -1.0, 1.0)) tf.summary.histogram('weight', weight) with tf.name_scope('biases'): bias = tf.Variable(tf.zeros([1])) tf.summary.histogram('bias', bias) ##get y_prediction with tf.name_scope('y_prediction'): y_prediction = weight * x_data + bias ##compute the loss with tf.name_scope('loss'): loss = tf.reduce_mean(tf.square(y_data - y_prediction)) tf.summary.scalar('loss', loss) ##creat optimizer optimizer = tf.train.GradientDescentOptimizer(0.5) # creat train ,minimize the loss with tf.name_scope('train'): train = optimizer.minimize(loss) # creat init with tf.name_scope('init'): init = tf.global_variables_initializer() ##creat a Session sess = tf.Session() # merged merged = tf.summary.merge_all() ##initialize writer = tf.summary.FileWriter("/Users/zhongfucheng/tensorboard/loss-2", sess.graph) sess.run(init) ## Loop for step in range(201): sess.run(train) rs = sess.run(merged) writer.add_summary(rs, step) if __name__ == '__main__': learn_tensor_board_2() # 啓動完了以後,要在命令行上運行tensor_board的命令,指定其目錄,最後咱們就能夠經過6006的默認端口訪問咱們的圖。
(例子來源網絡,我改動了一下,出處我忘了,侵刪~)
接下來,咱們啓動一下TensorBoard,看看圖是怎麼樣的,啓動命令以下:
tensorboard --logdir=/Users/zhongfucheng/tensorboard/loss-2
啓動成功的圖:
經過6006端口咱們去訪問一下,首先咱們能夠檢測到loss值的變動:
咱們也能夠查看TensorFlow程序大概的執行步驟:
參數w和b的直方圖:
總之,TensorBoard能夠方便地查看咱們參數的變化,以便更好理解咱們寫的代碼。
參考資料:
樂於輸出乾貨的Java技術公衆號:Java3y。公衆號內有200多篇原創技術文章、海量視頻資源、精美腦圖,不妨來關注一下!
以爲個人文章寫得不錯,不妨點一下贊!