2017-07-28 190 views
0

我想在函數之間傳遞一個可變值用於調試目的。共享變量不起作用,因爲他們的任務需要調用.eval()sess.run(),而我位於我的程序和輸出值的深處,使用tf.Print()Tensorflow:共享可變張量

假設我要輸出其梯度的時刻計算層的數量,所以我試圖用張量做到這一點:

# initialize shared tensor somewhere outside 
LevelCounter = tf.constant(5, name ="sharedtensor", dtype=tf.int32) 

#function that updates shared tensor value  
def process_gradient_layer_counter(): # show current layer 
    #access shared tensor 
    current_layer = tf.get_default_graph().get_tensor_by_name("sharedtensor:0") 
    #modify it's value 
    current_layer -= 1 

    # My attempt: save it again using the same name. Didn't work 
    current_layer = tf.identity(current_layer, name ="sharedtensor") 

    return current_layer 

# compute gradient 
@tf.RegisterGradient('MyGrad') 
def mygrad(op, grad): 
    x = op.inputs[0] 
    # ... compute grad_new, which I want to debug ... # 

    #Display layer counter 
    grad_new = tf.Print(grad_new, [process_gradient_layer_counter()], message = 'debug: ') 

    return grad_new 

但不幸的是,這段代碼的輸出始終4.我應該怎麼如何在不破壞工作流程的情況下在不同功能之間共享可變值?

回答

1

要理解發生了什麼,請考慮創建的計算圖。每次調用mygrad()時,都會創建tf.identity(sharedtensor-1)節點。你有一堆節點正在進行相同的計算,所以你看到打印的結果並不奇怪。

通過控制依賴性強制assign_add可能具有可變的內部狀態,但它不直觀且容易出錯。更好的方法可能是將process_gradient_layer_counter替換爲tf.py_func,它更新全局Python變量

+0

謝謝!然而,py_func實際上殲滅了我的GPU,或者至少顯着減慢了速度。梯度絕對是按順序調用的,我也注意到張量名稱是「sharedtensor:0」。那麼也許我可以每次創建一個新節點並從這些節點訪問最後一個節點?一些內存泄漏是可以接受的調試... – Slowpoke

+0

如果沒有其他的方式,那麼我會去與CPU和pyfunc解決方案... – Slowpoke

+1

,而不是添加到'sharedtensor'你可以添加到一些全球性的python變量包含最後另外 –