हाँ वहाँ है!
क्रेडिट: यह लेकिन जानकारी खोजने के लिए और यह काम कर पाने के मुश्किल था यहाँ सिद्धांतों से एक उदाहरण की प्रतिलिपि बनाने और कोड here और here पाया।
आवश्यकताएँ: शुरू करने से पहले, इसके लिए सफल होने में सक्षम होने के लिए दो आवश्यकताएं हैं। सबसे पहले आपको अपने सक्रियण को numpy arrays पर फ़ंक्शन के रूप में लिखने में सक्षम होना चाहिए। दूसरा, आपको उस कार्य के व्युत्पन्न को या तो टेन्सफोर्लो (आसान) में फ़ंक्शन के रूप में लिखना होगा या सबसे खराब स्थिति परिदृश्य में numpy arrays पर फ़ंक्शन के रूप में लिखना होगा।
लेखन सक्रियण समारोह:
तो चलो उदाहरण के लिए इस समारोह है जो हम एक सक्रियण समारोह का उपयोग करना चाहते हैं करते हैं:
def spiky(x):
r = x % 1
if r <= 0.5:
return r
else:
return 0
कौन सा रूप में देखने के लिए इस प्रकार है:
पहला कदम इसे एक गंदे फ़ंक्शन में बना रहा है, यह आसान है:
import numpy as np
np_spiky = np.vectorize(spiky)
अब हमें इसके व्युत्पन्न लिखना चाहिए।
एक्टिवेशन की ढाल: हमारे मामले में यह आसान है, यह 1 है अगर एक्स आधुनिक 1 < 0.5 और 0 अन्यथा। तो:
def d_spiky(x):
r = x % 1
if r <= 0.5:
return 1
else:
return 0
np_d_spiky = np.vectorize(d_spiky)
अब इसमें से एक टेंसरफ्लो फ़ंक्शन बनाने के कठिन हिस्से के लिए।
एक tensorflow एफसीटी करने के लिए एक numpy एफसीटी बनाना: हम एक tensorflow समारोह में np_d_spiky बनाकर शुरू कर देंगे। वहाँ tensorflow tf.py_func(func, inp, Tout, stateful=stateful, name=name)
[doc] जो एक tensorflow समारोह के लिए किसी भी numpy समारोह बदल देती है में एक समारोह है, तो हम इसका इस्तेमाल कर सकते हैं: tensors की सूची पर
import tensorflow as tf
from tensorflow.python.framework import ops
np_d_spiky_32 = lambda x: np_d_spiky(x).astype(np.float32)
def tf_d_spiky(x,name=None):
with ops.op_scope([x], name, "d_spiky") as name:
y = tf.py_func(np_d_spiky_32,
[x],
[tf.float32],
name=name,
stateful=False)
return y[0]
tf.py_func
में कार्य करता है (और tensors की सूची लौटाता है), इसलिए हम है [x]
(और y[0]
लौटाएं)। stateful
विकल्प tensorflow को बताना है कि फ़ंक्शन हमेशा एक ही इनपुट (स्टेटफुल = झूठी) के लिए एक ही आउटपुट देता है, जिस स्थिति में टेंसफोर्लो बस टेंसफोर्लो ग्राफ कर सकता है, यह हमारा मामला है और शायद अधिकांश स्थितियों में यह मामला होगा।इस बिंदु पर सावधान रहने की एक बात यह है कि numpy float64
का उपयोग किया जाता है लेकिन tensorflow float32
का उपयोग करता है, इसलिए आपको इसे अपने टेंसरफ़्लो फ़ंक्शन में परिवर्तित करने से पहले float32
का उपयोग करने के लिए अपने फ़ंक्शन को कनवर्ट करने की आवश्यकता है अन्यथा tensorflow शिकायत करेगा। यही कारण है कि हमें पहले np_d_spiky_32
बनाने की आवश्यकता है।
ग्रेडियेंट्स के बारे में क्या? केवल उपर्युक्त करने में समस्या यह है कि भले ही हमारे पास tf_d_spiky
है जो np_d_spiky
का टेंसफोर्लो संस्करण है, हम इसे सक्रियण फ़ंक्शन के रूप में उपयोग नहीं कर पाएंगे क्योंकि हम चाहते थे क्योंकि tensorflow को नहीं पता कि ग्रेडियेंट की गणना कैसे करें वह समारोह
हैक ग्रेडिएंट पाने के लिए: के रूप में सूत्रों का कहना है कि ऊपर उल्लेख किया में विस्तार से बताया, वहाँ एक समारोह tf.RegisterGradient
[doc] और tf.Graph.gradient_override_map
[doc] का उपयोग करने का ढ़ाल परिभाषित करने के लिए एक हैक है। harpone से कोड को कॉपी करने हम इसे एक ही समय में ढाल को परिभाषित करने के लिए tf.py_func
समारोह को संशोधित कर सकते हैं:
def py_func(func, inp, Tout, stateful=True, name=None, grad=None):
# Need to generate a unique name to avoid duplicates:
rnd_name = 'PyFuncGrad' + str(np.random.randint(0, 1E+8))
tf.RegisterGradient(rnd_name)(grad) # see _MySquareGrad for grad example
g = tf.get_default_graph()
with g.gradient_override_map({"PyFunc": rnd_name}):
return tf.py_func(func, inp, Tout, stateful=stateful, name=name)
अब हम लगभग कर लिया है, केवल एक चीज स्नातक समारोह हम ऊपर को पास किए जाने कि है py_func फ़ंक्शन को एक विशेष रूप लेना आवश्यक है। संचालन से पहले इसे एक ऑपरेशन, और पिछले ग्रेडियेंट में लेना होगा और ऑपरेशन के बाद पिछड़े ग्रेडियेंट को प्रसारित करना होगा।
ढाल फंक्शन: यही वजह है कि x = op.inputs[0]
def spikygrad(op, grad):
x = op.inputs[0]
n_gr = tf_d_spiky(x)
return grad * n_gr
सक्रियण समारोह केवल एक इनपुट है,: इसलिए हमारे काँटेदार सक्रियण समारोह के लिए है कि हम इसे कैसे करना होगा। यदि ऑपरेशन में कई इनपुट थे, तो हमें प्रत्येक इनपुट के लिए एक ट्यूपल, एक ढाल वापस करने की आवश्यकता होगी। उदाहरण के लिए यदि ऑपरेशन a-b
a
के संबंध में ढाल +1
है और b
-1
के संबंध में है तो हमारे पास return +1*grad,-1*grad
होगा। ध्यान दें कि हमें इनपुट के tensorflow कार्यों को वापस करने की आवश्यकता है, यही कारण है कि tf_d_spiky
, np_d_spiky
की आवश्यकता नहीं होती क्योंकि यह टेन्सफोर्लो टेंसर पर कार्य नहीं कर सकता है।
def spikygrad2(op, grad):
x = op.inputs[0]
r = tf.mod(x,1)
n_gr = tf.to_float(tf.less_equal(r, 0.5))
return grad * n_gr
यह सब एक साथ संयोजन:: वैकल्पिक रूप से हम व्युत्पन्न का उपयोग कर tensorflow कार्यों लिख सकता अब हम
np_spiky_32 = lambda x: np_spiky(x).astype(np.float32)
def tf_spiky(x, name=None):
with ops.op_scope([x], name, "spiky") as name:
y = py_func(np_spiky_32,
[x],
[tf.float32],
name=name,
grad=spikygrad) # <-- here's the call to the gradient
return y[0]
और: अब जब हम सभी टुकड़ों है, हम उन सब को एक साथ गठजोड़ कर सकते हैं कार्य पूर्ण। और हम इसका परीक्षण कर सकते हैं।
टेस्ट:
with tf.Session() as sess:
x = tf.constant([0.2,0.7,1.2,1.7])
y = tf_spiky(x)
tf.initialize_all_variables().run()
print(x.eval(), y.eval(), tf.gradients(y, [x])[0].eval())
[0.2 ०.६९९९९९९९ १.२,००,००,००५ १.७,००,००,००५] [0.2 0. .२,००,००,००५ 0.] [1. 0. 1. 0.]
सफलता!
यह भी देखें [आप केरास के साथ एक कस्टम सक्रियण फ़ंक्शन कैसे बनाते हैं?] (Http://stackoverflow.com/q/43915482/562769) –
किसी भी सॉफ़्टवेयर के साथ पूर्ण स्वतंत्रता रखना मुश्किल है, लेकिन यदि आप हमें देते हैं एक विचार क्या सक्रियण समारोह (फ़ंक्शन परिवार) जिसे आप बनाने की कोशिश कर रहे हैं, कोई भी आपकी मदद करने में सक्षम हो सकता है। – user1700890