2016-08-17 51 views
11

Trong vấn đề của tôi, tôi cần chạy GD với 1 ví dụ từ dữ liệu trên mỗi bước đào tạo. Đó là vấn đề được biết rằng session.run() có chi phí cao và do đó quá dài để đào tạo mô hình. Để tránh phải trả phí, tôi đã cố gắng sử dụng mô hình while_loop và đào tạo trên tất cả dữ liệu bằng một cuộc gọi run(). Nhưng phương pháp tiếp cận không hoạt động và train_op không thực hiện ngay cả những cái. Dưới đây là ví dụ đơn giản về những gì tôi đang làm:Tensorflow while_loop để đào tạo

data = [k*1. for k in range(10)] 
tf.reset_default_graph() 

i = tf.Variable(0, name='loop_i') 
q_x = tf.FIFOQueue(100000, tf.float32) 
q_y = tf.FIFOQueue(100000, tf.float32) 

x = q_x.dequeue() 
y = q_y.dequeue() 
w = tf.Variable(0.) 
b = tf.Variable(0.) 
loss = (tf.add(tf.mul(x, w), b) - y)**2 

gs = tf.Variable(0) 

train_op = tf.train.GradientDescentOptimizer(0.05).minimize(loss, global_step=gs) 

s = tf.Session() 
s.run(tf.initialize_all_variables()) 

def cond(i): 
    return i < 10 

def body(i): 
    return tf.tuple([tf.add(i, 1)], control_inputs=[train_op]) 


loop = tf.while_loop(cond, body, [i]) 

for _ in range(1): 
    s.run(q_x.enqueue_many((data,))) 
    s.run(q_y.enqueue_many((data,))) 

s.run(loop) 
s.close() 

Tôi đang làm gì sai? Hoặc có một giải pháp của vấn đề này với chi phí quá đắt?

Cảm ơn!

Trả lời

18

Lý do mô hình không xuất hiện để đào tạo là do đầu vào đọc sách, tính toán gradient, và minimize() cuộc gọi đều được xác định ngoài (và do đó, trong điều kiện dataflow, trước) cơ thể của tf.while_loop(). Điều này có nghĩa là tất cả các phần của mô hình này chỉ chạy một lần, trước khi vòng lặp thực thi và chính vòng lặp đó không có hiệu lực.

Một refactoring nhẹ — để di chuyển dequeue() hoạt động, tính toán gradient, và minimize() gọi bên trong vòng lặp — sửa chữa các vấn đề và cho phép chương trình của bạn để đào tạo:

optimizer = tf.train.GradientDescentOptimizer(0.05) 

def cond(i): 
    return i < 10 

def body(i): 
    # Dequeue a new example each iteration. 
    x = q_x.dequeue() 
    y = q_y.dequeue() 

    # Compute the loss and gradient update based on the current example. 
    loss = (tf.add(tf.mul(x, w), b) - y)**2 
    train_op = optimizer.minimize(loss, global_step=gs) 

    # Ensure that the update is applied before continuing. 
    return tf.tuple([tf.add(i, 1)], control_inputs=[train_op]) 

loop = tf.while_loop(cond, body, [i]) 

UPDATE: Dưới đây là một chương trình hoàn chỉnh thực thi vòng lặp while, dựa trên mã trong câu hỏi của bạn:

import tensorflow as tf 

# Define a single queue with two components to store the input data. 
q_data = tf.FIFOQueue(100000, [tf.float32, tf.float32]) 

# We will use these placeholders to enqueue input data. 
placeholder_x = tf.placeholder(tf.float32, shape=[None]) 
placeholder_y = tf.placeholder(tf.float32, shape=[None]) 
enqueue_data_op = q_data.enqueue_many([placeholder_x, placeholder_y]) 

gs = tf.Variable(0) 
w = tf.Variable(0.) 
b = tf.Variable(0.) 
optimizer = tf.train.GradientDescentOptimizer(0.05) 

# Construct the while loop. 
def cond(i): 
    return i < 10 

def body(i): 
    # Dequeue a single new example each iteration. 
    x, y = q_data.dequeue() 
    # Compute the loss and gradient update based on the current example. 
    loss = (tf.add(tf.multiply(x, w), b) - y) ** 2 
    train_op = optimizer.minimize(loss, global_step=gs) 
    # Ensure that the update is applied before continuing. 
    with tf.control_dependencies([train_op]): 
     return i + 1 

loop = tf.while_loop(cond, body, [tf.constant(0)]) 

data = [k * 1. for k in range(10)] 

with tf.Session() as sess: 
    sess.run(tf.global_variables_initializer()) 
    for _ in range(1): 
     # NOTE: Constructing the enqueue op ahead of time avoids adding 
     # (potentially many) copies of `data` to the graph. 
     sess.run(enqueue_data_op, 
       feed_dict={placeholder_x: data, placeholder_y: data}) 
    print (sess.run([gs, w, b])) # Prints before-loop values. 
    sess.run(loop) 
    print (sess.run([gs, w, b])) # Prints after-loop values. 
+1

Tôi có nên xác định ** w ** và ** b ** bên ngoài không? Vì vậy, tôi đang cố gắng một cái gì đó như thế (và bây giờ tôi cố gắng chính xác những gì bạn cung cấp) nhưng tôi đã nhận lỗi * Tất cả các đầu vào cho nút trong khi/GradientDescent/update_while/w/ApplyGradientDescent phải từ cùng một khung. * –

+0

Tôi đã thêm toàn bộ chương trình mà tôi đã chạy với TensorFlow 0.10rc0. (Bạn có thể cần phải nâng cấp, đã có nhiều lỗi khác nhau trong việc thực hiện 'tf.while_loop()' đã được sửa chữa trong vài phiên bản trước. – mrry

+0

Vâng, tôi đã khởi chạy nó trên 0.9, cảm ơn bạn, sau khi cập nhật nó hoạt động! một câu hỏi nữa về giải pháp của bạn - nó trông giống như trình tối ưu hóa mới tạo ra từng bước, và nếu tôi muốn sử dụng trình tối ưu hóa Ftrl (có một số khe được cập nhật) thì nó sẽ hoạt động như một trình tối ưu hóa cùng với quá trình đào tạo? –

Các vấn đề liên quan