इकाई परीक्षण आपका मित्र है
लेखकों के बीच एक कहावत है कि "सभी लेखन फिर से लिख रहे हैं" - अर्थात, लेखन का बड़ा हिस्सा संशोधित है। प्रोग्रामर (या कम से कम डेटा वैज्ञानिकों) के लिए अभिव्यक्ति को "सभी कोडिंग डीबगिंग" के रूप में फिर से प्रकाशित किया जा सकता है।
किसी भी समय आप कोड लिख रहे हैं, आपको यह सत्यापित करने की आवश्यकता है कि यह इरादा के अनुसार काम करता है। शुद्धता की पुष्टि करने के लिए मैंने जो सबसे अच्छी विधि पाई है, वह यह है कि अपने कोड को छोटे खंडों में तोड़ें, और सत्यापित करें कि प्रत्येक खंड काम करता है। यह खंड आउटपुट की तुलना करके किया जा सकता है जिसे आप सही उत्तर के रूप में जानते हैं। इसे इकाई परीक्षण कहा जाता है । अच्छी इकाई परीक्षण लिखना एक अच्छा सांख्यिकीविद् / डेटा वैज्ञानिक / मशीन लर्निंग विशेषज्ञ / तंत्रिका नेटवर्क व्यवसायी बनने का एक महत्वपूर्ण हिस्सा है। बस कोई विकल्प नहीं है।
आपको यह जांचना होगा कि नेटवर्क प्रदर्शन को ट्यून करने से पहले आपका कोड बग से मुक्त है! अन्यथा, आप आरएमएस टाइटैनिक पर डेक कुर्सियों की फिर से व्यवस्था कर सकते हैं ।
तंत्रिका नेटवर्क की दो विशेषताएं हैं जो सत्यापन को अन्य प्रकार के मशीन लर्निंग या सांख्यिकीय मॉडल की तुलना में अधिक महत्वपूर्ण बनाती हैं।
तंत्रिका नेटवर्क "ऑफ-द-शेल्फ" एल्गोरिदम नहीं हैं जिस तरह से यादृच्छिक वन या लॉजिस्टिक प्रतिगमन हैं। यहां तक कि सरल, फ़ीड-फॉरवर्ड नेटवर्क के लिए, ओनस उपयोगकर्ता पर काफी हद तक है कि नेटवर्क कैसे कॉन्फ़िगर किया गया है, जुड़ा हुआ है, प्रारंभ या अनुकूलित किया गया है। इसका मतलब है कोड लिखना, और कोड लिखना मतलब डीबगिंग।
यहां तक कि जब एक तंत्रिका नेटवर्क कोड एक अपवाद को बढ़ाए बिना निष्पादित होता है, तो भी नेटवर्क में बग हो सकते हैं! ये बग ऐसे कपटी प्रकार भी हो सकते हैं जिनके लिए नेटवर्क प्रशिक्षित होगा, लेकिन एक उप-इष्टतम समाधान पर अटक जाता है, या परिणामस्वरूप नेटवर्क में वांछित वास्तुकला नहीं होती है। ( यह एक वाक्यात्मक और शब्दार्थ त्रुटि के बीच अंतर का एक उदाहरण है ।)
चेस रॉबर्ट्स द्वारा यह मीडियम पोस्ट, " यूनिट टेस्ट मशीन लर्निंग कोड कैसे करें ", मशीन लर्निंग मॉडल के लिए यूनिट-परीक्षण पर अधिक विस्तार से चर्चा करता है। मैंने लेख से छोटी गाड़ी कोड का यह उदाहरण उधार लिया है:
def make_convnet(input_image):
net = slim.conv2d(input_image, 32, [11, 11], scope="conv1_11x11")
net = slim.conv2d(input_image, 64, [5, 5], scope="conv2_5x5")
net = slim.max_pool2d(net, [4, 4], stride=4, scope='pool1')
net = slim.conv2d(input_image, 64, [5, 5], scope="conv3_5x5")
net = slim.conv2d(input_image, 128, [3, 3], scope="conv4_3x3")
net = slim.max_pool2d(net, [2, 2], scope='pool2')
net = slim.conv2d(input_image, 128, [3, 3], scope="conv5_3x3")
net = slim.max_pool2d(net, [2, 2], scope='pool3')
net = slim.conv2d(input_image, 32, [1, 1], scope="conv6_1x1")
return net
क्या आप त्रुटि देखते हैं? कई अलग-अलग ऑपरेशन वास्तव में उपयोग नहीं किए जाते हैं क्योंकि पिछले परिणाम नए चर के साथ लिखे गए हैं। एक नेटवर्क में कोड के इस ब्लॉक का उपयोग करना अभी भी प्रशिक्षित होगा और वजन अपडेट हो जाएगा और नुकसान भी कम हो सकता है - लेकिन कोड निश्चित रूप से वह नहीं कर रहा है जो इरादा था। (लेखक एकल या दोहरे उद्धरणों का उपयोग करने के बारे में भी असंगत है लेकिन यह विशुद्ध रूप से शैलीगत है।)
तंत्रिका नेटवर्क से संबंधित सबसे आम प्रोग्रामिंग त्रुटियां हैं
- चर बनाए जाते हैं लेकिन कभी भी उपयोग नहीं किए जाते हैं (आमतौर पर कॉपी-पेस्ट त्रुटियों के कारण);
- ग्रेडिएंट अपडेट के लिए अभिव्यक्तियाँ गलत हैं;
- वजन अपडेट लागू नहीं होते हैं;
- हानि कार्यों को सही पैमाने पर नहीं मापा जाता है (उदाहरण के लिए, संभावना या प्रवेश के संदर्भ में क्रॉस-एन्ट्रापी नुकसान को व्यक्त किया जा सकता है)
- नुकसान कार्य के लिए उपयुक्त नहीं है (उदाहरण के लिए, प्रतिगमन कार्य के लिए श्रेणीबद्ध-एन्ट्रापी नुकसान का उपयोग करना)।
आप चलने से पहले क्रॉल करें; चलने से पहले चलें
व्यापक और गहरे तंत्रिका नेटवर्क, और विदेशी तारों के साथ तंत्रिका नेटवर्क, मशीन सीखने में अभी हॉट थिंग हैं। लेकिन इन नेटवर्क ने वसंत को पूरी तरह से अस्तित्व में नहीं बनाया; उनके डिजाइनरों ने छोटी इकाइयों से उनका निर्माण किया। सबसे पहले, एक छिपी हुई परत के साथ एक छोटा नेटवर्क बनाएं और सत्यापित करें कि यह सही ढंग से काम करता है। फिर इंक्रीमेंटल अतिरिक्त मॉडल जटिलता जोड़ें, और सत्यापित करें कि उनमें से प्रत्येक भी काम करता है।
एक परत में बहुत कम न्यूरॉन्स प्रतिनिधित्व को प्रतिबंधित कर सकते हैं जो नेटवर्क सीखता है, जिससे अंडर-फिटिंग होती है। बहुत अधिक न्यूरॉन्स ओवर-फिटिंग का कारण बन सकते हैं क्योंकि नेटवर्क प्रशिक्षण डेटा को "याद" करेगा।
यहां तक कि अगर आप यह साबित कर सकते हैं कि गणितीय रूप से, केवल एक समस्या को मॉडल करने के लिए आवश्यक न्यूरॉन्स की एक छोटी संख्या है, तो अक्सर ऐसा होता है कि "कुछ और" न्यूरॉन्स होने से ऑप्टिमाइज़र को "अच्छा" कॉन्फ़िगरेशन ढूंढना आसान हो जाता है। (लेकिन मुझे नहीं लगता कि कोई भी पूरी तरह से समझता है कि यह मामला क्यों है।) मैं यहां XOR समस्या के संदर्भ में इसका एक उदाहरण प्रदान करता हूं: क्या मेरे पुनरावृत्तियों को MSE <0.001 के साथ XOR के लिए NN को प्रशिक्षित करने की आवश्यकता नहीं है? ।
छिपी हुई परतों की संख्या को चुनना नेटवर्क को कच्चे डेटा से एक अमूर्तता सीखने देता है। इन दिनों दीप लर्निंग सभी क्रोध है, और बड़ी संख्या में परतों के साथ नेटवर्क ने प्रभावशाली परिणाम दिखाए हैं। लेकिन बहुत सी छिपी हुई परतों को जोड़ने से ओवरफिटिंग का खतरा हो सकता है या नेटवर्क को अनुकूलित करना बहुत कठिन हो सकता है।
एक चतुर नेटवर्क वायरिंग चुनना आपके लिए बहुत सारे काम कर सकता है। क्या आपका डेटा स्रोत विशिष्ट नेटवर्क आर्किटेक्चर के लिए उत्तरदायी है? संवैधानिक तंत्रिका नेटवर्क "संरचित" डेटा स्रोतों, छवि या ऑडियो डेटा पर प्रभावशाली परिणाम प्राप्त कर सकते हैं। आवर्तक तंत्रिका नेटवर्क अनुक्रमिक डेटा प्रकारों पर अच्छा कर सकते हैं, जैसे कि प्राकृतिक भाषा या समय श्रृंखला डेटा। अवशिष्ट कनेक्शन गहरे फीड-फॉरवर्ड नेटवर्क में सुधार कर सकते हैं।
न्यूरल नेटवर्क ट्रेनिंग लॉक पिकिंग की तरह है
कला की स्थिति को प्राप्त करने के लिए, या केवल अच्छे परिणाम के लिए, आपको एक साथ अच्छी तरह से काम करने के लिए कॉन्फ़िगर किए गए सभी भागों को स्थापित करना होगा । एक तंत्रिका नेटवर्क कॉन्फ़िगरेशन स्थापित करना जो वास्तव में सीखता है, एक लॉक को चुनना बहुत पसंद है: सभी टुकड़ों को बस सही ऊपर पंक्तिबद्ध करना होगा। जिस तरह सही जगह पर एक भी टंबलर रखना पर्याप्त नहीं है, न ही यह केवल आर्किटेक्चर, या केवल ऑप्टिमाइज़र के लिए पर्याप्त है, सही तरीके से सेट किया गया है।
ट्यूनिंग कॉन्फ़िगरेशन विकल्प वास्तव में यह कहते हुए सरल नहीं है कि एक प्रकार की कॉन्फ़िगरेशन पसंद (जैसे सीखने की दर) अन्य की तुलना में अधिक या कम महत्वपूर्ण है (जैसे इकाइयों की संख्या), क्योंकि ये सभी विकल्प अन्य सभी विकल्पों के साथ बातचीत करते हैं, इसलिए एक पसंद अन्य जगह किए गए एक अन्य विकल्प के साथ संयोजन में अच्छा कर सकता है ।
यह कॉन्फ़िगरेशन विकल्पों की एक गैर-विस्तृत सूची है जो नियमितीकरण विकल्प या संख्यात्मक अनुकूलन विकल्प भी नहीं हैं।
ये सभी विषय अनुसंधान के सक्रिय क्षेत्र हैं।
गैर-उत्तल अनुकूलन कठिन है
एक तंत्रिका नेटवर्क का उद्देश्य फ़ंक्शन केवल उत्तल होता है जब कोई छिपी हुई इकाइयां नहीं होती हैं, तो सभी सक्रियताएं रैखिक होती हैं, और डिज़ाइन मैट्रिक्स पूर्ण-रैंक है - क्योंकि यह कॉन्फ़िगरेशन सामान्य रूप से एक साधारण प्रतिगमन समस्या है।
अन्य सभी मामलों में, अनुकूलन समस्या गैर-उत्तल है, और गैर-उत्तल अनुकूलन कठिन है। तंत्रिका नेटवर्क को प्रशिक्षित करने की चुनौतियां अच्छी तरह से ज्ञात हैं (देखें: गहरे तंत्रिका नेटवर्क को प्रशिक्षित करना कठिन क्यों है? )। इसके अतिरिक्त, तंत्रिका नेटवर्क में बहुत बड़ी संख्या में पैरामीटर होते हैं, जो हमें पूरी तरह से प्रथम-क्रम के तरीकों के लिए प्रतिबंधित करता है (देखें: न्यूटन की विधि व्यापक रूप से मशीन सीखने में क्यों नहीं उपयोग की जाती है? )। यह शोध का बहुत सक्रिय क्षेत्र है।
स्थापना सीखने दर बहुत बड़ी अनुकूलन, वितरित हो जाते हैं, क्योंकि आप दूसरे के लिए "घाटी" के एक पक्ष से छलांग होगा कारण होगा। इसे बहुत छोटा सेट करना आपको किसी भी वास्तविक प्रगति करने से रोकेगा, और संभवतः अपने ढालने वाले अनुमानों को कम करने के लिए नॉइज़े में निहित शोर को अनुमति देगा।
धीरे - धीरे कतरन ढाल का मान बढ़ाता है अगर यह कुछ सीमा से ऊपर है। मैं समझता था कि यह एक सेट-एंड-भूल पैरामीटर था, आमतौर पर 1.0 पर, लेकिन मैंने पाया कि मैं एक LSTM भाषा मॉडल को नाटकीय रूप से बेहतर बनाकर इसे 0.25 पर सेट कर सकता हूं। मुझे नहीं पता कि ऐसा क्यों है।
लर्निंग दर निर्धारण प्रशिक्षण के दौरान सीखने की दर को कम कर सकता है। मेरे अनुभव में, शेड्यूलिंग का उपयोग करने की कोशिश करना रेगेक्स की तरह बहुत कुछ है : यह एक समस्या को बदल देता है ("मैं एक निश्चित अवधि के बाद जारी रखने के लिए कैसे सीख सकता हूं?") दो समस्याओं के साथ ("मैं एक निश्चित युग के बाद कैसे जारी रखना सीखता हूं?" ? "और" मैं एक अच्छी अनुसूची कैसे चुनूँ? ")। अन्य लोग इस बात पर जोर देते हैं कि शेड्यूलिंग आवश्यक है। मैं आपको फैसला करने दूँगा।
एक अच्छा मिनीबच आकार चुनना , सीखने की प्रक्रिया को अप्रत्यक्ष रूप से प्रभावित कर सकता है, क्योंकि एक बड़ा मिनी-बैच एक छोटे मिनी-बैच की तुलना में एक छोटे संस्करण ( कानून-से-बड़ी संख्या ) का होगा। आप चाहते हैं कि मिनी-बैच ढाल की दिशा के बारे में जानकारीपूर्ण होने के लिए पर्याप्त बड़ा हो, लेकिन इतना छोटा कि आपके नेटवर्क को नियमित कर सकें।
स्टोकेस्टिक ग्रेडिएंट डिसेंट पर कई वेरिएंट हैं जो वनीला एसडब्ल्यूएस में सुधार करने के लिए गति, अनुकूली सीखने की दर, नेस्टरोव अपडेट आदि का उपयोग करते हैं। एक बेहतर अनुकूलक डिज़ाइन करना अनुसंधान का एक सक्रिय क्षेत्र है। कुछ उदाहरण:
जब यह पहली बार सामने आया, तो एडम ऑप्टिमाइज़र ने बहुत रुचि पैदा की। लेकिन कुछ हालिया शोध में पाया गया है कि गति के साथ SGD तंत्रिका नेटवर्क के लिए अनुकूली ढाल के तरीकों का प्रदर्शन कर सकता है। " मशीन लर्निंग में एडेप्टिव ग्रैडिएंट मेथड्स का मार्जिनल वैल्यू " आशिया सी। विल्सन, रेबेका रोलोफ्स, मिशेल स्टर्न, नाथन स्रेब्रॉन, बेंजामिन रेचट द्वारा
लेकिन दूसरी ओर, यह बहुत हालिया पेपर एक नए अनुकूली शिक्षण-दर अनुकूलक का प्रस्ताव करता है, जो अनुकूली-दर विधियों और SGD के बीच के अंतर को गति के साथ बंद कर देता है। जिंगहुई चेन, क्वेकक्वैन गुजरात द्वारा " ट्रेनिंग दीप न्यूरल नेटवर्क्स में एडाप्टिव ग्रैडिएंट मेथड्स का सामान्यीकरण गैप बंद करना "
अनुकूली ढाल विधियाँ, जो सीखने की दर को स्वचालित रूप से समायोजित करने के लिए ऐतिहासिक ढाल की जानकारी को अपनाती हैं, गहन तंत्रिका नेटवर्क के प्रशिक्षण में गति के साथ स्टोकेस्टिक ग्रेडिएंट डिसेंट (SGD) की तुलना में बदतर सामान्यीकरण करने के लिए देखा गया है। यह अनुकूली ढाल के सामान्यीकरण अंतराल को बंद करने के लिए एक खुली समस्या को छोड़ देता है। इस काम में, हम दिखाते हैं कि एडम, एम्सग्रेड जैसे अनुकूली ढाल तरीके कभी-कभी "ओवर अनुकूलित" होते हैं। हम आंशिक रूप से अनुकूली गति आकलन विधि (पदम) नामक एक नया एल्गोरिथ्म डिज़ाइन करते हैं, जो दोनों दुनिया से सर्वश्रेष्ठ हासिल करने के लिए एडम के साथ एडम / एम्सग्रेड को एकीकृत करता है। मानक बेंचमार्क पर प्रयोग से पता चलता है कि पदम गहरी तंत्रिका नेटवर्क के प्रशिक्षण में सामान्य और साथ ही SGD को सामान्य करते हुए एडम / एम्सग्रेड के रूप में तेजी से अभिसरण दर बनाए रख सकते हैं।
मानकीकरण
डेटा का पैमाना प्रशिक्षण पर एक बड़ा बदलाव ला सकता है।
[ - 0.5 , 0.5 ]
परत का सामान्यीकरण न्यूरॉन्स की सक्रियता के लिए एक सामान्य साधन और मानक विचलन रखकर नेटवर्क प्रशिक्षण में सुधार कर सकता है। यह अच्छी तरह से समझा नहीं गया है कि यह प्रशिक्षण में मदद क्यों करता है, और अनुसंधान का एक सक्रिय क्षेत्र बना हुआ है।
- जोहान ब्योर्क, कार्ला गोम्स, बार्ट सेलमैन द्वारा " अंडरस्टैंडिंग बैच सामान्यीकरण "
- जोनास कोहलर, हाडी दानेशमंद, ऑरेलिन लुच्ची, मिंग झोउ, क्लाउस नेमेइर, थॉमस हॉफमैन द्वारा " बैच सामान्यीकरण की एक सैद्धांतिक समझ " की ओर
- शिबनी सांतुरकर, दिमित्रीस सिप्रास, एंड्रयू इलियास, अलेक्जेंडर मैड्री द्वारा " कैसे सामान्यीकरण को बैच सामान्यीकरण मदद करता है? (नहीं, यह आंतरिक सहसंयोजक पारी के बारे में नहीं है) "
नियमितीकरण
नेटवर्क नियमितीकरण चुनना और ट्यूनिंग एक मॉडल के निर्माण का एक महत्वपूर्ण हिस्सा है जो अच्छी तरह से सामान्यीकरण करता है (अर्थात, एक मॉडल जो प्रशिक्षण डेटा से अधिक नहीं है)। हालांकि, उस समय जब आपका नेटवर्क प्रशिक्षण डेटा पर नुकसान को कम करने के लिए संघर्ष कर रहा है - जब नेटवर्क सीख नहीं रहा है - नियमितीकरण समस्या क्या है यह अस्पष्ट कर सकता है।
जब मेरा नेटवर्क नहीं सीखता है, तो मैं सभी नियमितीकरण को बंद कर देता हूं और सत्यापित करता हूं कि गैर-नियमित नेटवर्क सही तरीके से काम करता है। फिर मैं प्रत्येक नियमितीकरण टुकड़े को वापस जोड़ता हूं, और सत्यापित करता हूं कि उनमें से प्रत्येक रास्ते में काम करता है।
यह रणनीति इंगित कर सकती है जहां कुछ नियमितीकरण खराब सेट हो सकते हैं। कुछ उदाहरण निम्न हैं
एल2एल1
नियमितीकरण के दो भाग संघर्ष में हैं। उदाहरण के लिए, यह व्यापक रूप से देखा गया है कि परत सामान्यीकरण और ड्रॉपआउट एक साथ उपयोग करना मुश्किल है। चूंकि या तो अपने आप में बहुत उपयोगी है, यह समझना कि दोनों का उपयोग कैसे करना है अनुसंधान का एक सक्रिय क्षेत्र है।
प्रयोग की एक लॉगबुक रखें
जब मैं एक तंत्रिका नेटवर्क स्थापित करता हूं, तो मैं किसी भी पैरामीटर सेटिंग्स को हार्ड-कोड नहीं करता हूं। इसके बजाय, मैं एक कॉन्फ़िगरेशन फ़ाइल (उदाहरण के लिए, JSON) को पढ़ता हूं और रनटाइम पर नेटवर्क कॉन्फ़िगरेशन विवरण को पॉप्युलेट करने के लिए उपयोग किया जाता है। मैं इन सभी कॉन्फ़िगरेशन फ़ाइलों को रखता हूं। यदि मैं कोई भी पैरामीटर संशोधन करता हूं, तो मैं एक नई कॉन्फ़िगरेशन फ़ाइल बनाता हूं। अंत में, मैं प्रशिक्षण और सत्यापन के लिए प्रति-युग हानि के सभी टिप्पणियों के रूप में संलग्न करता हूं।
क
एक उदाहरण के रूप में, मैं एलएसटीएम भाषा के मॉडल के बारे में सीखना चाहता था, इसलिए मैंने एक ट्विटर बॉट बनाने का फैसला किया जो अन्य ट्विटर उपयोगकर्ताओं के जवाब में नए ट्वीट लिखता है। मैंने अपने खाली समय में, ग्रेडिंग स्कूल और अपनी नौकरी के बीच इस पर काम किया। इसमें लगभग एक साल का समय लगा, और मैंने एक मॉडल को पाने से पहले लगभग 150 से अधिक विभिन्न मॉडलों को प्रसारित किया, जो मैं चाहता था: नए अंग्रेजी-भाषा का पाठ उत्पन्न करता है जो (इस प्रकार) समझ में आता है। (एक प्रमुख स्टिकिंग पॉइंट, और इस कारण से कि यह बहुत सारे प्रयास करता है, यह है कि यह केवल एक कम आउट-ऑफ-सैंपल लॉस प्राप्त करने के लिए पर्याप्त नहीं था, क्योंकि शुरुआती कम-नुकसान वाले मॉडल प्रशिक्षण डेटा को याद रखने में कामयाब रहे थे, तो यह सिर्फ संकेतों के जवाब में पाठ शब्दशः के जर्मे ब्लॉक को पुन: प्रस्तुत कर रहा था - इसने मॉडल को अधिक सहज बनाने के लिए कुछ ट्विकिंग ली और अभी भी कम नुकसान हुआ है।)