2016-07-13 25 views
7

Bu Paper'da tanıtılan ve bu recipe numaralı belgede açıklanan "Güdümlü geri yayılım" tekniğini TensorFlow uygulamasında uygulamak istiyorum. Hesapsal olarak, yani girdi wrt değerinin gradyanını hesapladığımda hesaplama anlamındadır. NN'nin çıktısı, 'a, her RELU birimi'da hesaplanan degradeleri değiştireceğim. Somut olarak, bu tekniklerin çalışması için, bu birimler üzerindeki geri yayılan sinyalin sıfır olarak eşleştirilmesi gerekir. Başka bir deyişle, negatif olan RELU'ların kısmi türevi göz ardı edilmelidir.Güdümlü Geri yayılımı TensorFlow

Bu gradyan hesaplamalarını yalnızca test örneklerine uygulamakla ilgilendim, yani, modelin parametrelerini güncellemek istemiyorum - nasıl yapmalıyım?

  1. Kullanım tf.py_funcg aracılığıyla o degrade operasyon yeniden tanımlamak için daha sonra uygun olan bir relu, benim basit numpy versiyonunu sarmak için:

    I (başarısız) şimdiye kadar iki şey denedik .gradient_override_map içerik yöneticisi.

  2. BackProp'un ileri/geri değerlerini toplayın ve Relus'tan kaynaklanan eşikleri uygulayın.

Her iki yaklaşımda da başarısız oldum, çünkü şu anda sahip olmadığım TF'nin dahili bilgisine ihtiyaç duyuyorlar.

Başka herhangi bir yol önerebilir veya kodu çizebilir mi?

Çok teşekkürler.

cevap

5

tf.gradients, bu amaç için kullanılabilecek grad_ys parametresine sahiptir. aşağıdaki gibi ağ sadece bir relu katmanını içerdiğini varsayalım:

before_relu = f1(inputs, params) 
after_relu = tf.nn.relu(before_relu) 
loss = f2(after_relu, params, targets) 

Öncelikle after_relu kadar türevini hesaplamak. Aşağı göndermek

Dafter_relu = tf.gradients(loss, after_relu)[0] 

Sonra eşik senin gradyanları.

Dafter_relu_thresholded = tf.select(Dafter_relu < 0.0, 0.0, Dafter_relu) 

hesaplayın gerçek geçişlerini params için w.r.t.

Dparams = tf.gradients(after_relu, params, grad_ys=Dafter_relu_thresholded) 

Kolayca birçok relu katmanlarla bir ağ için bu aynı yöntemi uzatabilir.

+0

Merhaba Kaveman, hızlı cevap için çok teşekkürler. Son tf.gradients çağrısında, ilk argüman olarak Dafter_relu kasıtlı olarak geçiyorsunuz? – Peter

+1

Ayrıca, hala kafam karıştı. RELU öğelerine sahip olan herhangi bir NN için çalışacak şekilde birçok katmana sahip bir ağ üzerinde bunu nasıl genelleştirebilirsiniz. Bu bölüm için, her RELU elemanının tüm giriş/çıkışını ve daha önce açıklanan mantığınızı 'zincirlemeniz' izlemeniz gerekmiyor mu? Teşekkürler. – Peter

+0

@Peter, üzgünüm, bu bir yazım hatasıydı. Tf.gradients’a yapılan ikinci çağrı 'after_relu' w.r.t. 'Params'. – keveman

5

Daha iyi bir çözüm (yaklaşımınız 1) ops.RegisterGradient ve tf.Graph.gradient_override_map ile. Birlikte önceden tanımlanmış bir Op için gradyan hesaplamayı geçersiz kılarlar, örn. Sadece python kodunu kullanarak gradient_override_map bağlamında Relu.https://gist.github.com/falcondai/561d5eec7fed9ebf48751d124a77b087

Güncelleme:

@ops.RegisterGradient("GuidedRelu") 
def _GuidedReluGrad(op, grad): 
    return tf.where(0. < grad, gen_nn_ops._relu_grad(grad, op.outputs[0]), tf.zeros(grad.get_shape())) 

... 
with g.gradient_override_map({'Relu': 'GuidedRelu'}): 
    y = tf.nn.relu(x) 

burada güdümlü relu tam uygulanmasının örneği sunulmuştur Tensorflow içinde> = 1.0, tf.selecttf.where yeniden adlandırılır. Snippet'i buna göre güncelledim. (Bu konuya dikkatimi çekmek için teşekkür ederim :)

+2

"gradient_override_map" içeriğindeki relu op * inside * öğesini içeren grafik yapısını sarmanız gerektiğini unutmayın. – Falcon

+1

Teşekkür ederim, @Falcon, bu iyi çalışıyor. Ben de TF sürüm 1.2 kullanıyorum tf.where tarafından tf.where yerine vardı. – sbond

+0

@sbond Güncelleme için teşekkürler. Yorumunuzu dahil etmek için yayınımı düzenledim. – Falcon