2017-07-17 48 views
1

現在我有一個模型配置爲使用feed_dict輸入它的輸入。代碼看起來像這樣:在feed_dict和隊列之間輕鬆切換以輸入到TensorFlow模型

# model.py 
class MyModel(object): 
    def __init__(self, hyperparams): 
    self.build_model(hyperparams) 

    def build_model(self, hps): 
    self.input_data = tf.placeholder(dtype=tf.float32, shape=[hps.batch_size, hps.nfeats]) 
    self.labels = tf.placeholder(dtype=tf.float32, shape=[hps.batch_size]) 
    # Define hidden layers, loss, training step, etc. 

# train.py 
model = MyModel(hps) 
for _ in range(100): 
    x, y = some_python_function() # Read a batch from disk, preprocess 
    sess.run(model.train_step, feed_dict={model.input_data: x, model.labels: y}) 

由於性能原因,我想切換到使用隊列進行培訓。但我想保持使用feed_dict的能力,例如進行推理或測試。

有沒有一個優雅的方式來做到這一點?我想要做的是,在使用隊列時,將我的隊列的出隊操作返回的張量替換爲佔位符變量。我認爲tf.assign會做到這一點的方式,即:

single_x, single_y = tf.parse_single_example(...) 
x, y = tf.train.batch([single_x, single_y], batch_size) 
model = MyModel(hps) 
sess.run([tf.assign(model.input_data, x), tf.assign(model.labels, y)]) 
for _ in range(100): 
    sess.run(model.train_step) 

但是這引起了AttributeError: 'Tensor' object has no attribute 'assign'tf.assign的API文檔將第一個參數描述爲:「可變的Tensor。應該來自Variable節點,可能未初始化。」這是否意味着我的佔位符不可變?我可以讓他們如此嗎?還是我以錯誤的方式接近這個?

最小可運行示例here

回答

0

如果你能控制圖表並知道你想要什麼,你可以在你的輸入上使用開關。例如,

x_plh = tf.placeholder(tf.float32, myshape) 
x_dsk = my_input_from_disk() 
use_dsk = tf.placeholder(tf.bool,()) 
x = tf.cond(use_dsk, lambda: x_dsk, lambda: x_plh) 

如果你想有一個更靈活的解決方案,並採取了幾分先鋒路線,你可以有一個去tensorflow的的Dataset API。花時間閱讀文檔,這是一個很好的閱讀。一個Iterator可以有幾個初始化程序,使用不同的Dataset s,這可能適合您的情況。

2

你可以分開Variables的創建和Operations通過:

  • 添加build_variables方法叫你Model類的實例,
  • 改變build_model方法的接口,因此它會將您的xy張量作爲參數,所以它建立在它們的基礎上的模型operations

這樣你就可以重用模型的變量和常量。缺點是這些操作將被複製爲placeholder版本和任何其他版本。

import tensorflow as tf 
import numpy as np 

BATCH_SIZE = 2 

class Model(object): 

    def __init__(self): 
    self.build_variables() 

    def build_variables(self): 
    self.w = tf.Variable(tf.random_normal([3, 1])) 

    def build_model(self, x, y): 
    self.x = x 
    self.y = y 
    self.output = tf.matmul(self.x, self.w) 
    self.loss = tf.losses.absolute_difference(self.y, self.output) 


model = Model() 
sess = tf.InteractiveSession() 
sess.run(tf.global_variables_initializer()) 

def placeholder_run(): 
    x = tf.placeholder(dtype=tf.float32, shape=[BATCH_SIZE, 3]) 
    y = tf.placeholder(dtype=tf.float32, shape=[BATCH_SIZE, 1]) 
    model.build_model(x, y) 

    for i in range(3): 
    x = np.random.rand(BATCH_SIZE, 3) 
    y = x.sum(axis=1, keepdims=True) 
    loss = sess.run(model.loss, feed_dict={model.x:x, model.y:y}) 
    print(loss) 

def nonph_run(): 
    x = tf.random_normal([BATCH_SIZE, 3]) 
    y = tf.reduce_sum(x, axis=1, keep_dims=True) 
    model.build_model(x, y) 
    for i in range(3): 
    loss = sess.run(model.loss) 
    print(loss) 

if __name__ == '__main__': 
    # Works 
    placeholder_run() 
    # Doesn't fail 
    nonph_run() 
相關問題