天天看點

TensorFlow —— Demo建構資料流圖運作資料流圖

import tensorflow as tf           
g = tf.Graph()  # 建立一個Graph對象           

在模型中有兩個“全局”風格的Variable對象:

global_step

total_output

。它們本質上是全局的,是以在聲明它們時需要與資料流圖的其他節點區分開,并把它們放入自己的名稱作用域。

trainable= False

的設定使得該Variable對象對象不會對模型造成影響(因為沒有任何訓練的步驟),但該設定明确指定了這些Variable對象隻能通過手工設定。

shape

None

代表流經邊的張量為任意長度的向量;

shape

[]

代表流經邊的張量為一個标量。

建構資料流圖

with g.as_default():   # 将 Graph對象 設為預設 Graph對象
    with tf.name_scope('variables'):
        # 記錄資料流圖運作次數的 Variable 對象
        # 這是一種常見的範式,在整個API中,這種範式會頻繁出現
        global_step = tf.Variable(0, dtype= tf.float32, trainable= False, name= 'global_step')
        
        # 追蹤該模型的所有輸出随時間的累加和的 Variable 對象
        total_output = tf.Variable(0.0, dtype= tf.float32, trainable= False, name= 'total_output')
        
    with tf.name_scope('transformation'):  # 該模型的核心變換部分
        
        # 獨立的輸入層
        with tf.name_scope('input'):
            # 建立輸出占位符,用于接收任意長度的向量
            a = tf.placeholder(tf.float32, shape= [None], name= 'input_placeholder_a')
            
        # 獨立的中間層
        with tf.name_scope('intermediate_layer'):
            # 對整個向量實施乘法和加法
            b = tf.reduce_prod(a, name= 'prod_b')
            c = tf.reduce_sum(a, name= 'sum_c')
            
        # 獨立的輸出層
        with tf.name_scope('output'):
            output = tf.add(b, c, name= 'output')
        
        # 對變量進行更新
        with tf.name_scope('update'):
            # 用最新的輸出更新Variable對象total_output
            update_total = total_output.assign(output)
            # 将Variable對象global_step增 1 ,隻要資料流圖運作,該操作便需要進行
            increment_step = global_step.assign_add(1)
            
        with tf.name_scope('summaries'):
            avg = tf.div(update_total, tf.cast(increment_step, tf.float32), name= 'average')
            
            # 為輸出節點建立彙總資料
            tf.summary.scalar('Output', output)
            tf.summary.scalar('Sum of outputs over time', update_total)
            tf.summary.scalar('Average of outputs over time', avg)
            
        with tf.name_scope('global_ops'):
            # 初始化Op
            init = tf.global_variables_initializer()
            # 将所有彙總資料合并到一個Op中
            merged_summaries = tf.summary.merge_all()           
INFO:tensorflow:Summary name Sum of outputs over time is illegal; using Sum_of_outputs_over_time instead.
INFO:tensorflow:Summary name Average of outputs over time is illegal; using Average_of_outputs_over_time instead.           

為什麼将

tf.summary.merge_all()

\(Op\) 放在 “\(global\_ops\)” 名稱作用域,而非放在 “\(summaries\)” 作用域?

  • 一般而言,将

    tf.summary.merge_all()

    與其他全局\(Op\)放在一起是最佳做法。我們的資料流圖隻為彙總資料設定了一個環節,但這并不妨礙去想象一個擁有

    Variable

    Op

    和名稱作用域等的不同彙總資料的資料流圖。通過保持

    tf.summary.merge_all()

    的分離,可確定使用者無需記憶放置它的特定“summary” 代碼塊,進而比較容易找到該\(Op\)。

運作資料流圖

sess = tf.Session(graph= g)
# 儲存彙總資料
writer = tf.summary.FileWriter('E:/Graphs/xin_graph', g)
sess.run(init)
def run_graph(input_tensor):
    '''
    運作計算圖
    '''
    feed_dict = {a: input_tensor}
    _, step, summary = sess.run([output, increment_step, merged_summaries],feed_dict= feed_dict)

    writer.add_summary(summary, global_step= step)           
# 用不同的輸入運作該資料流圖
run_graph([2, 8])
run_graph([3, 1, 3, 3])
run_graph([8])
run_graph([1, 2, 3])
run_graph([11, 4])
run_graph([4, 1])
run_graph([7, 3, 1])
run_graph([6, 3])
run_graph([0, 2])
run_graph([4, 5 ,6])

writer.flush()      # 将彙總資料寫入磁盤
writer.close()
sess.close()           

關于Tensorboard

Tensorboard踩坑記:

https://zhuanlan.zhihu.com/p/29284886

探尋有趣之事!

繼續閱讀