2016-08-17 2 views
11

제 문제는 각 교육 단계의 데이터에서 1 개의 예를 사용하여 GD를 실행해야한다는 것입니다. session.run()이 오버 헤드를 가지고 있으므로 모델을 훈련하기에는 너무 길다는 것이 알려진 문제입니다. 오버 헤드를 피하기 위해 while_loop 및 train 모델을 하나의 run() 호출로 모든 데이터에 사용하려고했습니다. 그러나 접근 방식은 효과가 없으며 train_op은 실행하지 않습니다. 아래에 나와있는 간단한 예는 다음과 같습니다.Tensorflow while_loop for training

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() 

내가 잘못하고있는 것은 무엇입니까? 또는 너무 비싼 오버 헤드로이 문제의 또 다른 해결책이 있습니까?

감사합니다! 판독 입력 그라데이션 계산하고 minimize() 호가 모두 정의되어 있기 때문에 모델이 훈련 나타나지

답변

18

이유는 외부 (따라서, 플로우 조건, 전에 단위) tf.while_loop() 본문. 즉, 모델의 이러한 모든 부분은 루프가 실행되기 전에 한 번만 실행되며 루프 자체는 아무런 영향을 미치지 않습니다.

약간의 리팩토링 — 문제 루프 내부에 — 수정을 dequeue() 운영, 그라데이션 계산 및 minimize() 전화를 이동하고 프로그램이 훈련 할 수 있도록합니다 :

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 : 여기이입니다 전체 프로그램은 질문의 코드를 기반으로 while 루프를 실행합니다.

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

외부에 ** w ** 및 ** b **를 정의해야합니까? 그래서 나는 그런 것을 시도하고 있습니다. (그리고 지금 당신이 제공하는 것을 시도합니다.)하지만 오류가 있습니다. * GradientDescent/update_while/w/ApplyGradientDescent는 같은 프레임에서 가져야 만합니다. * –

+0

전체 프로그램을 추가했습니다. TensorFlow 0.10rc0와 함께 뛰었습니다. (업그레이드가 필요할 수도 있는데, 마지막 몇 가지 릴리스에서 수정 된'tf.while_loop()'구현에는 여러 가지 버그가있었습니다.) – mrry

+0

예, 0.9에서 시작했습니다. 업데이트 후 고맙습니다! 새로운 옵티마이 저는 모든 단계를 생성하는 것처럼 보이고 Ftrl 옵티 마이저 (업데이트 된 슬롯이 있음)를 사용하려면 어떻게해야합니까? 교육 과정에서 하나의 옵티 마이저처럼 작동합니까? –