मैं एक तंत्रिका नेटवर्क को प्रशिक्षित कर रहा हूं जब फॉरवर्ड पास में, बेतरतीब ढंग से आधे समय में एक गैर-अलग-अलग सक्रियण का उपयोग किया जाता है जो सक्रियण को या तो 0 या 1 (बाइनरी) में बदल देता है, और दूसरा आधा यह सिग्मॉइड के समान एक अलग-अलग फ़ंक्शन का उपयोग करता है (संतृप्त) -सिग्मॉइड सटीक होना) हालांकि, बैकवर्ड पास में, हम डिफरेंशियल फंक्शन के संबंध में ग्रेडिएंट का उपयोग करते हैं, भले ही हमने फॉरवर्ड पास के लिए नॉन-डिफरेंशियल असतत का उपयोग किया हो। मेरे पास अब तक का कोड है:

diff_active = tf.math.maximum(sat_sigmoid_term1(feature), sat_sigmoid_term2(feature))
binary_masks = diff_active 
rand_cond = tf.random.uniform([1,])
cond = tf.constant(rand_cond, shape=[1,])
if cond <0.5:
        with tf.GradientTape() as tape:
            non_diff_active = tf.grad_pass_through(tf.keras.layers.Lambda(lambda x: tf.where(tf.math.greater(x,0), x, tf.zeros_like(x))))(feature)
            grads = tape.gradient(non_diff_active , feature)
            binary_masks = non_diff_active  
tf.math.multiply(binary_masks, feature)  

मेरा अंतर्ज्ञान यह है कि इस तरह, अलग-अलग सक्रियण हमेशा लागू होता है (और उम्मीद है कि इसका ढाल हमेशा बीएसीएल-प्रोप में शामिल होता है) और tf.grad_pass_through() के साथ मैं पहचान के साथ इसके बैक-प्रचार को प्रतिस्थापित करते हुए गैर-भिन्न सक्रियण लागू कर सकता हूं आव्यूह। हालांकि, मुझे यकीन नहीं है कि tf.grad_pass_through() का मेरा उपयोग या मेरे यादृच्छिक चर की जिस तरह से मैं स्थिति सही है और यदि व्यवहार इरादा के अनुसार है?

3
TheEngineer 15 जून 2020, 04:03

1 उत्तर

सबसे बढ़िया उत्तर

इसके लिए आप tf.custom_gradient का इस्तेमाल कर सकते हैं:

import tensorflow as tf

@tf.function
def sigmoid_grad(x):
    return tf.gradients(tf.math.sigmoid(x), x)[0]

@tf.custom_gradient
def sigmoid_or_bin(x, rand):
    rand = tf.convert_to_tensor(rand)
    out = tf.cond(rand > 0.5,
                  lambda: tf.math.sigmoid(x),
                  lambda: tf.dtypes.cast(x > 0, x.dtype))
    return out, lambda y: (y * sigmoid_grad(x), None)

# Test
tf.random.set_seed(0)
x = tf.random.uniform([4], -1, 1)
tf.print(x)
# [-0.416049719 -0.586867094 0.0707814693 0.122514963]
with tf.GradientTape() as t:
    t.watch(x)
    y = tf.math.sigmoid(x)
tf.print(y)
# [0.397462428 0.357354015 0.517688 0.530590475]
tf.print(t.gradient(y, x))
# [0.239486054 0.229652107 0.249687135 0.249064222]
with tf.GradientTape() as t:
    t.watch(x)
    y = sigmoid_or_bin(x, 0.2)
tf.print(y)
# [0 0 1 1]
tf.print(t.gradient(y, x))
# [0.239486054 0.229652107 0.249687135 0.249064222]
with tf.GradientTape() as t:
    t.watch(x)
    y = sigmoid_or_bin(x, 0.8)
tf.print(y)
# [0.397462428 0.357354015 0.517688 0.530590475]
tf.print(t.gradient(y, x))
# [0.239486054 0.229652107 0.249687135 0.249064222]
0
jdehesa 18 जून 2020, 17:47