स्वचालित अवकलन

गणित और कंप्यूटर बीजगणित में, स्वचालित अवकलन (स्व-अवकलन, ऑटोडिफ़, या एआडी), जिसे कलनविधीय अवकलन तथा अभिकलनीय अवकलन भी कहा जाता है, और यह कंप्यूटर प्रोग्राम द्वारा निर्दिष्ट फलन के आंशिक अवकलज का मूल्यांकन करने के लिए तकनीकों का एक समुच्चय है।

स्वचालित अवकलन इस तथ्य का फायदा उठाता है कि प्रत्येक कंप्यूटर प्रोग्राम, चाहे कितना भी जटिल क्यों न हो, प्राथमिक अंकगणितीय संचालन (जोड़, घटाव, गुणा, भाग, आदि) और प्राथमिक फलनो (ऍक्स्प, लॉग, साइन, कॉस, आदि) के अनुक्रम को निष्पादित करता है। इन परिचालनों में श्रृंखला नियम को बार-बार लागू करने से, यादृच्छिक रूप से क्रम के आंशिक अवकलज की गणना स्वचालित रूप से, सटीकता से काम करने के लिए की जा सकती है, और मूल प्रोग्राम की तुलना में अधिक अंकगणितीय संचालन के एक छोटे स्थिर कारक का उपयोग किया जा सकता है।

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

समग्र फलनों के आंशिक अवकलजों का श्रृंखला नियम
स्वचालित अवकलन के लिए मूल, संयुक्त फलनो के आंशिक अवकलज के श्रृंखला नियम द्वारा प्रदान किए गए अंतर का अपघटन है। सरल संयोजन$$\begin{align} y &= f(g(h(x))) = f(g(h(w_0))) = f(g(w_1)) = f(w_2) = w_3 \\ w_0 &= x \\ w_1 &= h(w_0) \\ w_2 &= g(w_1) \\ w_3 &= f(w_2) = y \end{align}$$के लिए श्रृंखला नियम $$\frac{\partial y}{\partial x} = \frac{\partial y}{\partial w_2} \frac{\partial w_2}{\partial w_1} \frac{\partial w_1}{\partial x} = \frac{\partial f(w_2)}{\partial w_2} \frac{\partial g(w_1)}{\partial w_1} \frac{\partial h(w_0)}{\partial x}$$देता है

दो प्रकार के स्वचालित अवकलन
आमतौर पर, स्वचालित अवकलन के दो अलग-अलग तरीके प्रस्तुत किए जाते हैं। अग्रगामी संचयन निर्दिष्ट करता है कि कोई व्यक्ति श्रृंखला नियम को अंदर से (अर्थात, पहले $$\partial w_1/ \partial x$$ की गणना करें और फिर  $$\partial w_2/\partial w_1$$ की तथा अंत में  $$\partial y/\partial w_2$$ की गणना करें) बाहर तक चंक्रमण करता है, जबकि उत्क्रम संचयन में बाहर से अंदर (पहले  $$\partial y/\partial w_2$$ की गणना करें और फिर $$\partial w_2/\partial w_1$$ की और अंत में  $$\partial w_1/\partial x$$की गणना करें) तक चंक्रमण करता है।
 * अग्रगामी संचयन (जिसे समानयन, अग्रगामी मोड या स्पर्शी मोड भी कहा जाता है)
 * उत्क्रम संचयन (जिसे अधोशीर्ष, उत्क्रम मोड या सहखंडज मोड भी कहा जाता है)
 * अग्रगामी संचयन पुनरावर्ती संबंध की गणना करता है, $$\frac{\partial w_i}{\partial x} = \frac{\partial w_i}{\partial w_{i-1}} \frac{\partial w_{i-1}}{\partial x}$$ के साथ $$w_3 = y$$, और,
 * उत्क्रम संचयन पुनरावर्ती संबंध की गणना करता है, $$\frac{\partial y}{\partial w_i} = \frac{\partial y}{\partial w_{i+1}} \frac{\partial w_{i+1}}{\partial w_{i}}$$ के साथ $$w_0 = x$$।

आंशिक अवकलज का मूल्य, जिसे सीड कहा जाता है, अग्रगामी या पश्चगामी प्रसारित होता है और प्रारंभ में $$\frac{\partial x}{\partial x}=1$$ या $$\frac{\partial y}{\partial y}=1$$ होता है। अग्रगामी संचयन फलन का मूल्यांकन करता है और एक पास में एक स्वतंत्र चर के संबंध में अवकलज की गणना करता है। प्रत्येक स्वतंत्र चर $$x_1,x_2,\dots,x_n$$के लिए एक अलग पास आवश्यक है जिसमें उस स्वतंत्र चर के संबंध में अवकलज को एक ($$\frac{\partial x_1}{\partial x_1}=1$$) और अन्य सभी को शून्य ($$\frac{\partial x_2}{\partial x_1}= \dots = \frac{\partial x_n}{\partial x_1} = 0$$) पर निर्धारित किया जाता है। इसके विपरीत, उत्क्रम संचयन के लिए आंशिक अवकलज के लिए मूल्यांकन किए गए आंशिक फलनो की आवश्यकता होती है। इसलिए उत्क्रम संचयन पहले फलन का मूल्यांकन करता है और एक अतिरिक्त पास में सभी स्वतंत्र चर के संबंध में अवकलज की गणना करता है।

इन दोनों प्रकारों में से किसका उपयोग किया जाना चाहिए यह स्वीप गणना पर निर्भर करता है। एक स्वीप का अभिकलनीय जटिलता मूल कोड की जटिलता के समानुपाती होती है। बहुपरतीय परसेप्ट्रॉन में त्रुटियों की पश्चसंचरण, यंत्र अधिगम में उपयोग की जाने वाली तकनीक, उत्क्रम संचयन की एक विशेष स्थिति है।
 * $n ≫ m$ के साथ फलन $f : R^{n} → R^{m}$ के लिए उत्क्रम संचयन की तुलना में अग्रगामी संचयन अधिक कुशल है क्योंकि उत्क्रम संचयन के लिए $m$ स्वीप की तुलना में केवल $n$ स्वीप आवश्यक हैं।
 * फलन $f : R^{n} → R^{m}$ के लिए $n ≪ m$ के साथ अग्रगामी संचयन की तुलना में उत्क्रम संचयन अधिक कुशल है क्योंकि अग्रगामी संचयन के लिए $n$ स्वीप की तुलना में केवल $m$ स्वीप आवश्यक है।

अग्रगामी संचयन की शुरुआत 1964 में आर.ई. वेंगर्ट द्वारा की गई थी।। एंड्रियास ग्रिवैंक के अनुसार, 1960 के दशक के उत्तरार्ध से उत्क्रम संचयन का सुझाव दिया गया है, लेकिन आविष्कारक अज्ञात है। सेप्पो लिन्नैनमा ने 1976 में उत्क्रम संचयन प्रकाशित किया।

अग्रगामी संचयन
अग्रगामी संचयन एडी में, व्यक्ति पहले स्वतंत्र चर को निर्धारित करता है जिसके संबंध में अवकलन किया जाता है और प्रत्येक उप-व्यंजक के अवकलज की पुनरावर्ती गणना करता है। कलम और कागज की गणना में, इसमें श्रृंखला नियम में आंतरिक फलनो के अवकलज को बार-बार प्रतिस्थापित करना सम्मिलित है, $$\begin{align} \frac{\partial y}{\partial x} &= \frac{\partial y}{\partial w_{n-1}} \frac{\partial w_{n-1}}{\partial x} \\[6pt] &= \frac{\partial y}{\partial w_{n-1}} \left(\frac{\partial w_{n-1}}{\partial w_{n-2}} \frac{\partial w_{n-2}}{\partial x}\right) \\[6pt] &= \frac{\partial y}{\partial w_{n-1}} \left(\frac{\partial w_{n-1}}{\partial w_{n-2}} \left(\frac{\partial w_{n-2}}{\partial w_{n-3}} \frac{\partial w_{n-3}}{\partial x}\right)\right) \\[6pt] &= \cdots \end{align}$$ इसे जैकोबियन के आव्यूह गुणन के रूप में कई चर के लिए सामान्यीकृत किया जा सकता है।

उत्क्रम संचयन की तुलना में, अग्रगामी संचयन स्वाभाविक रूप से लागू करना आसान है क्योंकि अवकलज सूचना का प्रवाह मूल्यांकन के क्रम के साथ मेल खाता है। प्रत्येक चर $$w_i$$ को इसके अवकलज $$\dot w_i$$ (संख्यात्मक मान के रूप में संग्रहीत, प्रतीकात्मक व्यंजक नहीं), $$\dot w_i = \frac{\partial w_i}{\partial x}$$के साथ संवर्धित किया गया है ,जैसा कि बिंदु द्वारा दर्शाया गया है। फिर मूल्यांकन चरणों के साथ अवकलज की गणना की जाती है और श्रृंखला नियम के माध्यम से अन्य अवकलज के साथ जोड़ा जाता है। श्रृंखला नियम का उपयोग करते हुए, यदि $$w_i$$ के पास अभिकलनीय ग्राफ़ में पूर्ववर्ती हैं, तो
 * $$\dot w_i = \sum_{j \in \{\text{predecessors of i}\}} \frac{\partial w_i}{\partial w_j} \dot w_j$$

उदाहरण के तौर पर, फलन पर विचार करें, $$\begin{align} y &= f(x_1, x_2) \\ &= x_1 x_2 + \sin x_1 \\ &= w_1 w_2 + \sin w_1 \\ &= w_3 + w_4 \\ &= w_5 \end{align}$$ स्पष्टता के लिए, व्यक्तिगत उप-व्यंजको को चर $$w_i$$ के साथ वर्गीकृत किया गया है.

जिस स्वतंत्र चर का विभेदीकरण किया जाता है उसका चयन सीड मूल्यों $ẇ_{1}$ और $ẇ_{2}$ को प्रभावित करता है। $x_{1}$ के संबंध में इस फलन के अवकलज में रुचि को देखते हुए, सीड मान को इस पर निर्धारित किया जाना चाहिए, $$\begin{align} \dot w_1 = \frac{\partial w_1}{\partial x_1} = \frac{\partial x_1}{\partial x_1} = 1 \\ \dot w_2 = \frac{\partial w_2}{\partial x_1} = \frac{\partial x_2}{\partial x_1} = 0 \end{align}$$ सीड मान निर्धारित होने के साथ, मान दिखाए गए अनुसार श्रृंखला नियम का उपयोग करके प्रसारित होते हैं। चित्र 2 एक अभिकलनीय ग्राफ़ के रूप में इस प्रक्रिया का सचित्र चित्रण दिखाता है।
 * {| class="wikitable"

!मूल्य की गणना करने के लिए संचालन !!अवकलज की गणना करने के लिए संचालन इस उदाहरण फलन की प्रवणता की गणना करने के लिए, जिसके लिए न केवल $$\tfrac{\partial y}{\partial x_1}$$ बल्कि $$\tfrac{\partial y}{\partial x_2}$$ की भी आवश्यकता होती है, सीड मान $$\dot w_1 = 0; \dot w_2 = 1$$ का उपयोग करके अभिकलनीय ग्राफ़ पर एक अतिरिक्त स्वीप किया जाता है।
 * $$w_1 = x_1$$ || $$\dot w_1 = 1$$ (seed)
 * $$w_2 = x_2$$ || $$\dot w_2 = 0$$ (seed)
 * $$w_3 = w_1 \cdot w_2$$ || $$\dot w_3 = w_2 \cdot \dot w_1 + w_1 \cdot \dot w_2$$
 * $$w_4 = \sin w_1$$ || $$\dot w_4 = \cos w_1 \cdot \dot w_1$$
 * $$w_5 = w_3 + w_4$$ || $$\dot w_5 = 1 \cdot \dot w_3 + 1 \cdot \dot w_4$$
 * }
 * $$w_4 = \sin w_1$$ || $$\dot w_4 = \cos w_1 \cdot \dot w_1$$
 * $$w_5 = w_3 + w_4$$ || $$\dot w_5 = 1 \cdot \dot w_3 + 1 \cdot \dot w_4$$
 * }
 * $$w_5 = w_3 + w_4$$ || $$\dot w_5 = 1 \cdot \dot w_3 + 1 \cdot \dot w_4$$
 * }

छद्म कोड
अग्रगामी संचयनन एक पास में फलन और अवकलज (लेकिन केवल एक स्वतंत्र चर के लिए) की गणना करता है। संबंधित विधि कॉल एक चर V के संबंध में व्यंजक Z को प्राप्त करने की अपेक्षा करती है। विधि मूल्यांकन किए गए फलन और इसकी व्युत्पत्ति की एक जोड़ी लौटाती है। यह विधि एक चर तक पहुंचने तक व्यंजक वृक्ष को पुनरावर्ती रूप से पार करती है। यदि इस चर के संबंध में अवकलज का अनुरोध किया जाता है, तो इसका अवकलज 1, 0 है अन्यथा। फिर आंशिक फलन के साथ-साथ आंशिक अवकलज का मूल्यांकन किया जाता है।  टपल<फ्लोट,फ्लोट> eval(व्यंजक Z, व्यंजक V) { यदि चर(Z) है यदि (Z=V) वापसी {valueOf(Z),1}; अन्यथा वापसी {valueOf(Z),0}; अन्यथा यदि (Z = X + Y)     {x,x'} = eval(X,V); {y,y'} = eval(Y,V); वापसी {x+y, x'+y'}; अन्यथा यदि (Z = X - Y)     {x,x'} = eval(X,V); {y,y'} = eval(Y,V); वापसी {x-y, x'-y'}; अन्यथा यदि (Z = X * Y)     {x,x'} = eval(X,V); {y,y'} = eval(Y,V); वापसी {x*y, x'*y+x*y'}; } 

सी++
 टाइपडिफ स्ट्रक्चर डुअल {फ्लोट वी,डी; } दोहरा; संरचना व्यंजक { वर्चुअल डुअल इवल(std,,map &vals, Expression *v) { return {0,0}; }; }; स्ट्रक्चर प्लस, सार्वजनिक व्यंजक { व्यंजक *ए, *बी; प्लस(व्यंजक *ए, व्यंजक *बी), ए{ए}, बी{बी} {} दोहरी eval(std,,map &vals, व्यंजक *v) { दोहरी x=a->eval(vals,v); दोहरी y=b->eval(vals,v); वापसी {x.v+y.v, x.d+y.d}; } }; संरचना मूल, सार्वजनिक व्यंजक { व्यंजक *ए, *बी; मूल(व्यंजक *ए, व्यंजक *बी), ए{ए}, बी{बी} {} दोहरी eval(std,,map &vals, व्यंजक *v) { दोहरी x=a->eval(vals,v); दोहरी y=b->eval(vals,v); वापसी {x.v*y.v, x.d*y.v+x.v*y.d}; } }; संरचना वार, सार्वजनिक व्यंजक { एसटीडी,,स्ट्रिंग एस; Var(std,,string s)), s{s} {}  दोहरी eval(std,,map &vals, व्यंजक *v) {      वापसी {vals[s], this==v?1.0f,0.0f};   } }; मुख्य प्रवेश बिंदु {   std,,map dict;   dict.insert(std,,pair( x ,1));   dict.insert(std,,pair( y ,-3));   dict.insert(std,,pair( z ,4));   वर x( x ), y( y ), z( z );   मूल m1(&x,&z); मूल m2(&y,&z); प्लस p(&m1,&m2); // x*z+y*z   std,,cout << x, << p.eval(dict,&x).d <<, << y, << p.eval(dict,&y).d << , << z, << p. eval(dict,&z).d << std,,endl;   वापसी 0; } 
 * 1) सम्मिलित करें
 * 2) सम्मिलित <स्ट्रिंग>
 * 3) सम्मिलित <मानचित्र>

विपरीत संचय
फ़ाइल,AutoDiff.webp|अंगूठा उत्क्रम संचयन एडी में, विभेदित किए जाने वाले आश्रित चर को तय किया जाता है और अवकलज की गणना प्रत्येक उप-व्यंजक (गणित) के संबंध में पुनरावर्ती रूप से की जाती है। कलम और कागज की गणना में, बाहरी कार्यों के अवकलज को श्रृंखला नियम में बार-बार प्रतिस्थापित किया जाता है, $$\begin{align} \frac{\partial y}{\partial x} &= \frac{\partial y}{\partial w_1} \frac{\partial w_1}{\partial x}\\ &= \left(\frac{\partial y}{\partial w_2} \frac{\partial w_2}{\partial w_1}\right) \frac{\partial w_1}{\partial x}\\ &= \left(\left(\frac{\partial y}{\partial w_3} \frac{\partial w_3}{\partial w_2}\right) \frac{\partial w_2}{\partial w_1}\right) \frac{\partial w_1}{\partial x}\\ &= \cdots \end{align}$$ विपरीत संचयन में, ब्याज की मात्रा सहायक होती है, जिसे एक बार से दर्शाया जाता है $$\bar w_i$$; यह उपव्यंजक के संबंध में चुने गए आश्रित चर का अवकलज है $$w_i$$, $$\bar w_i = \frac{\partial y}{\partial w_i}$$ श्रृंखला नियम का उपयोग करना, यदि $$w_i$$ अभिकलनीय ग्राफ़ में उत्तराधिकारी हैं,
 * $$\bar w_i = \sum_{j \in \{\text{successors of i}\}} \bar w_j \frac{\partial w_j}{\partial w_i}$$

उत्क्रम संचयन श्रृंखला नियम को बाहर से अंदर तक, या चित्र 3 में अभिकलनीय ग्राफ के मामले में, ऊपर से नीचे तक पार करता है। उदाहरण फलन स्केलर-मूल्यवान है, और इस प्रकार अवकलज गणना के लिए केवल एक बीज है, और (दो-घटक) ग्रेडिएंट की गणना करने के लिए अभिकलनीय ग्राफ के केवल एक स्वीप की आवश्यकता होती है। अग्रगामी संचयन की तुलना में यह केवल स्पेस-टाइम ट्रेडऑफ़ है, लेकिन उत्क्रम संचयन के लिए मध्यवर्ती चर के भंडारण की आवश्यकता होती है $w_{i}$ साथ ही वे निर्देश जो उन्हें डेटा संरचना में उत्पादित करते हैं जिन्हें टेप या वेंगर्ट सूची के रूप में जाना जाता है (हालाँकि, वेंगर्ट ने अग्रगामी संचयन प्रकाशित किया, न कि उत्क्रम संचय ), जो अभिकलनीय ग्राफ़ बड़ा होने पर महत्वपूर्ण मेमोरी का उपभोग कर सकता है। मध्यवर्ती चरों के केवल एक उपसमूह को संग्रहीत करके और फिर मूल्यांकन को दोहराकर आवश्यक कार्य चरों का पुनर्निर्माण करके इसे कुछ हद तक कम किया जा सकता है, एक तकनीक जिसे पुनर्भौतिकीकरण के रूप में जाना जाता है। चेकपॉइंटिंग योजना का उपयोग मध्यस्थ राज्यों को बचाने के लिए भी किया जाता है।

रिवर्स संचय का उपयोग करके व्युत्पन्न की गणना करने के संचालन को नीचे दी गई तालिका में दिखाया गया है (उल्टे क्रम पर ध्यान दें):

किसी गणना के डेटा प्रवाह ग्राफ़ को उसकी मूल गणना के ग्रेडिएंट की गणना करने के लिए हेरफेर किया जा सकता है। यह प्रत्येक प्राइमल नोड के लिए एक एडजॉइंट नोड जोड़कर किया जाता है, जो एडजॉइंट किनारों से जुड़ा होता है जो कि प्राइमल किनारों के समानांतर होता है लेकिन विपरीत दिशा में बहता है। निकटवर्ती ग्राफ में नोड्स प्रारंभिक में नोड्स द्वारा गणना किए गए कार्यों के अवकलज द्वारा गुणा का प्रतिनिधित्व करते हैं। उदाहरण के लिए, मूल में जोड़ के कारण जोड़ में फैनआउट हो जाता है; मूल में फ़ैनआउट के कारण जोड़ में वृद्धि होती है; एक यूनरी ऑपरेशन फलन $y = f(x)$ मौलिक कारणों में $x̄ = ȳ f′(x)$ सन्निकट में; वगैरह।

छद्म कोड
उत्क्रम संचयन के लिए दो पास की आवश्यकता होती है, फॉरवर्ड पास में, फलन का पहले मूल्यांकन किया जाता है और आंशिक परिणाम कैश किए जाते हैं। उत्क्रम पास में, आंशिक अवकलज की गणना की जाती है और पहले से प्राप्त मूल्य को बैकप्रोपेगेट किया जाता है। संबंधित विधि कॉल से अपेक्षा की जाती है कि व्यंजक Z को अवकलज किया जाए और मूल व्यंजक के अवकलज मूल्य के साथ बीजित किया जाए। शीर्ष व्यंजक के लिए, Z, Z के संबंध में अवकलज, यह 1 है। विधि व्यंजक वृक्ष को पुनरावर्ती रूप से पार करती है जब तक कि एक चर तक नहीं पहुंच जाता है और अवकलज व्यंजक में वर्तमान बीज मान जोड़ता है।  शून्य अवकलज (व्यंजक Z, फ्लोट बीज) { यदि (Z = X + Y)     अवकलज (एक्स, बीज); अवकलज (वाई, बीज); अन्यथा यदि (Z = X - Y)     अवकलज (एक्स, बीज); अवकलज(Y,-बीज); अन्यथा यदि (Z = X * Y)     अवकलज(X,valueOf(X)*seed); अवकलज(Y,seed*valueOf(Y)); अन्यथा यदि वैरिएबल (जेड) है आंशिकDerivativeOf(Z) += बीज; } 

पायथन
टेप के बिना पायथन (प्रोग्रामिंग भाषा) में कार्यान्वयन।

सी++
 संरचना व्यंजक { आगे तैरना = 0, पीछे = 0; वर्चुअल फ्लोट eval(std,,map &vals) = 0; आभासी शून्य वापस(फ्लोट बीज) {पिछड़ा+=बीज; }; }; स्ट्रक्चर प्लस, सार्वजनिक व्यंजक { व्यंजक *ए, *बी; प्लस(व्यंजक *ए, व्यंजक *बी), ए{ए}, बी{बी} {} फ्लोट eval(std,,map &vals) { पिछड़ा=0; फॉरवर्ड=a->eval(vals); फॉरवर्ड+=बी->ईवल(वैल); आगे लौटें; }  शून्य वापस (फ्लोट बीज) { व्यंजक,,वापस(बीज); ए->वापस(बीज); बी->वापस(बीज); } }; संरचना मूल, सार्वजनिक व्यंजक { व्यंजक *ए, *बी; मूल(व्यंजक *ए, व्यंजक *बी), ए{ए}, बी{बी} {} फ्लोट eval(std,,map &vals) { पिछड़ा=0; फॉरवर्ड=a->eval(vals); आगे*=b->eval(vals); आगे लौटें; }  शून्य वापस (फ्लोट बीज) { व्यंजक,,वापस(बीज); a->पीछे(बीज * b->आगे); बी->पीछे(बीज * ए->आगे); } }; संरचना वार, सार्वजनिक व्यंजक { एसटीडी,,स्ट्रिंग एस; Var(std,,string s)), s{s} {}  फ्लोट eval(std,,map &vals) {      फॉरवर्ड=वैल्स[एस];      पिछड़ा=0;      आगे लौटें;   }   शून्य वापस (फ्लोट बीज) {      व्यंजक,,वापस(बीज);      std,,cout << s < dict;   dict.insert(std,,pair<std,,string,int>( x ,1));   dict.insert(std,,pair<std,,string,int>( y ,-3));   dict.insert(std,,pair<std,,string,int>( z ,4));   वर x( x ), y( y ), z( z ); मूल m1(&x,&z); मूल m2(&y,&z); प्लस p(&m1,&m2); // x*z+y*z   std,,cout << p.eval(dict) << std,,endl;   पी.बैक(1); std,,cout << std,,endl;   वापसी 0; } </सिंटैक्सहाइलाइट>
 * 1) सम्मिलित करें
 * 2) सम्मिलित <स्ट्रिंग>
 * 3) सम्मिलित <मानचित्र>

आगे और पीछे संचयन से परे
आगे और पीछे संचयन श्रृंखला नियम को पार करने के केवल दो (चरम) तरीके हैं। संपूर्ण जैकोबियन की गणना करने की समस्या $f : R^{n} → R^{m}$ अंकगणितीय परिचालनों की न्यूनतम संख्या के साथ इष्टतम जैकोबियन संचयन (ओजेए) समस्या के रूप में जाना जाता है, जो एनपी-पूर्ण है। इस प्रमाण के केंद्र में यह विचार है कि ग्राफ़ के किनारों को लेबल करने वाले स्थानीय आंशिक भागों के बीच बीजगणितीय निर्भरताएँ मौजूद हो सकती हैं। विशेष रूप से, दो या दो से अधिक एज लेबल को बराबर के रूप में पहचाना जा सकता है। समस्या की जटिलता अभी भी खुली है यदि यह मान लिया जाए कि सभी किनारे के लेबल अद्वितीय और बीजगणितीय रूप से स्वतंत्र हैं।

दोहरी संख्याओं का उपयोग करके स्वचालित अवकलन
वास्तविक संख्याओं के क्षेत्र में बीजगणित को बढ़ाकर और एक नया अंकगणित प्राप्त करके फॉरवर्ड मोड स्वचालित अवकलन पूरा किया जाता है। संख्या पर किसी फलन के अवकलज का प्रतिनिधित्व करने के लिए प्रत्येक संख्या में एक अतिरिक्त घटक जोड़ा जाता है, और सभी अंकगणितीय ऑपरेटरों को संवर्धित बीजगणित के लिए विस्तारित किया जाता है। संवर्धित बीजगणित दोहरी संख्याओं का बीजगणित है।

हर नंबर बदलें $$\,x$$ संख्या के साथ $$x + x'\varepsilon$$, कहाँ $$x'$$ एक वास्तविक संख्या है, लेकिन $$\varepsilon$$ संपत्ति के साथ एक अमूर्त संख्या है $$\varepsilon^2=0$$ (एक अतिसूक्ष्म; सहज अतिसूक्ष्म विश्लेषण देखें)। इसके प्रयोग से ही नियमित अंकगणित मिलता है $$\begin{align} (x + x'\varepsilon) + (y + y'\varepsilon) &= x + y + (x' + y')\varepsilon \\ (x + x'\varepsilon) - (y + y'\varepsilon) &= x - y + (x' - y')\varepsilon \\ (x + x'\varepsilon) \cdot (y + y'\varepsilon) &= xy + xy'\varepsilon + yx'\varepsilon + x'y'\varepsilon^2 = xy + (x y' + yx')\varepsilon \\ (x + x'\varepsilon) / (y + y'\varepsilon) &= (x/y + x'\varepsilon/y) / (1 + y'\varepsilon/y) = (x/y + x'\varepsilon/y) \cdot (1 - y'\varepsilon/y) = x/y + (x'/y - xy'/y^2)\varepsilon \end{align}$$ का उपयोग करते हुए $$(1 + y'\varepsilon/y) \cdot (1 - y'\varepsilon/y) = 1$$.

अब, इस संवर्धित अंकगणित में बहुपदों की गणना की जा सकती है। अगर $$P(x) = p_0 + p_1 x + p_2x^2 + \cdots + p_n x^n$$, तब $$\begin{align} P(x + x'\varepsilon) &= p_0 + p_1(x + x'\varepsilon) + \cdots + p_n (x + x'\varepsilon)^n \\ &= p_0 + p_1 x + \cdots + p_n x^n + p_1x'\varepsilon + 2p_2xx'\varepsilon + \cdots + np_n x^{n-1} x'\varepsilon \\ &= P(x) + P^{(1)}(x)x'\varepsilon \end{align}$$ कहाँ $$P^{(1)}$$ के अवकलज को दर्शाता है $$P$$ इसके पहले तर्क के संबंध में, और $$x'$$, जिसे बीज कहा जाता है, मनमाने ढंग से चुना जा सकता है।

नए अंकगणित में क्रमित जोड़े, लिखे गए तत्व सम्मिलित हैं $$\langle x, x' \rangle$$, जैसा कि ऊपर वर्णित है, पहले घटक पर सामान्य अंकगणित और दूसरे घटक पर प्रथम क्रम अवकलन अंकगणित के साथ। बहुपदों पर उपरोक्त परिणामों को विश्लेषणात्मक कार्यों तक विस्तारित करने से बुनियादी अंकगणित और नए अंकगणित के लिए कुछ मानक कार्यों की एक सूची मिलती है, $$\begin{align} \left\langle u,u'\right\rangle + \left\langle v,v'\right\rangle &= \left\langle u + v, u' + v' \right\rangle \\ \left\langle u,u'\right\rangle - \left\langle v,v'\right\rangle &= \left\langle u - v, u' - v' \right\rangle \\ \left\langle u,u'\right\rangle * \left\langle v,v'\right\rangle &= \left\langle u v, u'v + uv' \right\rangle \\ \left\langle u,u'\right\rangle / \left\langle v,v'\right\rangle &= \left\langle \frac{u}{v}, \frac{u'v - uv'}{v^2} \right\rangle \quad ( v\ne 0) \\ \sin\left\langle u,u'\right\rangle &= \left\langle \sin(u), u' \cos(u) \right\rangle \\ \cos\left\langle u,u'\right\rangle &= \left\langle \cos(u), -u' \sin(u) \right\rangle \\ \exp\left\langle u,u'\right\rangle &= \left\langle \exp u, u' \exp u \right\rangle \\ \log\left\langle u,u'\right\rangle &= \left\langle \log(u), u'/u \right\rangle \quad (u>0) \\ \left\langle u,u'\right\rangle^k &= \left\langle u^k, u' k u^{k - 1} \right\rangle \quad (u \ne 0) \\ \left| \left\langle u,u'\right\rangle \right| &= \left\langle \left| u \right|, u' \operatorname{sign} u \right\rangle \quad (u \ne 0) \end{align}$$ और सामान्य तौर पर आदिम कार्य के लिए $$g$$, $$g(\langle u,u' \rangle, \langle v,v' \rangle ) = \langle g(u,v) , g_u(u,v) u' + g_v(u,v) v' \rangle$$ कहाँ $$g_u$$ और $$g_v$$ के अवकलज हैं $$g$$ क्रमशः इसके पहले और दूसरे तर्क के संबंध में।

जब एक द्विआधारी बुनियादी अंकगणितीय ऑपरेशन को मिश्रित तर्कों पर लागू किया जाता है - जोड़ी $$\langle u, u' \rangle$$ और वास्तविक संख्या $$c$$-वास्तविक संख्या को पहले उठाया जाता है $$\langle c, 0 \rangle$$. किसी फलन का अवकलज $$f : \R\to\R$$ बिंदु पर $$x_0$$ अब गणना करके पाया जाता है $$f(\langle x_0, 1 \rangle)$$ उपरोक्त अंकगणित का उपयोग करते हुए, जो देता है $$\langle f ( x_0 ), f' ( x_0 ) \rangle $$ परिणाम के रूप में।

वेक्टर तर्क और कार्य
दिशात्मक अवकलज ऑपरेटर को अपनाकर बहुभिन्नरूपी कार्यों को अविभाज्य कार्यों के समान दक्षता और तंत्र के साथ संभाला जा सकता है। अर्थात्, यदि यह गणना करने के लिए पर्याप्त है $$y' = \nabla f(x)\cdot x'$$, दिशात्मक अवकलज $$y' \in \R^m$$ का $$f:\R^n\to\R^m$$ पर $$x \in \R^n$$ दिशा में $$x' \in \R^n$$ के रूप में गणना की जा सकती है $$(\langle y_1,y'_1\rangle, \ldots, \langle y_m,y'_m\rangle) = f(\langle x_1,x'_1\rangle, \ldots, \langle x_n,x'_n\rangle)$$ उपरोक्त के समान अंकगणित का उपयोग करना। यदि के सभी तत्व $$\nabla f$$ तो वांछित हैं $$n$$ फलन मूल्यांकन की आवश्यकता है. ध्यान दें कि कई अनुकूलन अनुप्रयोगों में, दिशात्मक अवकलज वास्तव में पर्याप्त है।

उच्च क्रम और कई चर
उपरोक्त अंकगणित को दूसरे क्रम और बहुभिन्नरूपी कार्यों के उच्च अवकलज की गणना करने के लिए सामान्यीकृत किया जा सकता है। हालाँकि, अंकगणित के नियम तेजी से जटिल हो जाते हैं, जटिलता उच्चतम अवकलज डिग्री में द्विघात है। इसके बजाय, काटे गए टेलर श्रृंखला बीजगणित का उपयोग किया जा सकता है। परिणामी अंकगणित, सामान्यीकृत दोहरी संख्याओं पर परिभाषित, कार्यों का उपयोग करके कुशल गणना की अनुमति देता है जैसे कि वे एक डेटा प्रकार थे। एक बार किसी फलन का टेलर बहुपद ज्ञात हो जाने पर, अवकलज आसानी से निकाले जा सकते हैं।

कार्यान्वयन
फॉरवर्ड-मोड एआई को प्रोग्राम की एक गैर-मानक व्याख्या द्वारा कार्यान्वित किया जाता है जिसमें वास्तविक संख्याओं को दोहरी संख्याओं द्वारा प्रतिस्थापित किया जाता है, स्थिरांक को शून्य ईपीएसलॉन गुणांक के साथ दोहरी संख्याओं में उठाया जाता है, और संख्यात्मक प्राइमेटिव्स को दोहरी संख्याओं पर काम करने के लिए उठाया जाता है। यह गैरमानक व्याख्या आम तौर पर दो रणनीतियों में से एक का उपयोग करके कार्यान्वित की जाती है, स्रोत कोड परिवर्तन या ऑपरेटर ओवरलोडिंग।

स्रोत कोड परिवर्तन (एससीटी)
किसी फलन के स्रोत कोड को स्वचालित रूप से उत्पन्न स्रोत कोड द्वारा प्रतिस्थापित किया जाता है जिसमें मूल निर्देशों के साथ जुड़े अवकलज की गणना के लिए विवरण सम्मिलित होते हैं।

स्रोत कोड परिवर्तन को सभी प्रोग्रामिंग भाषाओं के लिए लागू किया जा सकता है, और कंपाइलर के लिए संकलन समय अनुकूलन करना भी आसान है। हालाँकि, एआई टूल का कार्यान्वयन स्वयं अधिक कठिन है और निर्माण प्रणाली अधिक जटिल है। स्रोत कोड परिवर्तन टूल के उदाहरणों में Enzyme टूल सम्मिलित है एलएलवीएम/एमएलआईआर के लिए (और इस प्रकार सी/सी++, जूलिया, रस्ट, फोरट्रान, पायथन, आदि को अलग करता है) और टेपेनेड टूल फोरट्रान/सी के लिए.

ऑपरेटर ओवरलोडिंग (ओओ)
ऑपरेटर ओवरलोडिंग कर रहा है के कारण स्रोत कोड का समर्थन करने वाली भाषा में लिखे जाने की संभावना है। ऊपर दर्शाए गए संवर्धित अंकगणित को पूरा करने के लिए वास्तविक संख्याओं और प्राथमिक गणितीय परिचालनों के लिए वस्तुओं को अतिभारित किया जाना चाहिए। फलन को विभेदित करने के लिए मूल स्रोत कोड में संचालन के रूप या अनुक्रम में कोई बदलाव की आवश्यकता नहीं होती है, लेकिन अक्सर ओवरलोडिंग का समर्थन करने के लिए संख्याओं और वैक्टरों के लिए बुनियादी डेटा प्रकारों में बदलाव की आवश्यकता होती है और अक्सर विशेष फ़्लैगिंग संचालन को सम्मिलित करना भी सम्मिलित होता है। प्रत्येक लूप पर अंतर्निहित ऑपरेटर ओवरहेड ओवरलोडिंग के कारण, यह दृष्टिकोण आमतौर पर कमजोर गति प्रदर्शन को प्रदर्शित करता है।

C++ में स्वचालित अवकलन के ऑपरेटर-ओवरलोडिंग कार्यान्वयन के उदाहरण हैं,
 * निपुण (सी++ लाइब्रेरी)
 * एनएजी की डीसीओ लाइब्रेरी
 * स्टेन (सॉफ्टवेयर) पुस्तकालय
 * Xएआई ओपन-सोर्स टूल

ऑपरेटर ओवरलोडिंग और स्रोत कोड परिवर्तन
ओवरलोडेड ऑपरेटर्स का उपयोग वैल्यूएशन ग्राफ़ निकालने के लिए किया जा सकता है, जिसके बाद रन-टाइम पर प्राइमल फलन के एडी-संस्करण की स्वचालित पीढ़ी होती है। क्लासिक OO Aएआई के विपरीत, ऐसा एआई-फलन एक पुनरावृत्ति से अगले में नहीं बदलता है। इसलिए प्रति Xi नमूने में कोई OO या टेप व्याख्या रन-टाइम ओवरहेड है।

रनटाइम पर एडी-फलन उत्पन्न होने के साथ, इसे प्रोग्राम की वर्तमान स्थिति को ध्यान में रखने और कुछ मानों की पूर्व-गणना करने के लिए अनुकूलित किया जा सकता है। इसके अलावा, इसे उपयोगकर्ता डेटा के 4(8)-दोगुने टुकड़ों (AVX2\AVX512 गति x4-x8) को संसाधित करने के लिए देशी सीपीयू वेक्टराइजेशन का लगातार उपयोग करने के तरीके से उत्पन्न किया जा सकता है। मल्टीथ्रेडिंग को ध्यान में रखते हुए, इस तरह के दृष्टिकोण से पारंपरिक Aएआई टूल की तुलना में ऑर्डर 8 × #Cores का अंतिम त्वरण हो सकता है। GitHub पर एक संदर्भ कार्यान्वयन उपलब्ध है।

यह भी देखें

 * विभिन्न प्रोग्रामिंग

बाहरी संबंध

 * www.autodiff.org, An "entry site to everything you want to know about automatic differentiation"
 * Automatic Differentiation of Parallel OpenMP Programs
 * Automatic Differentiation, C++ Templates and Photogrammetry
 * Automatic Differentiation, Operator Overloएआईing Approach
 * Compute analytic derivatives of any Fortran77, Fortran95, or C program through a web-based interface Automatic Differentiation of Fortran programs
 * Description and example code for forward Automatic Differentiation in Scala
 * finmath-lib stochastic automatic differentiation, Automatic differentiation for random variables (Java implementation of the stochastic automatic differentiation).
 * एआईjoint Algorithmic Differentiation, Calibration and Implicit Function Theorem
 * C++ Template-based automatic differentiation article and implementation
 * Tangent Source-to-Source Debuggable Derivatives
 * Exact First- and Second-Order Greeks by Algorithmic Differentiation
 * एआईjoint Algorithmic Differentiation of a GPU Accelerated Application
 * एआईjoint Methods in Computational Finance Software Tool Support for Algorithmic Differentiationop
 * More than a Thousand Fold Speed Up for xVA Pricing Calculations with Intel Xeon Scalable Processors