2016-03-27 14 views
7

TensorFlow ile basit bir çok katmanlı algılayıcı yapıyorum ve sinir ağının girişlerindeki kaymanın degradelerini (veya hata sinyalini) almam gerekiyor.TensorFlow: girişlerde degradeler alınırken yavaş performans

İşte çalışır benim kod verilmiştir:

cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(self.network, self.y)) 
optimizer = tf.train.AdagradOptimizer(learning_rate=nn_learning_rate).minimize(cost) 
... 
for i in range(epochs): 
    .... 
    for batch in batches: 
     ... 
     sess.run(optimizer, feed_dict=feed_dict) 
     grads_wrt_input = sess.run(tf.gradients(cost, self.x), feed_dict=feed_dict)[0] 

son satırı (grads_wrt_input...) olmadan

(eğitim döngü içerecek şekilde düzenlenmiş), bu gerçekten hızlı bir CUDA makinede çalışır. Ancak, tf.gradients(), performansı on kat ya da daha fazla büyük oranda azaltır.

Geri tepme algoritmasında düğümlerdeki hata sinyallerinin ara değerler olarak hesaplandığını hatırlıyorum ve bunu başarıyla DeepLearning4j Java kütüphanesini kullanarak yaptım. Ayrıca, bu zaten optimizer tarafından yapılan hesaplama grafiği için hafif bir değişiklik olacağını izlenim altındaydı.

Bu nasıl daha hızlı yapılabilir veya kayıpların gradyanlarını hesaplamak için başka bir yol var mıdır? girişler?

+0

Gerçekten de eğitim döngüsünde tf.gradients() 'i mi çağırıyorsunuz? Eğer öyleyse, ek yükü her aradığınızda arka plan grafiği oluşturduğundan şüpheliyim? – mrry

+0

Eğitim döngü kodunu netlik için ekledim; evet eğitim döngüsünde tf.gradients() işlevini arıyorum. Program, aşamalı olarak yavaşlar. Bu binanın önünü önlemek için ne yapmalıyım? –

+0

Degradeler için hesaplama grafiğini bir kez oluşturmak için döngü dışındaki tf.gradients öğesini çağırın. Ayrıca compute_gradients –

cevap

10

tf.gradients() işlevi, her çağrıldığında yeni bir arka çoğaltma grafiği oluşturur, bu nedenle yavaşlamanın nedeni, TensorFlow'un, döngüdeki her yinelemede yeni bir grafiği ayrıştırması gerektiğidir. (Bu şaşırtıcı derecede pahalı olabilir: TensorFlow şu anki sürümü aynı grafiktir kez çok sayıda yürütülmesi için optimize edilmiştir.)

Neyse çözelti kolaydır: döngü dışında, bir kez gradyanlarını hesaplamak. aşağıdaki gibi kodunuzu yeniden yapılandırabilir:, performans için, ben de iki sess.run() aramaları kombine

cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(self.network, self.y)) 
optimizer = tf.train.AdagradOptimizer(learning_rate=nn_learning_rate).minimize(cost) 
grads_wrt_input_tensor = tf.gradients(cost, self.x)[0] 
# ... 
for i in range(epochs): 
    # ... 
    for batch in batches: 
     # ... 
     _, grads_wrt_input = sess.run([optimizer, grads_wrt_input_tensor], 
             feed_dict=feed_dict) 

Not. Bu, ileri yayılımın ve geri yayılmanın çoğunun yeniden kullanılmasını sağlar. As


bir bu eğitim döngü başlamadan önce tf.get_default_graph().finalize() çağırmak gibi bir kenara, bir ucu performans hataları bulmak için. Bu, herhangi bir düğümün grafiğe istemeyerek eklenmesi durumunda, bu hataların nedenini izlemeyi kolaylaştıran bir istisna oluşturacaktır.

+0

kullanarak iyileştirici için yapılan degrade grafiğini yeniden kullanabilirsiniz. Bu işe yaradı, teşekkür ederim! Programım şimdi hızlı. BTW, 'grads_wrt_input_tensor' listesinde 'session.run()' listesindeki grads_wrt_input' olduğunu düşünüyorum. –

+0

İyi bir nokta: sadece bir düzeltmeyle düzenlenmiş! – mrry