मेरा Python कोड एक neural network है
(blog.gabornyeki.com)- अस्पष्ट information extraction प्रोग्राम में जैसे-जैसे exception rules जुड़ते जाते हैं, वे आसानी से spaghetti code बन जाते हैं, और ऐसी state-based logic को recurrent neural network (RNN) के रूप में सोचा जा सकता है
- code review messages में C code references खोजने का उदाहरण
identifier–open_paren–close_parenजैसे token patterns को state के रूप में track करने वाले hand-written classifier से लागू किया गया है - यह rule दिए गए उदाहरण में precision 100% दिखाता है, लेकिन
if (err) goto cleanup;जैसे cases छूट जाते हैं, इसलिए recall 50% पर रहता है, और rules बढ़ने के साथStateऔर branching statements जटिल हो जाते हैं - उसी state machine को RNN की hidden state और layer computations में encode किया जा सकता है, और उसे trainable बनाने के लिए binary indicator functions की जगह ReLU·sigmoid और trainable weights·biases की ज़रूरत होती है
- PyTorch के Elman RNN, GRU, LSTM जैसे implementations और लंबे token sequences में vanishing gradients की समस्या वास्तविक training constraints बनती है, और dataset·labels·loss function तय करने की प्रक्रिया खुद hand-written rule design में भी मदद करती है
अस्पष्ट data extraction कैसे spaghetti code बन जाता है
- raw data से information निकालने वाले research programs में, जब data किसी स्पष्ट specification का पालन नहीं करता या उसका रूप असामान्य होता है, तो rules बहुत जल्दी जटिल हो जाते हैं
- उदाहरण के कामों में news articles से कंपनियों और executives की पहचान करना, public procurement contracts को service type के हिसाब से label करना, और engineer messages में program code है या नहीं यह तय करना शामिल है
- अगर आप perfect output चाहते हैं, तो हर observation को ध्यान से जाँच सकते हैं और representative cases के लिए unit tests लिख सकते हैं
- R और Python दोनों इसके लिए testing libraries उपलब्ध कराते हैं
- nickname, synonym, और English तथा code की सीमा जैसी स्थितियों में जहाँ जटिल decision rules चाहिए, hand-written rules आसानी से अस्थिर हो जाते हैं
- neural network learning algorithm इस समस्या को इस तरह बदल देता है कि नियमों के संयोजन को इंसान बार-बार ठीक करने के बजाय data से खोजा जाए
code review messages में code references खोजना
- लक्ष्य यह पता लगाना है कि code review के दौरान भेजा गया message program code को स्पष्ट रूप से refer करता है या नहीं
- माना गया है कि देखा जा रहा codebase C में लिखा गया है
- representative messages में इस तरह के code references शामिल हैं
render_ipa_alloc()FTPSACKdebug_error()NULLIS_ERROR()aarch64,amd64if (err) goto cleanup;
- सरल rule candidates अलग-अलग तरीकों से fail होते हैं
- किसी शब्द के बाद parentheses आने पर उसे code मानने वाला rule
render_ipa_alloc()जैसे cases पकड़ लेता है, लेकिनif (err) goto cleanup;को छोड़ देता है - पूरे uppercase वाले शब्द को code मानने वाला rule
FTPSACKऔरIS_ERROR()को पकड़ लेता है, लेकिनAFAICTजैसे acronyms पर false positive देता है - non-English शब्दों को code मानने वाला rule engineering terms या architecture names को भी गलती से code मान सकता है
- किसी शब्द के बाद parentheses आने पर उसे code मानने वाला rule
- rule 2 और rule 3 को बेहतर बनाने के लिए
AFAICT,LGTM,USD,COVID,aarch64,amd64जैसे acronyms और domain terms की सूची चाहिए
hand-written state machine से बना classifier
- सरल algorithm दो चरणों में तय करता है कि message में code है या नहीं
- preprocessing: message को ऐसे token sequence में बदलना जो C code के syntactic elements को दर्शाए
- inference: यह जाँचना कि token sequence rules को पूरा करता है या नहीं
- Rule 1
underscore_identifier–open_paren–close_parenpattern को code reference मानता है - Python implementation पिछले token state को
Statedata class में store करती हैprevious_was_identifierprevious_was_open_parenprevious_previous_was_identifierseen_code
contains_codetokens पर iterate करते हुएprocessको call करता है, और अंत मेंstate.seen_codeलौटाता हैprocessतबseen_codeकोTrueसेट करता है जब current tokenclose_parenहो, उससे पहलेopen_parenहो, और उससे पहले identifier हो- यह classifier उदाहरण में कोई false positive नहीं देता और precision 100% दिखाता है, लेकिन बहुत से cases छूट जाते हैं, इसलिए recall 50% पर रह जाता है
- Rule 2 जोड़ने पर
Statefields औरif/elif/elsebranches बढ़ जाते हैं, और rules को और refine करने पर maintenance कठिन हो जाती है
state machine को RNN में बदलना
contains_codeऔरprocessएक state machine हैं, और state machine को recurrent neural network (RNN) में encode किया जा सकता है- RNN token sequence को एक-एक करके process करता है और इस conditional probability का approximation बनाता है कि message में code है
- Python के
Stateके अनुरूप मान RNN की hidden state में व्यक्त होते हैंState_0initial state है- हर
State_tcurrent token और previous state को functionfमें डालकर compute किया जाता है - final state output layer
gसे गुजरकर classification result बनती है
- उदाहरण वाला RNN तीन hidden layers का उपयोग करता है
- पहली layer current token और previous state को store या copy करती है
- दूसरी layer Rule 1 के अनुरूप pattern को जाँचती है
- तीसरी layer यह याद रखती है कि code pattern पहले कभी देखा गया है या नहीं
- tokens को one-hot रूप के binary vectors में व्यक्त किया जाता है
- hand-written algorithm की ठीक-ठीक नकल करने के लिए binary indicator function
1{x > 0}का उपयोग किया जा सकता है- hidden layers को binary values में रखा जा सकता है
- लेकिन लगभग हर जगह derivative 0 होने के कारण यह learning के लिए उपयुक्त नहीं है
- pattern की जाँच
identifier,open_paren,close_parenके product से भी की जा सकती है, लेकिन binary hidden layer में वही जाँच sum से व्यक्त की जा सकती है - Giles et al. (1992) का काम state machine खोजने के लिए second-order RNN के उपयोग से जुड़ता है
इसे trainable network में बदलना
- training के लिए binary indicator function की जगह ReLU का उपयोग किया जाता है
- संख्यात्मक constants की जगह weights और biases ले लेते हैं, और gradient descent इन parameters का estimation करता है
- output layer sigmoid activation function से final probability value निकालती है
- इस रूप को PyTorch में डालकर train किया जा सकता है, लेकिन इसे जस का तस train करने पर performance बहुत अच्छी नहीं होती
- performance कम रहने का एक कारण यह है कि architecture सामान्य नहीं है, इसलिए training procedure का बड़ा हिस्सा Python glue code में चलता है और PyTorch के C++ library implementation का कम उपयोग हो पाता है
PyTorch implementation और लंबे messages की सीमाएँ
- PyTorch का torch.nn.RNN Elman RNN आधारित implementation देता है
- उदाहरण architecture और Elman RNN में hidden layers के connections अलग हैं
- उदाहरण architecture में token
tकी पहली layer, tokent-1की तीसरी layer को input के रूप में लेती है, और हर layer केवल अपने ठीक पिछले layer से input लेती है - Elman RNN में हर hidden layer उसी layer की previous time-step state को भी input के रूप में लेती है
- Elman RNN की पहली hidden layer previous time-step की final layer को input के रूप में नहीं लेती
- उदाहरण architecture में token
- वास्तविक code review messages लंबे हो सकते हैं, और लंबे messages लंबे token sequences में बदल जाते हैं
- लंबे sequences में, भले ही gradient descent सिद्धांततः काम करे, vanishing gradient problem के कारण numerical stability की समस्या आ सकती है
- Elman RNN भी इस समस्या के प्रति संवेदनशील हो सकता है, और GRU या LSTM code detection task में बेहतर performance दे सकते हैं
data-driven अनुशासन
- RNN उन rule combinations को, जिन्हें हाथ से संभालना कठिन है, learning target में बदल देता है और समस्या की परिभाषा को अधिक स्पष्ट बनाने के लिए मजबूर करता है
- network को train करने के लिए निम्न चीज़ें चाहिए
- training dataset और validation dataset का चयन
- पहले से labeling
- ऐसा loss function जो स्पष्ट करे कि classifier को क्या हासिल करना है और क्या नहीं करना है
- यह प्रक्रिया अनपेक्षित gray areas को सामने लाती है और निर्णय के मानदंडों को अधिक स्पष्ट बनाती है
- यह data-driven अनुशासन सिर्फ neural network के लिए नहीं, बल्कि hand-written algorithms से हल की जाने वाली समस्याओं में भी उपयोगी है
1 टिप्पणियां
Hacker News की रायें
यह लेख टेस्ट या training data जुटाने पर ज़्यादा बात नहीं करता, जबकि यही हिस्सा मुख्य लगता है
जिस code को हम समझते हुए महसूस करते हैं, वह इसलिए है क्योंकि हमने, भले ही अनौपचारिक रूप से, खुद को साबित कर दिया होता है कि वह सभी inputs पर generalize करता है। जैसे sorting algorithm सिर्फ test की गई lists ही नहीं, बल्कि किसी भी list को sort करता है
neural network में अनिश्चितता इस बात में है कि वह कैसे generalize करेगा, यह पता नहीं होता। अगर unseen input थोड़ा भी अलग हो, तो कोई guaranteed property नहीं होती, और हो सकता है कि शुरू से ही desired property को mathematically specify करना मुश्किल problem हो
अगर किसी property को QuickCheck जैसे property-based test के रूप में इस्तेमाल करने लायक साफ़-साफ़ define किया जा सके, तो randomization के ज़रिए बड़ी मात्रा में tests या training data बनाया जा सकता है। desired example से शुरू करके positive/negative examples के संभावित variations generate करने वाले tests लिखे जा सकते हैं
यह proof नहीं है, लेकिन शुरुआत है। कम-से-कम अगर proof किया जा सकता है, तो यह पता होता है कि क्या prove करना है
अगर ऐसा हो, तो spaghetti code पर निर्भर रहना और neural network पर निर्भर रहना काफ़ी समान दिखता है। अगर दूसरी properties भी satisfy करानी हों, तो एक और property-based test लिख दें। neural network को सीधे modify करने के बजाय train किया जा सकता है, लेकिन code modification के लिए भी AI assistance मौजूद है
फिर भी शायद मैं code पर ज़्यादा भरोसा करूँगा। कम-से-कम debugging तो संभव है
practical काम करने वाला neural network बनाने के तरीके के रूप में पढ़ें तो यह दिलचस्प लेख है। लेकिन अगली बार input parse करना हो और कोई सचमुच इसी तरीके को जस-का-तस अपनाने लगे, तो ईमानदारी से कहूँ तो समझ नहीं आता क्या कहूँ
लेखक ने loosely defined patterns वाले arbitrary input parsing जैसी कठिन समस्या ली है, और सही कहा है कि इससे पढ़ने में मुश्किल spaghetti code बनने की संभावना ज़्यादा है
लेकिन विकल्प के रूप में वह ऐसा code सुझाते हैं जिसकी working अभी भी research का विषय है और जिसे पढ़ना मुश्किल है—यानी neural network
बात समझ में आती है, लेकिन ‘बदसूरत’ चीज़ की जगह पूरी तरह non-interpretable चीज़ को ज़्यादा value नहीं देनी चाहिए। कुछ tasks के लिए machine learning model सही हो सकता है, लेकिन कई मामलों में, मेहनत लगे तब भी, ऐसा विकल्प बेहतर होता है जिसे पढ़कर verify किया जा सके कि वह ऐसा क्यों काम करता है, बजाय ऐसे विकल्प के जहाँ यह संभव ही न हो
आखिर machine learning बस एक और विकल्प देती है। यह कितना fit बैठता है, यह evaluation results और चुने गए algorithm के लिए ज़रूरी determinism व explainability के स्तर पर निर्भर करता है
ध्यान खींचने वाली बात यह है कि क्या RNN सही choice है। इसमें training चाहिए और आपके पास जितने examples हैं उससे कहीं ज़्यादा की ज़रूरत पड़ सकती है। हालांकि known rules के आधार पर positive/negative cases का synthetic data बनाया जा सकता है
ऐसा system अच्छा है जिसमें देखा जा सके कि वह ऐसा क्यों काम कर रहा है, लेकिन अगर वह लगातार गलत जवाब दे, तो उसका मतलब नहीं। real-world use में अक्सर answer तक कैसे पहुँचा गया यह जानने से ज़्यादा सही जवाब पाना महत्वपूर्ण होता है
neural networks के लिए universal approximation theorem है। इसका मतलब है कि वे desired accuracy level तक किसी arbitrary function को represent या encode कर सकते हैं[0]
लेकिन ऐसा approximation सीखा जा सकता है या उसे कैसे सीखते हैं, इस पर कोई theorem नहीं है
[0] https://en.m.wikipedia.org/wiki/Universal_approximation_theo...
यह बताने से काफ़ी दूर है कि convolutional neural networks, transformers, LSTM जैसे वास्तविक और उपयोगी neural networks असल में कैसे काम करते हैं
दिलचस्प बात यह है कि यह theorem single-layer network के बारे में है। व्यवहार में multiple layers रखना कहीं बेहतर काम करता है
सच में अच्छा लेख है, और RNN के आसपास के गहरे mathematical concepts को मैं पूरी तरह नहीं समझ पाया, लेकिन इसने कई विचार जगाए
यह मुझे उन चीज़ों जैसा लगा जिन्हें मैं इन दिनों explore कर रहा था। apps को forward-chaining algorithm के साथ जोड़कर बनाने का तरीका। लेखक RNN इस्तेमाल करते हैं, और मैं इसे Rete algorithm में डालकर बना रहा हूँ
input string को character by character digest करने की तरह सोचने वाला हिस्सा भी powerful लगता है। ऐसा हो तो inference logic algorithm पर छोड़ दी जाती है, और हम बस बहुत पतली input/output logic लिखते हैं; बाकी algorithm संभाल लेता है
यह लेख इसलिए अच्छा है क्योंकि यह बताता है कि किसी function को RNN में बदलने का असल मतलब क्या है, और इसे PyTorch में मौजूद “batteries included” RNN से compare करते हुए learning experience के रूप में समझाता है
सवाल यह है कि state model करने के लिए network में तीन hidden layers जोड़नी पड़ती हैं—लेकिन तीन ही क्यों? क्या यह implement किए जा रहे किसी specific rule का result था, या इस तरह के rules को इस architecture में implement करते समय आम तौर पर यही layer count इस्तेमाल होता है? यह भी जानना चाहूँगा कि Elman structure में शायद कम layers से काम चल जाता या नहीं
पहली layer current token से पता चलने वाली चीज़ों और previous token की calculation के बाद पता चली चीज़ों को इकट्ठा करती है। दूसरी layer decision rule satisfy होता है या नहीं यह check करके तय करती है कि current token program code जैसा दिखता है या नहीं। तीसरी layer उस decision की तुलना previous tokens के decisions से करती है
इसे single hidden layer में compress किया जा सकता है, ऐसा लगता है। ReLU non-linearity capture करने के लिए पर्याप्त है, इसलिए संभव लगता है। Elman structure से इसका correspondence अभी पर्याप्त रूप से नहीं देखा है, इसलिए जवाब नहीं जानता
क्या RNN पूरी तरह Transformers में समा गए हैं? सोच रहा हूँ कि क्या RNN से निपटना भूलकर सिर्फ Transformers पर ध्यान देना ठीक होगा
इसमें दिखाया गया है कि एक खास संकीर्ण परिभाषा वाले Transformer, यानी causal masking वाले Transformer, RNN के बराबर हैं और इसका उलटा भी संभव है
इसी तरह आजकल चर्चा में रहने वाला architecture Mamba(https://arxiv.org/abs/2312.00752) भी gated RNN के बराबर unit रखता है। मेरी जानकारी में performance की वजहों से training के समय equivalent CNN और inference के समय RNN इस्तेमाल किया जाता है
यही दरअसल Transformers का मुख्य फायदा है। नजदीकी और दूर की associations ज्यादा कठिन या आसान नहीं होतीं। लेकिन सिद्धांत रूप से RNN असीमित दूर के अतीत को भी याद रख सकता है
पिछले 7 वर्षों से research engineer के तौर पर machine learning/LLM पर काम किया है और FAANG lab में भी काम किया है, लेकिन मैंने हमेशा बस यही सोचा कि RNN सीखना चाहिए; असल में न कभी सीखा, न कभी जरूरत पड़ी
अगर यह रोचक लगे, तो genetic programming देख सकते हैं। मैं इसे उसी समस्या के लिए एक अधिक सरल approach मानता हूँ, और इसमें math की जरूरत नहीं है
programs को abstract syntax tree के आधार पर recombine किया जाता है, और कोई heuristic देने पर program को उसी criterion के अनुसार optimize किया जाता है। जादू heuristic function में है, और आप speed, program length, जटिल structures या function calls को कम करना, network efficiency, या इनके combination जैसी चीजों को optimization target के रूप में चुन सकते हैं
https://youtu.be/tTMpKrKkYXo
https://www.human-competitive.org/
हाल ही में ऐसे अस्पष्ट tasks के लिए local LLM से interface करने के idea को explore करते हुए मैंने एक blog post लिखी
neural network को सीधे code करने की तुलना में यह ज्यादा समझदारी वाली बात नहीं लगती? llama.cpp जैसी चीज़ का इस्तेमाल करके यह evaluate करना कि छोटा model problem को वैसे ही solve कर सकता है या नहीं, और अगर नहीं तो fine-tune करके फिर अपने मनचाहे wrapper से llama.cpp के साथ programmatically integrate करना ज्यादा practical लगता है
recurrent neural networks को arbitrary computation के लिए इस्तेमाल किया जा सकता है, और Turing machine के साथ उनकी equivalence भी साबित है। लेकिन उस काम के लिए वे पूरी तरह अव्यावहारिक हैं
इस लेख का तरीका किसी तरह learned state machine जैसा दिखता है। लेख में एक लंबा summary होता तो अच्छा रहता, और “Python” बिल्कुल relevant नहीं लगता। असली Python semantics सीखना भाषा की प्रकृति के कारण काफी मुश्किल होगा। यह कोई standard वाली भाषा नहीं है, बल्कि CPython जैसा करता है, वैसी भाषा है
तो code review comments जैसी formal natural language को संभाल न पाने की क्या वजह होगी?
उस मामले में inference को random input से चलाकर random “Shakespeare” बनाया गया था, लेकिन language structure और style फिर भी RNN ने सीखे थे। शायद इसे classification में भी इस्तेमाल किया जा सकता है
पहले Python को neural network में compile करें, और फिर उसे Transformer-based neural network पर किसी तरह फिट कर दें
तब Transformer Virtual Machine(TVM) arbitrary programs चला सकेगी
transfer learning, यानी weights को एक-दूसरे पर चढ़ाने का तरीका इस्तेमाल करें, तो LLM algorithms को गहराई से encode किए हुए “जन्म” ले सकता है