जेफिरनेट लोगो

कन्वनेट्स में ओवरफिटिंग को समझना

दिनांक:

परिचय

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

मैं बुनियादी समझ के लिए इन लेखों को पढ़ने की अनुशंसा करूंगा ओवरफिटिंग, अंडरफिटिंग और पूर्वाग्रह विचरण ट्रेडऑफ़।

उद्देश्य जानें

  • ओवरफिटिंग के कारणों, परिणामों और परिदृश्यों को समझें कन्वनेट्स.
  • तंत्रिका नेटवर्क मॉडल में ओवरफिटिंग और अंडरफिटिंग का पता लगाने के लिए सीखने के चरणों की व्याख्या करें।
  • ओवरफिटिंग को कम करने के लिए विभिन्न तकनीकों को सीखें, जैसे जल्दी रोकना, ड्रॉपआउट, बैच सामान्यीकरण, नियमितीकरण और डेटा वृद्धि।
  • इन तकनीकों का उपयोग करके कार्यान्वित करें TensorFlow और केरस CIFAR-10 डेटासेट पर ConvNets को प्रशिक्षित करने के लिए।
  • मॉडल प्रदर्शन और सामान्यीकरण पर विभिन्न तकनीकों के प्रभाव का विश्लेषण करें।

विषय - सूची

कन्वनेट में ओवरफिटिंग के लिए सामान्य परिदृश्य

आइए कन्वनेट में ओवरफिटिंग के कुछ सामान्य परिदृश्यों पर गौर करें:

परिदृश्य 1: अपर्याप्त डेटा के साथ अत्यधिक जटिल मॉडल

एक छोटे डेटासेट पर एक बहुत ही जटिल मॉडल, जैसे कि गहरे तंत्रिका नेटवर्क, का उपयोग करने से ओवरफिटिंग हो सकती है। मॉडल सामान्य पैटर्न सीखने के बजाय प्रशिक्षण उदाहरणों को याद कर सकता है। उदाहरण के लिए, छवि पहचान जैसे जटिल कार्य के लिए केवल कुछ सौ छवियों वाले एक गहरे तंत्रिका नेटवर्क को प्रशिक्षित करने से ओवरफिटिंग हो सकती है।

परिणाम

मॉडल प्रशिक्षण डेटा पर बहुत अच्छा प्रदर्शन कर सकता है लेकिन नए, अनदेखे डेटा को सामान्यीकृत करने में विफल रहता है, जिसके परिणामस्वरूप वास्तविक दुनिया के अनुप्रयोगों में खराब प्रदर्शन होता है।

इस समस्या का समाधान कैसे करें?

अधिक प्रशिक्षण डेटा प्राप्त करें, हमारे डेटासेट को सामान्य बनाने के लिए छवि संवर्द्धन करें। कम जटिल मॉडल से शुरुआत करें और यदि क्षमता कम है तो जटिलता बढ़ाएँ। 

परिदृश्य 2: अत्यधिक प्रशिक्षण

किसी मॉडल को कई युगों तक लगातार प्रशिक्षित करने से ओवरफिटिंग हो सकती है। जैसा कि मॉडल प्रशिक्षण डेटा को बार-बार देखता है, वह अंतर्निहित पैटर्न सीखने के बजाय इसे याद करना शुरू कर सकता है।

परिणाम

मॉडल का प्रदर्शन अनदेखी डेटा पर स्थिर या ख़राब भी हो सकता है क्योंकि यह प्रशिक्षण सेट के लिए तेजी से विशिष्ट होता जा रहा है।

इस समस्या का समाधान कैसे करें?

मॉडल को ओवरफिट होने से बचाने और सर्वोत्तम मॉडल को बचाने के लिए जल्दी रोकने का उपयोग करें। 

परिदृश्य 3: नियमितीकरण की अनदेखी

नियमितीकरण तकनीक, जैसे एल1 या एल2 नियमितीकरण, का उपयोग जटिल मॉडलों को दंडित करके ओवरफिटिंग को रोकने के लिए किया जाता है। नियमितीकरण मापदंडों को नजरअंदाज करने या अनुचित तरीके से ट्यूनिंग करने से ओवरफिटिंग हो सकती है।

परिणाम

मॉडल अत्यधिक जटिल हो सकता है और नए डेटा को अच्छी तरह से सामान्यीकृत करने में विफल हो सकता है, जिसके परिणामस्वरूप प्रशिक्षण सेट के बाहर खराब प्रदर्शन हो सकता है।

इस समस्या का समाधान कैसे करें?

नियमितीकरण, क्रॉस-सत्यापन, हाइपर पैरामीटर ट्यूनिंग लागू करें। 

मॉडल की क्षमता क्या है?

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

आप किसी नेटवर्क की क्षमता को या तो इसे व्यापक बनाकर (मौजूदा परतों में अधिक इकाइयाँ) या इसे गहरा बनाकर (अधिक परतें जोड़कर) बढ़ा सकते हैं। व्यापक नेटवर्क में अधिक रैखिक संबंधों को सीखना आसान होता है, जबकि गहरे नेटवर्क अधिक गैर-रेखीय संबंधों को पसंद करते हैं। कौन सा बेहतर है यह सिर्फ डेटासेट पर निर्भर करता है।

सीखने की अवस्थाओं की व्याख्या

प्रशिक्षण के दौरान केरस कॉलबैक पंजीकृत करने की क्षमता प्रदान करता है डीप लर्निंग मॉडल। सभी गहन शिक्षण मॉडलों को प्रशिक्षित करते समय पंजीकृत डिफ़ॉल्ट कॉलबैक में से एक इतिहास कॉलबैक है। यह प्रत्येक युग के लिए प्रशिक्षण मेट्रिक्स रिकॉर्ड करता है। इसमें हानि और सटीकता (वर्गीकरण समस्याओं के लिए) और यदि कोई सेट किया गया है तो सत्यापन डेटासेट के लिए हानि और सटीकता शामिल है।

मॉडल को प्रशिक्षित करने के लिए उपयोग किए जाने वाले फिट() फ़ंक्शन पर कॉल से इतिहास ऑब्जेक्ट वापस कर दिया जाता है। मेट्रिक्स लौटाए गए ऑब्जेक्ट के इतिहास सदस्य में एक शब्दकोश में संग्रहीत होते हैं।

उदाहरण के लिए, आप किसी मॉडल को प्रशिक्षित करने के बाद कोड के निम्नलिखित स्निपेट का उपयोग करके इतिहास ऑब्जेक्ट में एकत्रित मेट्रिक्स को सूचीबद्ध कर सकते हैं:

# list all data in history
print(history.history.keys())

आउटपुट:

['सटीकता', 'हानि', 'वैल_सटीकता', 'वैल_लॉस']

सूचना प्रकार

आप प्रशिक्षण डेटा की जानकारी के बारे में दो प्रकार की सोच सकते हैं:

  • सिग्नल: सिग्नल वह हिस्सा है जो सामान्यीकरण करता है, वह हिस्सा जो हमारे मॉडल को नए डेटा से भविष्यवाणियां करने में मदद कर सकता है।
  • शोर: शोर वह हिस्सा है जो केवल प्रशिक्षण डेटा के लिए सच है; शोर सभी यादृच्छिक उतार-चढ़ाव है जो वास्तविक दुनिया में डेटा या सभी आकस्मिक, गैर-सूचनात्मक पैटर्न से आता है जो वास्तव में मॉडल को भविष्यवाणियां करने में मदद नहीं कर सकता है। शोर वह हिस्सा है जो उपयोगी लग सकता है लेकिन वास्तव में ऐसा नहीं है।

जब हम किसी मॉडल को प्रशिक्षित करते हैं तो हम युग दर युग प्रशिक्षण सेट पर होने वाले नुकसान की साजिश रचते रहते हैं। इसमें हम सत्यापन डेटा का एक प्लॉट भी जोड़ देंगे। इन कथानकों को हम अधिगम वक्र कहते हैं। गहन शिक्षण मॉडलों को प्रभावी ढंग से प्रशिक्षित करने के लिए, हमें उनकी व्याख्या करने में सक्षम होने की आवश्यकता है।

सीखने की अवस्थाएँ

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

ओवरफिटिंग से बचने के उपाय

अब हमने कुछ परिदृश्य देख लिए हैं और ओवरफिटिंग का पता लगाने के लिए सीखने की अवस्थाओं की व्याख्या कैसे की जाए। आइए तंत्रिका नेटवर्क में ओवरफिटिंग से बचने के लिए कुछ तरीकों की जाँच करें:

विधि 1: अधिक डेटा का उपयोग करें

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

विधि 2: जल्दी रुकना

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

अंडरफिटिंग और ओवरफिटिंग

विधि 3: ड्रॉपआउट

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

ड्रॉपआउट के पीछे यही विचार है. इन साजिशों को तोड़ने के लिए, हम प्रशिक्षण के हर चरण में एक परत की इनपुट इकाइयों के कुछ अंश को बेतरतीब ढंग से छोड़ देते हैं, जिससे नेटवर्क के लिए प्रशिक्षण डेटा में उन नकली पैटर्न को सीखना बहुत कठिन हो जाता है। इसके बजाय, इसे व्यापक, सामान्य पैटर्न की खोज करनी होगी, जिनके वजन पैटर्न अधिक मजबूत होते हैं। 

आप ड्रॉपआउट के बारे में एक प्रकार के नेटवर्क का समूह बनाने के बारे में भी सोच सकते हैं। भविष्यवाणियाँ अब एक बड़े नेटवर्क द्वारा नहीं, बल्कि छोटे नेटवर्कों की एक समिति द्वारा की जाएंगी। समिति में व्यक्ति विभिन्न प्रकार की गलतियाँ करते हैं, लेकिन साथ ही सही भी होते हैं, जिससे समिति समग्र रूप से किसी भी व्यक्ति से बेहतर बन जाती है। (यदि आप निर्णय वृक्षों के समूह के रूप में यादृच्छिक वनों से परिचित हैं, तो यह वही विचार है।)

कन्वनेट्स में ओवरफिटिंग

विधि4: बैच सामान्यीकरण

अगली विशेष विधि जिसे हम देखेंगे वह "बैच सामान्यीकरण" (या "बैचनॉर्म") करती है, जो धीमी या अस्थिर प्रशिक्षण को सही करने में मदद कर सकती है।

तंत्रिका नेटवर्क के साथ, आमतौर पर अपने सभी डेटा को एक सामान्य पैमाने पर रखना एक अच्छा विचार है, शायद स्किकिट-लर्न के स्टैंडर्डस्केलर या मिनमैक्सस्केलर जैसी किसी चीज़ के साथ। इसका कारण यह है कि SGD नेटवर्क भार को उस अनुपात में स्थानांतरित कर देगा, जितना डेटा सक्रियण उत्पन्न करता है। ऐसी विशेषताएँ जो बहुत भिन्न आकारों की सक्रियताएँ उत्पन्न करती हैं, अस्थिर प्रशिक्षण व्यवहार का कारण बन सकती हैं।

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

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

विधि5: एल1 और एल2 नियमितीकरण

एल1 और एल2 नियमितीकरण ऐसी तकनीकें हैं जिनका उपयोग तंत्रिका नेटवर्क में बड़े भार को दंडित करके ओवरफिटिंग को रोकने के लिए किया जाता है। एल1 नियमितीकरण वजन के पूर्ण मूल्य के आनुपातिक हानि फ़ंक्शन में एक दंड शब्द जोड़ता है। यह वज़न में विरलता को प्रोत्साहित करता है और फीचर चयन को जन्म दे सकता है। L2 नियमितीकरण, जिसे वज़न क्षय के रूप में भी जाना जाता है, हानि फ़ंक्शन में वज़न के वर्ग के अनुपात में एक दंड शब्द जोड़ता है। यह वज़न को बहुत बड़ा होने से रोकता है और वज़न के वितरण को अधिक समान रूप से फैलाने के लिए प्रोत्साहित करता है।

एल1 और एल2 नियमितीकरण के बीच का चुनाव अक्सर विशिष्ट समस्या और मॉडल के वांछित गुणों पर निर्भर करता है।

L1/L2 नियमितीकरण के लिए बड़े मान होने से मॉडल तेजी से नहीं सीख पाएगा और सीखने में एक पठार पर पहुंच जाएगा, जिससे मॉडल कमजोर हो जाएगा। 

विधि 6: डेटा संवर्द्धन

मशीन लर्निंग मॉडल के प्रदर्शन को बेहतर बनाने का सबसे अच्छा तरीका इसे अधिक डेटा पर प्रशिक्षित करना है। मॉडल को जितने अधिक उदाहरणों से सीखना होगा, वह उतना ही बेहतर ढंग से यह पहचानने में सक्षम होगा कि छवियों में कौन सा अंतर मायने रखता है और कौन सा नहीं। अधिक डेटा मॉडल को बेहतर सामान्यीकरण करने में मदद करता है।

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

और डेटा वृद्धि के पीछे यही पूरा विचार है: कुछ अतिरिक्त नकली डेटा जोड़ें जो वास्तविक डेटा की तरह दिखता है और आपके क्लासिफायरियर में सुधार होगा। 

याद रखें, ओवरफिटिंग से बचने की कुंजी यह सुनिश्चित करना है कि आपका मॉडल अच्छी तरह से सामान्यीकृत हो। हमेशा अपने मॉडल के प्रदर्शन को केवल प्रशिक्षण सेट पर ही नहीं, बल्कि सत्यापन सेट पर भी जांचें।

डेटा के साथ उपरोक्त विधियों का कार्यान्वयन

आइए उपरोक्त विधियों के कार्यान्वयन चरणों का पता लगाएं:

चरण 1: आवश्यक पुस्तकालय लोड हो रहे हैं

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow.keras import datasets, layers, models
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.callbacks import ModelCheckpoint
import keras
from keras.preprocessing import image
from keras import models, layers, regularizers
from tqdm import tqdm
import warnings
warnings.filterwarnings(action='ignore')

चरण 2: डेटासेट लोड करना और प्रीप्रोसेसिंग करना

#Here all the images are in the form of a numpy array
cifar10 = tf.keras.datasets.cifar10
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
x_train = x_train / 255.0
x_test = x_test / 255.0

चरण 3: डेटासेट सीखना

x_train.shape, y_train.shape, x_test.shape, y_test.shape 

आउटपुट:

उत्पादन
np.unique(y_train)

आउटपुट:

उत्पादन
#These labels are in the order and taken from the documentaion
class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer',
               'dog', 'frog', 'horse', 'ship', 'truck']

चरण 4: डेटासेट से छवि विज़ुअलाइज़ करना

def show_image(IMG_INDEX):
    plt.imshow(x_train[20] ,cmap=plt.cm.binary)
    plt.xlabel(class_names[y_train[IMG_INDEX][0]])
    plt.show()
show_image(20)
कन्वनेट्स में ओवरफिटिंग
model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)))
model.add(layers.AveragePooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.AveragePooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10))
model.summary()

आइए अब ऑप्टिमाइज़र, लॉस फ़ंक्शन और मूल्यांकन मीट्रिक के साथ हाइपर पैरामीटर्स और कंपाइलिंग मॉडल को आरंभ करें।


train_hyperparameters_config={'optim':keras.optimizers.Adam(learning_rate=0.001),
                             'epochs':20,
                              'batch_size':16
                             }
model.compile(optimizer=train_hyperparameters_config['optim'],
                  loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
                  metrics=['accuracy'])

चरण 6: प्रशिक्षण मॉडल

history = model.fit(x_train, y_train, 
                        epochs=train_hyperparameters_config['epochs'], 
                        batch_size=train_hyperparameters_config['batch_size'], 
                        verbose=1,
                        validation_data=(x_test, y_test))

चरण7: मॉडल का मूल्यांकन करें

ये हमें इतिहास वस्तु में निहित जानकारी बताएंगे और हम उनका उपयोग अपनी सूचना वक्र बनाने के लिए करेंगे।

print(history.history.keys()) 
def learning_curves(history):
# Plotting Accuracy
    plt.figure(figsize=(14, 5))  # Adjust the figure size as needed
    plt.subplot(1, 2, 1)  # Subplot with 1 row, 2 columns, and index 1
    plt.plot(history.history['accuracy'], label='train_accuracy', marker='s', markersize=4)
    plt.plot(history.history['val_accuracy'], label='val_accuracy', marker='*', markersize=4)
    plt.xlabel('Epoch')
    plt.ylabel('Accuracy')
    plt.legend(loc='lower right')

    # Plotting Loss
    plt.subplot(1, 2, 2)  # Subplot with 1 row, 2 columns, and index 2
    plt.plot(history.history['loss'], label='train_loss', marker='s', markersize=4)
    plt.plot(history.history['val_loss'], label='val_loss', marker='*', markersize=4)
    plt.xlabel('Epoch')
    plt.ylabel('Loss')
    plt.legend(loc='lower right')

    plt.show()
learning_curves(history)
कन्वनेट्स में ओवरफिटिंग

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

चरण8: शीघ्र रोकथाम लागू करना

चूँकि हम अपने मॉडल के ओवरफिट होने के बारे में चिंतित नहीं हैं क्योंकि जल्दी रुकने से हमारा मॉडल ऐसा होने से बच जाएगा। अधिक संख्या में युगों और उपयुक्त धैर्य का चयन करना एक अच्छा विकल्प है। अब हम उसी मॉडल आर्किटेक्चर का उपयोग करेंगे और कॉलबैक को जल्दी रोकने के साथ प्रशिक्षित करेंगे। 

model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)))
model.add(layers.AveragePooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.AveragePooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.Flatten())
model.add(layers.Dense(128, activation='relu'))
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10))
model.summary()

# Here we have used more epochs than needed since we use patience parameter which we stop the model from overfitting
train_hyperparameters_config = {
    'optim': keras.optimizers.Adam(learning_rate=0.001),
    'patience': 5,
    'epochs': 50,
    'batch_size': 32, 
}
print('Setting the callback and early stopping configurations...')
callback = tf.keras.callbacks.EarlyStopping(
    monitor='val_loss', 
    min_delta=0.001, # minimium amount of change to count as an improvement
    patience=train_hyperparameters_config['patience'], 
    restore_best_weights=True)

def model_train(model, x_train, y_train, x_test, y_test, train_hyperparameters_config):
    model.compile(optimizer=train_hyperparameters_config['optim'],
                      loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
                      metrics=['accuracy'])
    ht = model.fit(x_train, y_train, 
                            epochs=train_hyperparameters_config['epochs'], 
                            batch_size=train_hyperparameters_config['batch_size'],
                            callbacks=[callback],
                            verbose=1,
                            validation_data=(x_test, y_test))
    return ht

ht=model_train(model, x_train, y_train, x_test, y_test, train_hyperparameters_config)
learning_curves(ht)
कन्वनेट्स में ओवरफिटिंग

मॉडल द्वारा उठाए गए हमारे सर्वोत्तम वजन को जानने के लिए। 

print('Testing ..................')
test_loss, test_acc = model.evaluate(x_test,  y_test, verbose=2)
print('test_loss : ', test_loss, 'test_accuracy : ', test_acc)

चरण9: मॉडल जटिलता बढ़ाना

चूँकि हमारा मॉडल अच्छा प्रदर्शन नहीं कर रहा है और पर्याप्त डेटा कैप्चर करने में सक्षम नहीं है। हमें अपने मॉडल की जटिलता बढ़ानी चाहिए और मूल्यांकन करना चाहिए। 

model = models.Sequential()

model.add(layers.Conv2D(128, (3, 3), activation='relu', input_shape=(32, 32, 3)))
model.add(layers.MaxPooling2D((2, 2)))

model.add(layers.Conv2D(256, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))

model.add(layers.Conv2D(256, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))

model.add(layers.Conv2D(512, (3, 3), activation='relu', padding='same'))
model.add(layers.MaxPooling2D((2, 2)))

model.add(layers.Flatten())
model.add(layers.Dense(256, activation='relu'))
model.add(layers.Dense(128, activation='relu'))
model.add(layers.Dense(10, activation='softmax'))
model.summary()
उत्पादन

हम देख सकते हैं कि कुल मापदंडों में वृद्धि हुई है। इससे हमारे मॉडल में अधिक जटिल संबंध खोजने में मदद मिलेगी। नोट: हमारा डेटासेट 32X32 छवियों का है; ये अपेक्षाकृत छोटी छवियां हैं। इसलिए शुरुआत में अधिक जटिल मॉडल का उपयोग निश्चित रूप से मॉडल पर हावी हो जाएगा इसलिए हम अपने मॉडल की जटिलता को धीरे-धीरे बढ़ाते हैं।

# Here we have used more epochs than needed since we use patience parameter which we stop the model from overfitting
train_hyperparameters_config = {
    'optim': keras.optimizers.Adam(learning_rate=0.001),
    'patience': 5,
    'epochs': 50,
    'batch_size': 32, 
}
print('Setting the callback and early stopping configurations...')
callback = tf.keras.callbacks.EarlyStopping(
    monitor='val_loss', 
    min_delta=0.001, # minimium amount of change to count as an improvement
    patience=train_hyperparameters_config['patience'], 
    restore_best_weights=True)
ht=model_train(model, x_train, y_train, x_test, y_test, train_hyperparameters_config)

learning_curves(ht)
कन्वनेट्स में ओवरफिटिंग
print('Testing ..................')
test_loss, test_acc = model.evaluate(x_test,  y_test, verbose=2)
print('test_loss : ', test_loss, 'test_accuracy : ', test_acc)

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

चरण10: ड्रॉपआउट परतें और बैच सामान्यीकरण परतें का उपयोग करना

model = models.Sequential()

model.add(layers.Conv2D(128, (3, 3), activation='relu', input_shape=(32, 32, 3)))
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling2D((2, 2)))

model.add(layers.Conv2D(256, (3, 3), activation='relu'))
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling2D((2, 2)))

model.add(layers.Conv2D(256, (3, 3), activation='relu'))
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling2D((2, 2)))

model.add(layers.Conv2D(512, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling2D((2, 2)))

model.add(layers.Flatten())
model.add(layers.Dense(256, activation='relu'))
model.add(layers.BatchNormalization())
model.add(layers.Dropout(0.3))

model.add(layers.Dense(128, activation='relu'))
model.add(layers.BatchNormalization())
model.add(layers.Dropout(0.3))

model.add(layers.Dense(10, activation='softmax'))
model.summary()
उत्पादन
# Here we have used more epochs than needed since we use patience parameter which we stop the model from overfitting
train_hyperparameters_config = {
    'optim': keras.optimizers.Adam(learning_rate=0.001),
    'patience': 5,
    'epochs': 50,
    'batch_size': 32, 
}
print('Setting the callback and early stopping configurations...')
callback = tf.keras.callbacks.EarlyStopping(
    monitor='val_loss', 
    min_delta=0.001, # minimium amount of change to count as an improvement
    patience=train_hyperparameters_config['patience'], 
    restore_best_weights=True)
ht=model_train(model, x_train, y_train, x_test, y_test, train_hyperparameters_config)
learning_curves(ht)
कन्वनेट्स में ओवरफिटिंग
print('Testing ..................')
test_loss, test_acc = model.evaluate(x_test,  y_test, verbose=2)
print('test_loss : ', test_loss, 'test_accuracy : ', test_acc)

सीखने के ग्राफ़ से हम देख सकते हैं कि मॉडल बैचनॉर्मलाइज़ेशन और ड्रॉपआउट परतों के साथ भी ओवरफिटिंग कर रहा है। इसलिए जटिलता बढ़ाने के बजाय फ़िल्टर की संख्या बढ़ाएँ। अधिक सुविधाएँ निकालने के लिए हम अधिक कनवल्शन परतें जोड़ेंगे।

चरण11: कनवल्शन परतें बढ़ाना

अधिक सुविधाएँ निकालने के लिए प्रशिक्षण योग्य पैरामीटर को कम करें लेकिन कनवल्शन परतों को बढ़ाएँ।

model = models.Sequential()

model.add(layers.Conv2D(32, (3, 3), activation='relu', padding='same', input_shape=(32, 32, 3)))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(32, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.MaxPool2D((2, 2)))
model.add(layers.Dropout(0.2))

model.add(layers.Conv2D(64, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(64, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.MaxPool2D((2, 2)))
model.add(layers.Dropout(0.3))

model.add(layers.Conv2D(128, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(128, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.MaxPool2D((2, 2)))
model.add(layers.Dropout(0.4))

model.add(layers.Flatten())
model.add(layers.Dense(128, activation='relu'))
model.add(layers.BatchNormalization())
model.add(layers.Dropout(0.5))

model.add(layers.Dense(10, activation='softmax'))

model.summary()
# Here we have used more epochs than needed since we use patience parameter which we stop the model from overfitting
train_hyperparameters_config = {
    'optim': keras.optimizers.Adam(learning_rate=0.001),
    'patience': 5,
    'epochs': 50,
    'batch_size': 32, 
}
print('Setting the callback and early stopping configurations...')
callback = tf.keras.callbacks.EarlyStopping(
    monitor='val_loss', 
    min_delta=0.001, # minimium amount of change to count as an improvement
    patience=train_hyperparameters_config['patience'], 
    restore_best_weights=True)
ht=model_train(model, x_train, y_train, x_test, y_test, train_hyperparameters_config)
उत्पादन
learning_curves(ht)
कन्वनेट्स में ओवरफिटिंग
print('Testing ..................')
test_loss, test_acc = model.evaluate(x_test,  y_test, verbose=2)
print('test_loss : ', test_loss, 'test_accuracy : ', test_acc)

उपरोक्त आउटपुट और लर्निंग कर्व से हम यह अनुमान लगा सकते हैं कि मॉडल ने बहुत अच्छा प्रदर्शन किया है और ओवरफिटिंग से बचा है। प्रशिक्षण सटीकता और सत्यापन सटीकता बहुत करीब हैं। इस परिदृश्य में हमें ओवरफिटिंग को कम करने के लिए अधिक तरीकों की आवश्यकता नहीं होगी। फिर भी हम L1/L2 नियमितीकरण का पता लगाएंगे। 

चरण12: एल1/एल2 नियमितीकरण का उपयोग करना

from tensorflow.keras import regularizers

model = models.Sequential()

model.add(layers.Conv2D(32, (3, 3), activation='relu', padding='same', input_shape=(32, 32, 3)))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(32, (3, 3), activation='relu', padding='same', kernel_regularizer=regularizers.l1(0.0005)))
model.add(layers.BatchNormalization())
model.add(layers.MaxPool2D((2, 2)))
model.add(layers.Dropout(0.2))

model.add(layers.Conv2D(64, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(64, (3, 3), activation='relu', padding='same', kernel_regularizer=regularizers.l2(0.0005)))
model.add(layers.BatchNormalization())
model.add(layers.MaxPool2D((2, 2)))
model.add(layers.Dropout(0.3))

model.add(layers.Conv2D(128, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(128, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.MaxPool2D((2, 2)))
model.add(layers.Dropout(0.4))

model.add(layers.Flatten())
model.add(layers.Dense(128, activation='relu', kernel_regularizer=regularizers.l1_l2(0.0005, 0.0005)))
model.add(layers.BatchNormalization())
model.add(layers.Dropout(0.5))
model.add(layers.Dense(10, activation='softmax'))

model.summary()
# Here we have used more epochs than needed since we use patience parameter which we stop the model from overfitting
train_hyperparameters_config = {
    'optim': keras.optimizers.Adam(learning_rate=0.001),
    'patience': 7,
    'epochs': 70,
    'batch_size': 32, 
}
print('Setting the callback and early stopping configurations...')
callback = tf.keras.callbacks.EarlyStopping(
    monitor='val_loss', 
    min_delta=0.001, # minimium amount of change to count as an improvement
    patience=train_hyperparameters_config['patience'], 
    restore_best_weights=True)
ht=model_train(model, x_train, y_train, x_test, y_test, train_hyperparameters_config)
learning_curves(ht)
कन्वनेट्स में ओवरफिटिंग
print('Testing ..................')
test_loss, test_acc = model.evaluate(x_test,  y_test, verbose=2)
print('test_loss : ', test_loss, 'test_accuracy : ', test_acc)

अब हम देख सकते हैं कि 1 के कम पेनल्टी स्कोर का उपयोग करने के बाद भी एल2/एल0.0001 नियमितीकरण ने हमारे मॉडल को 4% कम कर दिया। इसलिए सलाह दी जाती है कि सभी तरीकों का सावधानीपूर्वक एक साथ उपयोग करें। चूंकि बैच सामान्यीकरण और नियमितीकरण मॉडल को उसी तरह प्रभावित करते हैं, इसलिए हमें L1/L2 नियमितीकरण की आवश्यकता नहीं होगी। 

चरण 13: डेटा संवर्द्धन

हम टेंसरफ़्लो केरस से ImageDataGenerator का उपयोग करेंगे।

# creates a data generator object that transforms images
datagen = ImageDataGenerator(
rotation_range=40,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
fill_mode='nearest')

# pick an image to transform
test_img = x_train[20]
img = image.img_to_array(test_img)  # convert image to numpy arry
img = img.reshape((1,) + img.shape)  # reshape image

i = 0

for batch in datagen.flow(img, save_prefix='test', save_format='jpeg'):  # this loops runs forever until we break, saving images to current directory with specified prefix
    plt.figure(i)
    plot = plt.imshow(image.img_to_array(batch[0]))
    i += 1
    if i > 4:  # show 4 images
        break

plt.show()
कन्वनेट्स में ओवरफिटिंग

ये चार संवर्धित छवियाँ और एक मूल छवि हैं।

# Create an instance of the ImageDataGenerator
datagen = ImageDataGenerator(
    rotation_range=40,
    width_shift_range=0.2,
    height_shift_range=0.2,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True,
    fill_mode='nearest'
)

# Create an iterator for the data generator
data_generator = datagen.flow(x_train, y_train, batch_size=32)

# Create empty lists to store the augmented images and labels
augmented_images = []
augmented_labels = []

# Loop over the data generator and append the augmented data to the lists
num_batches = len(x_train) // 32
progress_bar = tqdm(total=num_batches, desc="Augmenting data", unit="batch")

for i in range(num_batches):
    batch_images, batch_labels = next(data_generator)
    augmented_images.append(batch_images)
    augmented_labels.append(batch_labels)
    progress_bar.update(1)

progress_bar.close()

# Convert the lists to NumPy arrays
augmented_images = np.concatenate(augmented_images, axis=0)
augmented_labels = np.concatenate(augmented_labels, axis=0)

# Combine the original and augmented data
x_train_augmented = np.concatenate((x_train, augmented_images), axis=0)
y_train_augmented = np.concatenate((y_train, augmented_labels), axis=0)
उत्पादन

हमने अपनी वृद्धि की प्रगति जानने के लिए tqdm लाइब्रेरी का उपयोग किया है।

x_train_augmented.shape, y_train_augmented.shape
उत्पादन

संवर्द्धन के बाद यह हमारा डेटासेट है। आइए अब इस डेटासेट का उपयोग करें और अपने मॉडल को प्रशिक्षित करें।

model = models.Sequential()

model.add(layers.Conv2D(32, (3, 3), activation='relu', padding='same', input_shape=(32, 32, 3)))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(32, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.MaxPool2D((2, 2)))
model.add(layers.Dropout(0.2))

model.add(layers.Conv2D(64, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(64, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.MaxPool2D((2, 2)))
model.add(layers.Dropout(0.3))

model.add(layers.Conv2D(128, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(128, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.MaxPool2D((2, 2)))
model.add(layers.Dropout(0.4))

model.add(layers.Flatten())
model.add(layers.Dense(128, activation='relu'))
model.add(layers.BatchNormalization())
model.add(layers.Dropout(0.5))

model.add(layers.Dense(10, activation='softmax'))

model.summary()

# Here we have used more epochs than needed since we use patience parameter which we stop the model from overfitting
train_hyperparameters_config = {
    'optim': keras.optimizers.Adam(learning_rate=0.001),
    'patience': 10,
    'epochs': 70,
    'batch_size': 32, 
}
print('Setting the callback and early stopping configurations...')
callback = tf.keras.callbacks.EarlyStopping(
    monitor='val_loss', 
    min_delta=0.001, # minimium amount of change to count as an improvement
    patience=train_hyperparameters_config['patience'], 
    restore_best_weights=True)

ht=model_train(model, x_train_augmented, y_train_augmented, x_test, y_test, train_hyperparameters_config)


learning_curves(ht)
कन्वनेट्स में ओवरफिटिंग
print('Testing ..................')
test_loss, test_acc = model.evaluate(x_test,  y_test, verbose=2)
print('test_loss : ', test_loss, 'test_accuracy : ', test_acc)

हम देख सकते हैं कि मॉडल अधिक सामान्यीकृत है और नुकसान में कमी आई है। हमें बेहतर सत्यापन सटीकता भी मिली है। इसलिए डेटा संवर्द्धन ने हमारे मॉडल की सटीकता में वृद्धि की है। 

निष्कर्ष

गहन शिक्षण में ओवरफिटिंग एक आम समस्या है, विशेष रूप से कन्वनेट्स जैसे जटिल तंत्रिका नेटवर्क आर्किटेक्चर के साथ। व्यवसायी इसके मूल कारणों को समझकर और उन परिदृश्यों को पहचानकर कन्वनेट्स में ओवरफिटिंग को रोक सकते हैं जहां यह होता है। जल्दी रोकना, ड्रॉपआउट, बैच सामान्यीकरण, नियमितीकरण और डेटा वृद्धि जैसी तकनीकें इस समस्या को कम करने में मदद कर सकती हैं। CIFAR-10 डेटासेट पर इन तकनीकों को लागू करने से मॉडल सामान्यीकरण और प्रदर्शन में महत्वपूर्ण सुधार देखा गया। इन तकनीकों में महारत हासिल करने और उनके सिद्धांतों को समझने से मजबूत और विश्वसनीय तंत्रिका नेटवर्क मॉडल तैयार हो सकते हैं।

आम सवाल-जवाब

Q1. ओवरफिटिंग क्या है और यह गहन शिक्षण में समस्या क्यों है? 

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

Q2. मैं अपने तंत्रिका नेटवर्क मॉडल में ओवरफिटिंग का पता कैसे लगा सकता हूँ?

उ. आप सीखने के वक्रों की व्याख्या करके कन्वनेट्स में ओवरफिटिंग का पता लगा सकते हैं, जो युगों के दौरान प्रशिक्षण और सत्यापन मेट्रिक्स (उदाहरण के लिए, हानि, सटीकता) की साजिश रचते हैं। यदि प्रशिक्षण मेट्रिक्स में सुधार जारी रहने के दौरान सत्यापन मेट्रिक्स में सुधार होना बंद हो जाता है या गिरावट शुरू हो जाती है, तो यह ओवरफिटिंग का संकेत है।

Q3. जल्दी रुकना क्या है और यह ओवरफिटिंग को रोकने में कैसे मदद करता है?

A. अर्ली स्टॉपिंग एक ऐसी तकनीक है जो प्रशिक्षण के दौरान सत्यापन सेट पर मॉडल के प्रदर्शन की निगरानी करती है और जब सत्यापन सेट पर प्रदर्शन खराब होने लगता है, तो ओवरफिटिंग का संकेत मिलने पर प्रशिक्षण प्रक्रिया को रोक दिया जाता है। यह सही समय पर प्रशिक्षण रोककर मॉडल को ओवरफिटिंग से रोकने में मदद करता है।

Q4. डेटा संवर्द्धन ओवरफिटिंग को कम करने में कैसे मदद करता है? 

A. डेटा संवर्द्धन मौजूदा डेटा में परिवर्तन (जैसे फ़्लिपिंग, रोटेटिंग, स्केलिंग) लागू करके नए, सिंथेटिक प्रशिक्षण डेटा उत्पन्न करने की प्रक्रिया है। यह मॉडल को अधिक विविध उदाहरणों के सामने लाकर बेहतर सामान्यीकरण में मदद करता है, जिससे सीमित प्रशिक्षण डेटा में कन्वनेट्स में ओवरफिटिंग का जोखिम कम हो जाता है।

स्पॉट_आईएमजी

नवीनतम खुफिया

स्पॉट_आईएमजी