स्वचालित भेदभाव

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

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

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

समग्र फलनों के आंशिक अवकलजों का श्रृंखला नियम
स्वचालित अवकलन के लिए मूल, संयुक्त फलनो के आंशिक अवकलज के श्रृंखला नियम द्वारा प्रदान किए गए अंतर का अपघटन है। सरल संयोजन$$\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 होगा अन्यथा। फिर आंशिक फलन के साथ-साथ आंशिक अवकलज का मूल्यांकन किया जाता है। tupleeval(Expression Z, Expression 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'};

सी++
#include typedef struct dual { float v,d; } dual; struct Expression {                                virtual dual eval(std::map         &vals, Expression *v) { return {0,0}; };               };                                                   struct Plus: public Expression {                 Expression *a, *b;                         Plus(Expression *a, Expression *b): a{a}, b{b} {}      dual eval(std::map &vals, Expression *v) {                                                dual x=a->eval(vals,v);                              dual y=b->eval(vals,v);                            return {x.v+y.v, x.d+y.d};                                                                     }                                                     };                                                struct Var: public Expression {                       std::string s;                                            Var(std::string s) : s{s} {}                            dual eval(std::map &vals,  Expression *v) {                                                     return {vals[s], this==v?1.0f:0.0f};                     }                                                      };                                                   int main {                             std,,map dict; dict.insert(std,,pair( x ,1)); dict.insert(std,,pair( y ,-3)); dict.insert(std,,pair( z ,4)); Var x( x ), y( y ), z( z ); Mul m1(&x,&z); Mul m2(&y,&z); Plus 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) include
 * 2) include

उत्क्रम संचयन
उत्क्रम संचयन एडी में, अवकलित किए जाने वाले आश्रित चर को तय किया जाता है और अवकलज की गणना प्रत्येक उप-व्यंजक के संबंध में पुनरावर्ती रूप से की जाती है। कलम और कागज की गणना में, बाहरी फलनो के अवकलज को श्रृंखला नियम में बार-बार प्रतिस्थापित किया जाता है, $$\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 है। यह विधि एक चर तक पहुंचने तक व्यंजक वृक्ष को पुनरावर्ती रूप से चंक्रमण करती है और अवकलज व्यंजक में वर्तमान सीड मान जोड़ती  है। void derive(Expression Z, float seed) {             यदि (Z = X + Y)      अवकलज (X, सीड); अवकलज (Y, सीड); अन्यथा यदि (Z = X - Y)     अवकलज (X, सीड); अवकलज(Y,-सीड); अन्यथा यदि (Z = X * Y)     अवकलज(X,valueOf(X)*seed); अवकलज(Y,seed*valueOf(Y)); अन्यथा यदि वैरिएबल (जेड) है आंशिकDerivativeOf(Z) += बीज;                      }

पायथन
बिना टेप के पायथन में कार्यान्वयन।

सी++
#include                                          #include                                     #include                                    struct Expression {                                float forward=0, backward=0; virtual float eval(std::map &vals) = 0; virtual void back(float seed) { backward+=seed; }; };                                                 struct Plus: public Expression {                    व्यंजक *a, *b; Plus(Expression *a, Expression *b): a{a}, b{b} {} float eval(std::map &vals) { backward=0; forward=a->eval(vals); forward+=b->eval(vals); return forward; }    void back(float seed) { Expression::back(seed); a->back(seed); b->back(seed); }                                                     };                                                 struct Mul: public Expression {                      व्यंजक *a, *b; Mul(Expression *a, Expression *b): a{a}, b{b} {}    float eval(std::map &vals) { backward=0; forward=a->eval(vals); forward*=b->eval(vals); return forward; }   void back(float seed) { Expression::back(seed); a->back(seed * b->forward); b->back(seed * a->forward); }                                                       };                                                     struct Var: public Expression {                     std::string s;   Var(std,,string s)), s{s} {}     float eval(std::map &vals) {       forward=vals[s];          backward=0;       return forward;   }   void back(float seed) {       Expression::back(seed);      std::cout << s << ": " << backward << ", ";   }                                                   };                                                     int main {                     std,,map dict;   dict.insert(std,,pair( x ,1));   dict.insert(std,,pair( y ,-3));   dict.insert(std,,pair( z ,4));   Var x( x ), y( y ), z( z ); Mul m1(&x,&z); Mul m2(&y,&z); Plus p(&m1,&m2); // x*z+y*z   std,,cout << p.eval(dict) << std,,endl;   p.back(1); std,,cout << std,,endl; return 0;                                                }

अग्रगामी और उत्क्रम संचयन के अतिरिक्त
अग्रगामी और उत्क्रम संचयन श्रृंखला नियम को चंक्रमण करने के केवल दो (चरम) तरीके हैं। अंकगणितीय संक्रियाओं की न्यूनतम संख्या के साथ $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