2016-11-17 104 views
1

我試圖在圖中使用佔位符作爲變量(所以我可以稍後優化與它有關的東西),但我不知道最好的方法來做到這一點。我已經試過這樣: x = tf.placeholder(tf.float32, shape = [None,1]) x_as_variable = tf.Variable(x, validate_shape = False) 使用佔位符作爲tensorflow變量(越來越錯誤!)

,但每次我建立我的圖表中,我得到一個錯誤,當我嘗試添加自己的損失函數: train = tf.train.AdamOptimizer().minimize(MSEloss)

的錯誤是: ValueError異常:as_list()不定義在一個未知的TensorShape上。

即使你完全不熟悉這個錯誤,如果你可以指導我如何構建一個佔位符值的複製變量,我將非常感激。 謝謝!

+0

你能粘貼你的完整堆棧跟蹤嗎? – yuefengz

+0

當然,這裏是一個鏈接http://pastebin.com/h1GENEsq –

+0

好像我無法對非靜態大小的變量進行優化 –

回答

2

正如你已經注意到,TensorFlow優化(即tf.train.Optimizer子類)上tf.Variable對象進行操作,因爲他們需要能夠爲新值分配給這些對象,並在TensorFlow唯一變量支持分配運算。如果您使用tf.placeholder(),則無需更新,因爲佔位符的值在每個步驟中都是不可變的。

那麼如何優化一個fed-in值?我能想到的兩個選項:

  1. 相反餵養tf.placeholder(),你可以先指定一個饋入的值的變量,然後針對其優化:

    var = tf.Variable(...) 
    set_var_placeholder = tf.placeholder(tf.float32, ...) 
    set_var_op = var.assign(set_var_placeholder) 
    # ... 
    train_op = tf.train.AdamOptimizer(...).minimize(mse_loss, var_list=[var, ...]) 
    
    # ... 
    initial_val = ... # A NumPy array. 
    sess.run(set_var_op, feed_dict={set_var_placeholder: initial_val}) 
    sess.run(train_op) 
    updated_val = sess.run(var) 
    
  2. 你可以使用底層tf.gradients()函數可以在單個步驟中獲取相對於佔位符的損失梯度。然後,您可以使用梯度的Python:

    var = tf.placeholder(tf.float32, ...) 
    # ... 
    mse_loss = ... 
    var_grad, = tf.gradients(loss, [var]) 
    
    var_grad_val = sess.run(var_grad, feed_dict={var: ...}) 
    

PS。您的問題中定義tf.Variable(tf.placeholder(...), ...)的代碼只是定義了一個變量,其初始值由佔位符提供。這可能不是你想要的,因爲優化器創建的訓練只會使用分配給該變量的值,並忽略提供給佔位符的任何內容(在初始化步驟之後)。

+0

對於1),當直接將佔位符提供給變量時,不會自動添加賦值操作嗎? https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/ops/variables.py#L358 – yuefengz

+0

分配操作將被添加,是的,但你必須記得運行'var.initializer '用飼料字典。它可以工作,但選項2可能更好......特別是如果形狀可以改變。 – mrry

+0

仍然與1相同的錯誤 –