मुख्य सामग्री पर जाएँ

Keras के साथ Python में कॉन्वोल्यूशनल न्यूरल नेटवर्क्स

इस ट्यूटोरियल में, आप Python में Keras के साथ Convolutional Neural Networks (CNNs) को लागू करना और ड्रॉपआउट के ज़रिए ओवरफिटिंग से निपटना सीखेंगे।
· 15 मि॰ पढ़ें

AI के साथ खोजें

आपने शायद पहले ही इमेज या फेशियल रिकग्निशन या सेल्फ-ड्राइविंग कारों के बारे में सुना होगा। ये Convolutional Neural Networks (CNNs) के वास्तविक जीवन में उपयोग हैं। इस ब्लॉग पोस्ट में, आप सीखेंगे और समझेंगे कि Keras में इन डीप, फीड-फॉरवर्ड आर्टिफिशियल न्यूरल नेटवर्क्स को कैसे इम्प्लीमेंट किया जाता है और साथ ही "ड्रॉपआउट" नामक रेग्युलराइज़ेशन तकनीक से ओवरफिटिंग पर काबू पाना भी सीखेंगे।

खास तौर पर, आज के ट्यूटोरियल में आप निम्नलिखित विषयों से निपटेंगे:

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

क्या आप Python में Keras और डीप लर्निंग पर कोर्स करना चाहेंगे? DataCamp का Deep Learning in Python कोर्स करने पर विचार करें!

साथ ही, हमारा Keras चीट शीट न चूकें, जो आपको Python में कोड उदाहरणों के साथ न्यूरल नेटवर्क बनाने के लिए आवश्यक छह चरण दिखाती है!

कॉन्वोल्यूशनल न्यूरल नेटवर्क: परिचय

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

ऐसा ही एक विशेष प्रकार का डीप न्यूरल नेटवर्क कॉन्वोल्यूशनल नेटवर्क है, जिसे आमतौर पर CNN या ConvNet कहा जाता है। यह एक डीप, फीड-फॉरवर्ड आर्टिफिशियल न्यूरल नेटवर्क है। याद रखें कि फीड-फॉरवर्ड न्यूरल नेटवर्क्स को मल्टी-लेयर परसेप्ट्रॉन्स (MLPs) भी कहा जाता है, जो क्विंटेसेंशियल डीप लर्निंग मॉडल हैं। इन्हें "फीड-फॉरवर्ड" इसलिए कहा जाता है क्योंकि सूचना सीधे मॉडल के आर-पार बहती है। ऐसे कोई फीडबैक कनेक्शन नहीं होते जिनमें मॉडल के आउटपुट्स को वापस उसी में फीड किया जाए।

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

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

  • इमेज क्लासिफिकेशन, ऑब्जेक्ट डिटेक्शन, सेगमेंटेशन, फेस रिकग्निशन;
  • CNN-आधारित विज़न सिस्टम का उपयोग करने वाली सेल्फ-ड्राइविंग कारें;
  • कॉन्वोल्यूशनल न्यूरल नेटवर्क का उपयोग करके क्रिस्टल स्ट्रक्चर का वर्गीकरण;
  • और भी बहुत कुछ!

इस सफलता को समझने के लिए, आपको 2012 में जाना होगा, जब Alex Krizhevsky ने उस वर्ष की ImageNet Competition जीतने के लिए कॉन्वोल्यूशनल न्यूरल नेटवर्क्स का उपयोग किया, और क्लासिफिकेशन त्रुटि को 26% से घटाकर 15% कर दिया।

नोट कि ImageNet Large Scale Visual Recognition Challenge (ILSVRC), जो 2010 में शुरू हुई, एक वार्षिक प्रतियोगिता है जहाँ शोध टीमें अपने एल्गोरिद्म को दिए गए डेटा सेट पर परखती हैं और कई विज़ुअल रिकग्निशन कार्यों पर उच्चतर सटीकता प्राप्त करने के लिए प्रतिस्पर्धा करती हैं।

यही वह समय था जब न्यूरल नेटवर्क्स ने काफी समय बाद फिर से प्रमुखता हासिल की। इसे अक्सर "न्यूरल नेटवर्क्स की तीसरी लहर" कहा जाता है। बाकी दो लहरें 1940 के दशक से 1960 के दशक तक और 1970 से 1980 के दशक तक रहीं।

ठीक है, आप जानते हैं कि आप फीड-फॉरवर्ड नेटवर्क्स के साथ काम करेंगे जो जैविक विज़ुअल कॉर्टेक्स से प्रेरित हैं, लेकिन इसका वास्तव में मतलब क्या है?

नीचे दी गई तस्वीर पर नज़र डालें:

Convolutional neural network
चित्र: कॉन्वोल्यूशनल न्यूरल नेटवर्क, स्रोत: Wikimedia

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

लेकिन ये सभी अवधारणाएँ क्या हैं?

  1. कॉन्वोल्यूशन लेयर इनपुट में स्थानीय क्षेत्रों या रिसेप्टिव फील्ड्स से जुड़े न्यूरॉन्स का आउटपुट गणना करती है, जिनमें से प्रत्येक अपने वेट्स और इनपुट वॉल्यूम में जुड़े छोटे रिसेप्टिव फील्ड के बीच डॉट प्रोडक्ट गणना करता है। हर गणना इनपुट इमेज से एक फीचर मैप निकालती है। दूसरे शब्दों में, मान लीजिए आपके पास 5x5 मैट्रिक्स के रूप में एक इमेज है, और आप 3x3 का मैट्रिक्स लेते हैं और उसे इमेज पर स्लाइड करते हैं। उस 3x3 विंडो की हर स्थिति पर, आप अपनी 3x3 विंडो के मानों को इमेज के उन मानों से गुणा करते हैं जो विंडो के नीचे हैं। नतीजतन, आपको एक एकल संख्या मिलती है जो इमेज की उस विंडो के सभी मानों का प्रतिनिधित्व करती है। आप इस लेयर का उपयोग फिल्टरिंग के लिए करते हैं: जैसे-जैसे विंडो इमेज पर आगे बढ़ती है, आप इमेज के उस हिस्से में पैटर्न खोजते हैं। यह फिल्टर्स की वजह से काम करता है, जिन्हें कॉन्वोल्यूशन से निकले मानों से गुणा किया जाता है।
  2. सबसैंपलिंग का उद्देश्य इनपुट के निरूपण को उसकी डाइमेंशंस घटाकर प्राप्त करना है, जो ओवरफिटिंग को कम करने में सहायक होता है। सबसैंपलिंग की एक तकनीक मैक्स पूलिंग है। इस तकनीक में आप किसी क्षेत्र से उसके आकार के आधार पर सबसे बड़ा पिक्सल मान चुनते हैं। दूसरे शब्दों में, मैक्स पूलिंग इमेज की उस विंडो से सबसे बड़ा मान लेती है जिसे फिलहाल कर्नेल कवर कर रहा होता है। उदाहरण के लिए, 2 x 2 आकार की मैक्स-पूलिंग लेयर 2 x 2 क्षेत्र से अधिकतम पिक्सल इंटेंसिटी मान चुनेगी। आप सही सोच रहे हैं कि पूलिंग लेयर तब कॉन्वोल्यूशन लेयर की तरह ही काम करती है! आप भी एक कर्नेल या विंडो लेते हैं और उसे इमेज पर घुमाते हैं; फर्क केवल इतना है कि कर्नेल और इमेज विंडो पर लागू होने वाला फंक्शन रैखिक (लीनियर) नहीं होता।

    Max pooling
    चित्र: मैक्स-पूलिंग, स्रोत: Wikipedia
  3. फुली कनेक्टेड लेयर का उद्देश्य कॉन्वोल्यूशनल लेयर्स द्वारा सीखे गए हाई-लेवल फीचर्स को फ्लैट करना और सभी फीचर्स को संयोजित करना है। यह फ्लैट किया हुआ आउटपुट आउटपुट लेयर को पास करती है, जहाँ आप इनपुट क्लास लेबल का प्रेडिक्शन करने के लिए softmax क्लासिफायर या sigmoid का उपयोग करते हैं।

और अधिक जानकारी के लिए, आप यहाँ जा सकते हैं।

Fashion-MNIST डेटा सेट

आगे बढ़कर डेटा लोड करने से पहले, यह देख लेना अच्छा है कि आप वास्तव में किसके साथ काम करेंगे! Fashion-MNIST डेटा सेट Zalando के आर्टिकल इमेजेज़ का डेटा सेट है, जिसमें 10 श्रेणियों के 70,000 फैशन उत्पादों की 28x28 ग्रेस्केल इमेजेज़ हैं, और प्रति श्रेणी 7,000 इमेजेज़ हैं। ट्रेनिंग सेट में 60,000 इमेजेज़ हैं, और टेस्ट सेट में 10,000 इमेजेज़। आप इसे बाद में, जब आप अपना डेटा लोड कर लेंगे, दोबारा जाँच सकते हैं! ;)

Fashion-MNIST, MNIST डेटा सेट जैसा ही है जिसे आप शायद पहले से जानते हैं, और जिसका उपयोग आप हस्तलिखित अंकों को वर्गीकृत करने के लिए करते हैं। इसका मतलब है कि इमेज के आयाम, ट्रेनिंग और टेस्ट स्प्लिट्स MNIST डेटा सेट के समान हैं। टिप: यदि आप बाद वाले डेटा सेट के साथ वर्गीकरण कार्यों के लिए एक Multi-Layer Perceptron (MLP) को इम्प्लीमेंट करना सीखना चाहते हैं, तो इस Keras के साथ डीप लर्निंग ट्यूटोरियल पर जाएँ।

आप Fashion-MNIST डेटा सेट यहाँ पा सकते हैं, लेकिन आप इसे विशेष TensorFlow और Keras मॉड्यूल्स की मदद से भी लोड कर सकते हैं। आप अगली सेक्शन में देखेंगे कि यह कैसे काम करता है!

डेटा लोड करें

Keras के साथ datasets नामक एक लाइब्रेरी आती है, जिसका उपयोग आप डेटा सेट्स को बॉक्स से बाहर लोड करने के लिए कर सकते हैं: आप डेटा को सर्वर से डाउनलोड करते हैं और प्रक्रिया तेज़ हो जाती है क्योंकि आपको अब डेटा अपने कंप्यूटर पर डाउनलोड नहीं करना पड़ता। ट्रेन और टेस्ट इमेजेज़ उनके लेबल्स के साथ क्रमशः train_X, train_Y, test_X, test_Y वैरिएबल्स में लोड और संग्रहीत हो जाते हैं।

from keras.datasets import fashion_mnist
(train_X,train_Y), (test_X,test_Y) = fashion_mnist.load_data()
Using TensorFlow backend.

बहुत बढ़िया! यह काफ़ी आसान था, है न?

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

डेटा का विश्लेषण करें

अब देखते हैं कि डेटा सेट में इमेजेज़ कैसी दिखती हैं। भले ही अब तक आप इमेज के डाइमेंशंस जानते हैं, फिर भी इसे प्रोग्रामेटिक ढंग से विश्लेषित करना उपयोगी है: आपको इमेज पिक्सल्स को रिस्केल और इमेजेज़ को रिसाइज़ करना पड़ सकता है।

import numpy as np
from keras.utils import to_categorical
import matplotlib.pyplot as plt
%matplotlib inline

print('Training data shape : ', train_X.shape, train_Y.shape)

print('Testing data shape : ', test_X.shape, test_Y.shape)
('Training data shape : ', (60000, 28, 28), (60000,))
('Testing data shape : ', (10000, 28, 28), (10000,))

ऊपर के आउटपुट से आप देख सकते हैं कि ट्रेनिंग डेटा का आकार 60000 x 28 x 28 है क्योंकि 60,000 ट्रेनिंग सैंपल्स हैं, जिनमें से प्रत्येक 28 x 28 का है। इसी तरह, टेस्ट डेटा का आकार 10000 x 28 x 28 है क्योंकि 10,000 टेस्टिंग सैंपल्स हैं।

# Find the unique numbers from the train labels
classes = np.unique(train_Y)
nClasses = len(classes)
print('Total number of outputs : ', nClasses)
print('Output classes : ', classes)
('Total number of outputs : ', 10)
('Output classes : ', array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=uint8))

कुल मिलाकर दस आउटपुट क्लासेस हैं, जो 0 से 9 तक हैं।

साथ ही, यह देखना न भूलें कि आपके डेटा सेट में इमेजेज़ कैसी हैं:

plt.figure(figsize=[5,5])

# Display the first image in training data
plt.subplot(121)
plt.imshow(train_X[0,:,:], cmap='gray')
plt.title("Ground Truth : {}".format(train_Y[0]))

# Display the first image in testing data
plt.subplot(122)
plt.imshow(test_X[0,:,:], cmap='gray')
plt.title("Ground Truth : {}".format(test_Y[0]))
Text(0.5,1,u'Ground Truth : 9')

धुंधले टखने तक के बूट

ऊपर के दोनों प्लॉट्स का आउटपुट टखने तक के बूट जैसा दिखता है, और इस क्लास को 9 का लेबल दिया गया है। इसी प्रकार, अन्य फैशन उत्पादों के अलग-अलग लेबल होंगे, लेकिन समान उत्पादों के लेबल समान होंगे। इसका अर्थ है कि सभी 7,000 टखने तक के बूट इमेजेज़ का क्लास लेबल 9 होगा।

डेटा प्रीप्रोसेसिंग

जैसा कि आप ऊपर के प्लॉट में देख सके, इमेजेज़ ग्रेस्केल हैं और इनके पिक्सल मान 0 से 255 तक होते हैं। साथ ही, इन इमेजेज़ का आकार 28 x 28 है। परिणामस्वरूप, आपको मॉडल में फीड करने से पहले डेटा का प्रीप्रोसेस करना होगा।

  • पहले चरण के रूप में, ट्रेन और टेस्ट सेट की प्रत्येक 28 x 28 इमेज को 28 x 28 x 1 आकार की मैट्रिक्स में बदलें, जिसे नेटवर्क में फीड किया जाएगा।
train_X = train_X.reshape(-1, 28,28, 1)
test_X = test_X.reshape(-1, 28,28, 1)
train_X.shape, test_X.shape
((60000, 28, 28, 1), (10000, 28, 28, 1))
  • डेटा फिलहाल int8 फ़ॉर्मेट में है, इसलिए नेटवर्क में फीड करने से पहले आपको इसका प्रकार float32 में कनवर्ट करना होगा, और आपको पिक्सल मानों को 0 - 1 की रेंज में रिस्केल भी करना होगा। आइए यह करते हैं!
train_X = train_X.astype('float32')
test_X = test_X.astype('float32')
train_X = train_X / 255.
test_X = test_X / 255.
  • अब आपको क्लास लेबल्स को वन-हॉट एनकोडिंग वेक्टर में बदलना है।

वन-हॉट एनकोडिंग में आप श्रेणीबद्ध डेटा को संख्याओं के वेक्टर में बदलते हैं। मशीन लर्निंग एल्गोरिद्म सीधे श्रेणीबद्ध डेटा पर काम नहीं कर सकते, इसलिए आप वन-हॉट एनकोडिंग करते हैं। आप प्रत्येक श्रेणी या क्लास के लिए एक बूलियन कॉलम बनाते हैं। प्रत्येक सैंपल के लिए इन कॉलम्स में से केवल एक का मान 1 हो सकता है। इसलिए इसे वन-हॉट एनकोडिंग कहा जाता है।

आपकी समस्या के लिए, वन-हॉट एनकोडिंग एक रो वेक्टर होगा, और प्रत्येक इमेज के लिए इसका आकार 1 x 10 होगा। यहाँ महत्वपूर्ण बात यह है कि वेक्टर में सभी जगह 0 होंगे, सिवाय उस क्लास के जिसे वह दर्शाता है, और उसके लिए 1 होगा। उदाहरण के लिए, ऊपर प्लॉट की गई टखने तक के बूट की इमेज का लेबल 9 है, तो सभी टखने तक के बूट इमेजेज़ के लिए वन-हॉट एनकोडिंग वेक्टर [0 0 0 0 0 0 0 0 1 0] होगा।

तो आइए ट्रेनिंग और टेस्टिंग लेबल्स को वन-हॉट एनकोडिंग वेक्टर में बदलते हैं:

# Change the labels from categorical to one-hot encoding
train_Y_one_hot = to_categorical(train_Y)
test_Y_one_hot = to_categorical(test_Y)

# Display the change for category label using one-hot encoding
print('Original label:', train_Y[0])
print('After conversion to one-hot:', train_Y_one_hot[0])
('Original label:', 9)
('After conversion to one-hot:', array([ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.]))

यह काफ़ी स्पष्ट है, है न? नोट कि आप train_Y_one_hot को भी प्रिंट कर सकते हैं, जो 60000 x 10 आकार की मैट्रिक्स दिखाएगा जिसमें प्रत्येक पंक्ति एक इमेज की वन-हॉट एनकोडिंग दर्शाती है।

  • यह आखिरी चरण बेहद महत्वपूर्ण है। मशीन लर्निंग या किसी भी डेटा-विशिष्ट कार्य में, आपको डेटा का सही विभाजन करना चाहिए। मॉडल को अच्छी तरह सामान्यीकृत कराने के लिए, आप ट्रेनिंग डेटा को दो भागों में विभाजित करते हैं, एक ट्रेनिंग के लिए और दूसरा वैलिडेशन के लिए। इस मामले में, आप मॉडल को ट्रेनिंग डेटा के 80% पर ट्रेन करेंगे और शेष 20% पर वैलिडेट करेंगे। यह ओवरफिटिंग को कम करने में भी मदद करेगा क्योंकि आप उस डेटा पर वैलिडेट करेंगे जिसे मॉडल ने ट्रेनिंग फेज़ में नहीं देखा, जिससे टेस्ट प्रदर्शन बेहतर होगा।
from sklearn.model_selection import train_test_split
train_X,valid_X,train_label,valid_label = train_test_split(train_X, train_Y_one_hot, test_size=0.2, random_state=13)

एक आखिरी बार ट्रेनिंग और वैलिडेशन सेट के आकार की जाँच कर लेते हैं।

train_X.shape,valid_X.shape,train_label.shape,valid_label.shape
((48000, 28, 28, 1), (12000, 28, 28, 1), (48000, 10), (12000, 10))

नेटवर्क

इमेजेज़ का आकार 28 x 28 है। आप इमेज मैट्रिक्स को एक एरे में बदलते हैं, उसे 0 और 1 के बीच रिस्केल करते हैं, उसे 28 x 28 x 1 के आकार में रीशेप करते हैं, और इसे नेटवर्क के इनपुट के रूप में फीड करते हैं।

आप तीन कॉन्वोल्यूशनल लेयर्स का उपयोग करेंगे:

  • पहली लेयर में 32-3 x 3 फिल्टर्स होंगे,
  • दूसरी लेयर में 64-3 x 3 फिल्टर्स होंगे और
  • तीसरी लेयर में 128-3 x 3 फिल्टर्स होंगे।

इसके अतिरिक्त, 2 x 2 आकार की तीन मैक्स-पूलिंग लेयर्स हैं।

मॉडल की संरचना
चित्र: मॉडल की आर्किटेक्चर

डेटा का मॉडल बनाना

सबसे पहले, मॉडल को ट्रेन करने के लिए आवश्यक सभी मॉड्यूल्स इम्पोर्ट करते हैं।

import keras
from keras.models import Sequential,Input,Model
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras.layers.normalization import BatchNormalization
from keras.layers.advanced_activations import LeakyReLU

आप 64 का बैच साइज उपयोग करेंगे; 128 या 256 जैसे अधिक बैच साइज का उपयोग करना भी संभव है, यह मेमोरी पर निर्भर करता है। यह लर्निंग पैरामीटर्स तय करने में बड़ा योगदान देता है और प्रेडिक्शन एक्यूरेसी को प्रभावित करता है। आप नेटवर्क को 20 epochs तक ट्रेन करेंगे।

batch_size = 64
epochs = 20
num_classes = 10

न्यूरल नेटवर्क आर्किटेक्चर

Keras में, आप इच्छित लेयर को एक-एक करके जोड़कर लेयर्स को स्टैक कर सकते हैं। यहीं आप वही करेंगे: आप पहले Conv2D() के साथ एक कॉन्वोल्यूशनल लेयर जोड़ेंगे। ध्यान दें कि आप यह फ़ंक्शन इसलिए उपयोग करते हैं क्योंकि आप इमेजेज़ के साथ काम कर रहे हैं! उसके बाद, आप Leaky ReLU एक्टिवेशन फ़ंक्शन जोड़ते हैं जो नेटवर्क को नॉन-लिनियर डिसीजन बाउंडरीज़ सीखने में मदद करता है। चूंकि आपके पास दस अलग-अलग क्लासेस हैं, आपको ऐसी नॉन-लिनियर डिसीजन बाउंडरी चाहिए जो इन दस क्लासेस को अलग कर सके, जो रैखिक रूप से सेपरेबल नहीं हैं।

और विशेष रूप से, आप Leaky ReLUs इसलिए जोड़ते हैं क्योंकि वे मरते हुए Rectified Linear Units (ReLUs) की समस्या को ठीक करने की कोशिश करते हैं। ReLU एक्टिवेशन फ़ंक्शन न्यूरल नेटवर्क आर्किटेक्चर्स, खासकर कॉन्वोल्यूशनल नेटवर्क्स में, बहुत उपयोग होता है, जहाँ यह व्यापक रूप से उपयोग होने वाले लॉजिस्टिक सिग्मॉइड फ़ंक्शन से अधिक प्रभावी साबित हुआ है। 2017 तक, यह एक्टिवेशन फ़ंक्शन डीप न्यूरल नेटवर्क्स के लिए सबसे लोकप्रिय था। ReLU फ़ंक्शन एक्टिवेशन को शून्य पर थ्रेशहोल्ड करने देता है। हालांकि, ट्रेनिंग के दौरान, ReLU यूनिट्स "मर" सकती हैं। यह तब हो सकता है जब किसी ReLU न्यूरॉन से बड़ा ग्रेडिएंट गुज़रता है: यह वेट्स को इस तरह अपडेट कर सकता है कि वह न्यूरॉन फिर कभी किसी डेटा पॉइंट पर एक्टिवेट ही न हो। यदि ऐसा होता है, तो उस बिंदु से उस यूनिट से गुज़रने वाला ग्रेडिएंट हमेशा के लिए शून्य हो जाएगा। Leaky ReLUs इसका हल ढूंढने की कोशिश करते हैं: फ़ंक्शन शून्य नहीं होगा बल्कि उसमें एक छोटा नकारात्मक ढलान होगा।

अगला, आप MaxPooling2D() के साथ मैक्स-पूलिंग लेयर जोड़ेंगे, और इसी तरह आगे बढ़ेंगे। आखिरी लेयर एक Dense लेयर है जिसमें 10 यूनिट्स के साथ softmax एक्टिवेशन फ़ंक्शन है, जो इस मल्टी-क्लास क्लासिफिकेशन समस्या के लिए आवश्यक है।

fashion_model = Sequential()
fashion_model.add(Conv2D(32, kernel_size=(3, 3),activation='linear',input_shape=(28,28,1),padding='same'))
fashion_model.add(LeakyReLU(alpha=0.1))
fashion_model.add(MaxPooling2D((2, 2),padding='same'))
fashion_model.add(Conv2D(64, (3, 3), activation='linear',padding='same'))
fashion_model.add(LeakyReLU(alpha=0.1))
fashion_model.add(MaxPooling2D(pool_size=(2, 2),padding='same'))
fashion_model.add(Conv2D(128, (3, 3), activation='linear',padding='same'))
fashion_model.add(LeakyReLU(alpha=0.1))                  
fashion_model.add(MaxPooling2D(pool_size=(2, 2),padding='same'))
fashion_model.add(Flatten())
fashion_model.add(Dense(128, activation='linear'))
fashion_model.add(LeakyReLU(alpha=0.1))                  
fashion_model.add(Dense(num_classes, activation='softmax'))

मॉडल कम्पाइल करें

मॉडल बनने के बाद, आप इसे Adam ऑप्टिमाइज़र के साथ कम्पाइल करते हैं, जो सबसे लोकप्रिय ऑप्टिमाइज़ेशन एल्गोरिद्म में से एक है। आप इस ऑप्टिमाइज़र के बारे में अधिक यहाँ पढ़ सकते हैं। इसके अतिरिक्त, आप लॉस टाइप निर्दिष्ट करते हैं जो कि कैटेगोरिकल क्रॉस एंट्रोपी है, जिसका उपयोग मल्टी-क्लास क्लासिफिकेशन के लिए होता है; आप बाइनरी क्रॉस-एंट्रोपी को भी लॉस फ़ंक्शन के रूप में उपयोग कर सकते हैं। अंत में, आप मेट्रिक्स के रूप में एक्यूरेसी निर्दिष्ट करते हैं, जिसे आप मॉडल ट्रेनिंग के दौरान एनालाइज़ करना चाहते हैं।

fashion_model.compile(loss=keras.losses.categorical_crossentropy, optimizer=keras.optimizers.Adam(),metrics=['accuracy'])

आइए summary फ़ंक्शन का उपयोग करके ऊपर बनाए गए लेयर्स को विज़ुअलाइज़ करें। यह प्रत्येक लेयर में कुछ पैरामीटर्स (वेट्स और बायसेज़) दिखाएगा और आपके मॉडल में कुल पैरामीटर्स भी।

fashion_model.summary()
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_51 (Conv2D)           (None, 28, 28, 32)        320       
_________________________________________________________________
leaky_re_lu_57 (LeakyReLU)   (None, 28, 28, 32)        0         
_________________________________________________________________
max_pooling2d_49 (MaxPooling (None, 14, 14, 32)        0         
_________________________________________________________________
conv2d_52 (Conv2D)           (None, 14, 14, 64)        18496     
_________________________________________________________________
leaky_re_lu_58 (LeakyReLU)   (None, 14, 14, 64)        0         
_________________________________________________________________
max_pooling2d_50 (MaxPooling (None, 7, 7, 64)          0         
_________________________________________________________________
conv2d_53 (Conv2D)           (None, 7, 7, 128)         73856     
_________________________________________________________________
leaky_re_lu_59 (LeakyReLU)   (None, 7, 7, 128)         0         
_________________________________________________________________
max_pooling2d_51 (MaxPooling (None, 4, 4, 128)         0         
_________________________________________________________________
flatten_17 (Flatten)         (None, 2048)              0         
_________________________________________________________________
dense_33 (Dense)             (None, 128)               262272    
_________________________________________________________________
leaky_re_lu_60 (LeakyReLU)   (None, 128)               0         
_________________________________________________________________
dense_34 (Dense)             (None, 10)                1290      
=================================================================
Total params: 356,234
Trainable params: 356,234
Non-trainable params: 0
_________________________________________________________________

मॉडल ट्रेन करें

आखिरकार Keras के fit() फ़ंक्शन से मॉडल ट्रेन करने का समय आ गया है! मॉडल 20 epochs तक ट्रेन करता है। fit() फ़ंक्शन एक history ऑब्जेक्ट लौटाएगा; इस फ़ंक्शन के परिणाम को fashion_train में स्टोर करके, आप बाद में ट्रेनिंग और वैलिडेशन के बीच एक्यूरेसी और लॉस के प्लॉट्स बना सकते हैं, जो आपको अपने मॉडल के प्रदर्शन का दृश्यात्मक विश्लेषण करने में मदद करेंगे।

fashion_train = fashion_model.fit(train_X, train_label, batch_size=batch_size,epochs=epochs,verbose=1,validation_data=(valid_X, valid_label))
Train on 48000 samples, validate on 12000 samples
Epoch 1/20
48000/48000 [==============================] - 60s 1ms/step - loss: 0.4661 - acc: 0.8311 - val_loss: 0.3320 - val_acc: 0.8809
Epoch 2/20
48000/48000 [==============================] - 60s 1ms/step - loss: 0.2874 - acc: 0.8951 - val_loss: 0.2781 - val_acc: 0.8963
Epoch 3/20
48000/48000 [==============================] - 60s 1ms/step - loss: 0.2420 - acc: 0.9111 - val_loss: 0.2501 - val_acc: 0.9077
Epoch 4/20
48000/48000 [==============================] - 59s 1ms/step - loss: 0.2088 - acc: 0.9226 - val_loss: 0.2369 - val_acc: 0.9147
Epoch 5/20
48000/48000 [==============================] - 59s 1ms/step - loss: 0.1838 - acc: 0.9324 - val_loss: 0.2602 - val_acc: 0.9070
Epoch 6/20
48000/48000 [==============================] - 59s 1ms/step - loss: 0.1605 - acc: 0.9396 - val_loss: 0.2264 - val_acc: 0.9193
Epoch 7/20
48000/48000 [==============================] - 59s 1ms/step - loss: 0.1356 - acc: 0.9488 - val_loss: 0.2566 - val_acc: 0.9180
Epoch 8/20
48000/48000 [==============================] - 59s 1ms/step - loss: 0.1186 - acc: 0.9553 - val_loss: 0.2556 - val_acc: 0.9149
Epoch 9/20
48000/48000 [==============================] - 59s 1ms/step - loss: 0.0985 - acc: 0.9634 - val_loss: 0.2681 - val_acc: 0.9204
Epoch 10/20
48000/48000 [==============================] - 59s 1ms/step - loss: 0.0873 - acc: 0.9670 - val_loss: 0.2712 - val_acc: 0.9221
Epoch 11/20
48000/48000 [==============================] - 59s 1ms/step - loss: 0.0739 - acc: 0.9721 - val_loss: 0.2757 - val_acc: 0.9202
Epoch 12/20
48000/48000 [==============================] - 60s 1ms/step - loss: 0.0628 - acc: 0.9767 - val_loss: 0.3126 - val_acc: 0.9132
Epoch 13/20
48000/48000 [==============================] - 61s 1ms/step - loss: 0.0569 - acc: 0.9789 - val_loss: 0.3556 - val_acc: 0.9081
Epoch 14/20
48000/48000 [==============================] - 60s 1ms/step - loss: 0.0452 - acc: 0.9833 - val_loss: 0.3441 - val_acc: 0.9189
Epoch 15/20
48000/48000 [==============================] - 60s 1ms/step - loss: 0.0421 - acc: 0.9847 - val_loss: 0.3400 - val_acc: 0.9165
Epoch 16/20
48000/48000 [==============================] - 60s 1ms/step - loss: 0.0379 - acc: 0.9861 - val_loss: 0.3876 - val_acc: 0.9195
Epoch 17/20
48000/48000 [==============================] - 60s 1ms/step - loss: 0.0405 - acc: 0.9855 - val_loss: 0.4112 - val_acc: 0.9164
Epoch 18/20
48000/48000 [==============================] - 60s 1ms/step - loss: 0.0285 - acc: 0.9897 - val_loss: 0.4150 - val_acc: 0.9181
Epoch 19/20
48000/48000 [==============================] - 61s 1ms/step - loss: 0.0322 - acc: 0.9877 - val_loss: 0.4584 - val_acc: 0.9196
Epoch 20/20
48000/48000 [==============================] - 61s 1ms/step - loss: 0.0262 - acc: 0.9906 - val_loss: 0.4396 - val_acc: 0.9205

आखिरकार! आपने मॉडल को fashion-MNIST पर 20 epochs तक ट्रेन किया, और ट्रेनिंग एक्यूरेसी और लॉस को देखकर आप कह सकते हैं कि मॉडल ने अच्छा काम किया है क्योंकि 20 epochs के बाद ट्रेनिंग एक्यूरेसी 99% है और ट्रेनिंग लॉस काफी कम है।

हालाँकि, ऐसा लगता है कि मॉडल ओवरफिट हो रहा है, क्योंकि वैलिडेशन लॉस 0.4396 है और वैलिडेशन एक्यूरेसी 92% है। ओवरफिटिंग यह संकेत देती है कि नेटवर्क ने ट्रेनिंग डेटा को बहुत अच्छे से याद कर लिया है लेकिन अनदेखे डेटा पर काम करने की कोई गारंटी नहीं है, और यही कारण है कि ट्रेनिंग और वैलिडेशन एक्यूरेसी में अंतर है।

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

पर पहले, किसी निष्कर्ष पर पहुँचने से पहले टेस्ट सेट पर अपने मॉडल के प्रदर्शन का मूल्यांकन कर लेते हैं।

टेस्ट सेट पर मॉडल का मूल्यांकन

test_eval = fashion_model.evaluate(test_X, test_Y_one_hot, verbose=0)
print('Test loss:', test_eval[0])
print('Test accuracy:', test_eval[1])
('Test loss:', 0.46366268818555401)
('Test accuracy:', 0.91839999999999999)

टेस्ट एक्यूरेसी प्रभावशाली लगती है। लगता है कि आपका क्लासिफ़ायर यहाँ रिपोर्ट किए गए बेंचमार्क से बेहतर कर रहा है यहाँ, जो एक SVM क्लासिफ़ायर है जिसकी औसत एक्यूरेसी 0.897 है। साथ ही, यह मॉडल उन कुछ डीप लर्निंग मॉडलों की तुलना में भी अच्छा करता है जिनका उल्लेख fashion-MNIST डेटा सेट के निर्माताओं की GitHub प्रोफाइल पर है।

फिर भी, आपने देखा कि मॉडल ओवरफिटिंग कर रहा था। क्या ये परिणाम वाकई इतने अच्छे हैं?

आइए अपने मॉडल के मूल्यांकन को परिप्रेक्ष्य में रखते हैं और ट्रेनिंग तथा वैलिडेशन डेटा के बीच एक्यूरेसी और लॉस के प्लॉट्स बनाते हैं:

accuracy = fashion_train.history['acc']
val_accuracy = fashion_train.history['val_acc']
loss = fashion_train.history['loss']
val_loss = fashion_train.history['val_loss']
epochs = range(len(accuracy))
plt.plot(epochs, accuracy, 'bo', label='Training accuracy')
plt.plot(epochs, val_accuracy, 'b', label='Validation accuracy')
plt.title('Training and validation accuracy')
plt.legend()
plt.figure()
plt.plot(epochs, loss, 'bo', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.title('Training and validation loss')
plt.legend()
plt.show()

ट्रेनिंग और वैलिडेशन एक्यूरेसी ग्राफ

ट्रेनिंग और वैलिडेशन लॉस ग्राफ

ऊपर के दोनों प्लॉट्स से आप देख सकते हैं कि वैलिडेशन एक्यूरेसी 4-5 epochs के बाद लगभग स्थिर हो गई और कुछ epochs पर ही बढ़ी। शुरुआत में, वैलिडेशन एक्यूरेसी लॉस के साथ रैखिक रूप से बढ़ रही थी, लेकिन फिर यह ज़्यादा नहीं बढ़ी।

वैलिडेशन लॉस दिखाता है कि यह ओवरफिटिंग का संकेत है; वैलिडेशन एक्यूरेसी की तरह यह रैखिक रूप से घटा, पर 4-5 epochs के बाद बढ़ना शुरू हो गया। इसका मतलब है कि मॉडल ने डेटा को याद करने की कोशिश की और सफल भी रहा।

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

नेटवर्क में ड्रॉपआउट जोड़ना

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

तो आइए नेटवर्क को फिर से बनाते, कम्पाइल करते और ट्रेन करते हैं, लेकिन इस बार ड्रॉपआउट के साथ। और इसे 20 epochs तक 64 के बैच साइज के साथ चलाते हैं।

batch_size = 64
epochs = 20
num_classes = 10
fashion_model = Sequential()
fashion_model.add(Conv2D(32, kernel_size=(3, 3),activation='linear',padding='same',input_shape=(28,28,1)))
fashion_model.add(LeakyReLU(alpha=0.1))
fashion_model.add(MaxPooling2D((2, 2),padding='same'))
fashion_model.add(Dropout(0.25))
fashion_model.add(Conv2D(64, (3, 3), activation='linear',padding='same'))
fashion_model.add(LeakyReLU(alpha=0.1))
fashion_model.add(MaxPooling2D(pool_size=(2, 2),padding='same'))
fashion_model.add(Dropout(0.25))
fashion_model.add(Conv2D(128, (3, 3), activation='linear',padding='same'))
fashion_model.add(LeakyReLU(alpha=0.1))                  
fashion_model.add(MaxPooling2D(pool_size=(2, 2),padding='same'))
fashion_model.add(Dropout(0.4))
fashion_model.add(Flatten())
fashion_model.add(Dense(128, activation='linear'))
fashion_model.add(LeakyReLU(alpha=0.1))           
fashion_model.add(Dropout(0.3))
fashion_model.add(Dense(num_classes, activation='softmax'))
fashion_model.summary()
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_54 (Conv2D)           (None, 28, 28, 32)        320       
_________________________________________________________________
leaky_re_lu_61 (LeakyReLU)   (None, 28, 28, 32)        0         
_________________________________________________________________
max_pooling2d_52 (MaxPooling (None, 14, 14, 32)        0         
_________________________________________________________________
dropout_29 (Dropout)         (None, 14, 14, 32)        0         
_________________________________________________________________
conv2d_55 (Conv2D)           (None, 14, 14, 64)        18496     
_________________________________________________________________
leaky_re_lu_62 (LeakyReLU)   (None, 14, 14, 64)        0         
_________________________________________________________________
max_pooling2d_53 (MaxPooling (None, 7, 7, 64)          0         
_________________________________________________________________
dropout_30 (Dropout)         (None, 7, 7, 64)          0         
_________________________________________________________________
conv2d_56 (Conv2D)           (None, 7, 7, 128)         73856     
_________________________________________________________________
leaky_re_lu_63 (LeakyReLU)   (None, 7, 7, 128)         0         
_________________________________________________________________
max_pooling2d_54 (MaxPooling (None, 4, 4, 128)         0         
_________________________________________________________________
dropout_31 (Dropout)         (None, 4, 4, 128)         0         
_________________________________________________________________
flatten_18 (Flatten)         (None, 2048)              0         
_________________________________________________________________
dense_35 (Dense)             (None, 128)               262272    
_________________________________________________________________
leaky_re_lu_64 (LeakyReLU)   (None, 128)               0         
_________________________________________________________________
dropout_32 (Dropout)         (None, 128)               0         
_________________________________________________________________
dense_36 (Dense)             (None, 10)                1290      
=================================================================
Total params: 356,234
Trainable params: 356,234
Non-trainable params: 0
_________________________________________________________________
fashion_model.compile(loss=keras.losses.categorical_crossentropy, optimizer=keras.optimizers.Adam(),metrics=['accuracy'])
fashion_train_dropout = fashion_model.fit(train_X, train_label, batch_size=batch_size,epochs=epochs,verbose=1,validation_data=(valid_X, valid_label))
Train on 48000 samples, validate on 12000 samples
Epoch 1/20
48000/48000 [==============================] - 66s 1ms/step - loss: 0.5954 - acc: 0.7789 - val_loss: 0.3788 - val_acc: 0.8586
Epoch 2/20
48000/48000 [==============================] - 64s 1ms/step - loss: 0.3797 - acc: 0.8591 - val_loss: 0.3150 - val_acc: 0.8832
Epoch 3/20
48000/48000 [==============================] - 64s 1ms/step - loss: 0.3302 - acc: 0.8787 - val_loss: 0.2836 - val_acc: 0.8961
Epoch 4/20
48000/48000 [==============================] - 64s 1ms/step - loss: 0.3034 - acc: 0.8868 - val_loss: 0.2663 - val_acc: 0.9002
Epoch 5/20
48000/48000 [==============================] - 64s 1ms/step - loss: 0.2843 - acc: 0.8936 - val_loss: 0.2481 - val_acc: 0.9083
Epoch 6/20
48000/48000 [==============================] - 64s 1ms/step - loss: 0.2699 - acc: 0.9002 - val_loss: 0.2469 - val_acc: 0.9032
Epoch 7/20
48000/48000 [==============================] - 65s 1ms/step - loss: 0.2561 - acc: 0.9049 - val_loss: 0.2422 - val_acc: 0.9095
Epoch 8/20
48000/48000 [==============================] - 65s 1ms/step - loss: 0.2503 - acc: 0.9068 - val_loss: 0.2429 - val_acc: 0.9098
Epoch 9/20
48000/48000 [==============================] - 65s 1ms/step - loss: 0.2437 - acc: 0.9096 - val_loss: 0.2230 - val_acc: 0.9173
Epoch 10/20
48000/48000 [==============================] - 65s 1ms/step - loss: 0.2307 - acc: 0.9126 - val_loss: 0.2170 - val_acc: 0.9187
Epoch 11/20
48000/48000 [==============================] - 65s 1ms/step - loss: 0.2307 - acc: 0.9135 - val_loss: 0.2265 - val_acc: 0.9193
Epoch 12/20
48000/48000 [==============================] - 65s 1ms/step - loss: 0.2229 - acc: 0.9160 - val_loss: 0.2136 - val_acc: 0.9229
Epoch 13/20
48000/48000 [==============================] - 65s 1ms/step - loss: 0.2202 - acc: 0.9162 - val_loss: 0.2173 - val_acc: 0.9187
Epoch 14/20
48000/48000 [==============================] - 64s 1ms/step - loss: 0.2161 - acc: 0.9188 - val_loss: 0.2142 - val_acc: 0.9211
Epoch 15/20
48000/48000 [==============================] - 65s 1ms/step - loss: 0.2119 - acc: 0.9196 - val_loss: 0.2133 - val_acc: 0.9233
Epoch 16/20
48000/48000 [==============================] - 65s 1ms/step - loss: 0.2073 - acc: 0.9222 - val_loss: 0.2159 - val_acc: 0.9213
Epoch 17/20
48000/48000 [==============================] - 65s 1ms/step - loss: 0.2050 - acc: 0.9231 - val_loss: 0.2123 - val_acc: 0.9233
Epoch 18/20
48000/48000 [==============================] - 64s 1ms/step - loss: 0.2016 - acc: 0.9238 - val_loss: 0.2191 - val_acc: 0.9235
Epoch 19/20
48000/48000 [==============================] - 65s 1ms/step - loss: 0.2001 - acc: 0.9244 - val_loss: 0.2110 - val_acc: 0.9258
Epoch 20/20
48000/48000 [==============================] - 64s 1ms/step - loss: 0.1972 - acc: 0.9255 - val_loss: 0.2092 - val_acc: 0.9269

आइए मॉडल को सेव कर लेते हैं ताकि आप इसे सीधे लोड कर सकें और 20 epochs तक फिर से ट्रेन न करना पड़े। इस तरह, यदि आपको बाद में ज़रूरत हो तो आप मॉडल को लोड कर सकते हैं और आर्किटेक्चर में बदलाव कर सकते हैं; वैकल्पिक रूप से, आप इस सेव किए गए मॉडल पर ट्रेनिंग प्रक्रिया शुरू कर सकते हैं। मॉडल को —और यहाँ तक कि मॉडल के वेट्स को भी!— सेव करना हमेशा एक अच्छा विचार है, क्योंकि यह आपका समय बचाता है। ध्यान दें कि आप हर epoch के बाद भी मॉडल को सेव कर सकते हैं ताकि यदि किसी epoch पर कोई समस्या आ जाए और ट्रेनिंग रुक जाए, तो आपको शुरुआत से ट्रेनिंग शुरू न करनी पड़े।

fashion_model.save("fashion_model_dropout.h5py")

टेस्ट सेट पर मॉडल का मूल्यांकन

अंत में, आइए आपके नए मॉडल का भी मूल्यांकन करें और देखें कि यह कैसा प्रदर्शन करता है!

test_eval = fashion_model.evaluate(test_X, test_Y_one_hot, verbose=1)
10000/10000 [==============================] - 5s 461us/step
print('Test loss:', test_eval[0])
print('Test accuracy:', test_eval[1])
('Test loss:', 0.21460009642243386)
('Test accuracy:', 0.92300000000000004)

वाह! लगता है कि हमारे मॉडल में Dropout जोड़ना कारगर रहा। भले ही टेस्ट एक्यूरेसी में बहुत अधिक सुधार नहीं हुआ, लेकिन पिछले परिणामों की तुलना में टेस्ट लॉस कम हुआ है।

अब, आखिरी बार ट्रेनिंग और वेलिडेशन डेटा के बीच एक्यूरेसी और लॉस के प्लॉट बनाते हैं।

accuracy = fashion_train_dropout.history['acc']
val_accuracy = fashion_train_dropout.history['val_acc']
loss = fashion_train_dropout.history['loss']
val_loss = fashion_train_dropout.history['val_loss']
epochs = range(len(accuracy))
plt.plot(epochs, accuracy, 'bo', label='Training accuracy')
plt.plot(epochs, val_accuracy, 'b', label='Validation accuracy')
plt.title('Training and validation accuracy')
plt.legend()
plt.figure()
plt.plot(epochs, loss, 'bo', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.title('Training and validation loss')
plt.legend()
plt.show()

ट्रेनिंग और वेलिडेशन एक्यूरेसी ग्राफ

트्रेनिंग और वेलिडेशन लॉस ग्राफ

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

अतः, आप कह सकते हैं कि आपके मॉडल की जनरलाइजेशन क्षमता काफी बेहतर हो गई है, क्योंकि टेस्ट सेट और वेलिडेशन सेट पर लॉस, ट्रेनिंग लॉस की तुलना में केवल थोड़ा ही अधिक था।

लेबल्स की भविष्यवाणी करें

predicted_classes = fashion_model.predict(test_X)

क्योंकि आपको जो प्रेडिक्शन मिलती है वह फ्लोटिंग-पॉइंट मान होती है, इसलिए भविष्यवाणी किए गए लेबल्स की तुलना वास्तविक टेस्ट लेबल्स से करना सीधे तौर पर संभव नहीं होगा। इसलिए, आप आउटपुट को राउंड ऑफ करेंगे, जिससे फ्लोट मान इन्टीजर में बदल जाएंगे। आगे, आप np.argmax() का उपयोग करेंगे ताकि पंक्ति में सबसे बड़े मान वाले इंडेक्स नंबर का चयन हो सके।

उदाहरण के लिए, मान लीजिए किसी एक टेस्ट इमेज के लिए प्रेडिक्शन 0 1 0 0 0 0 0 0 0 0 है, तो इसका आउटपुट क्लास लेबल 1 होना चाहिए।

predicted_classes = np.argmax(np.round(predicted_classes),axis=1)
predicted_classes.shape, test_Y.shape
((10000,), (10000,))
correct = np.where(predicted_classes==test_Y)[0]
print "Found %d correct labels" % len(correct)
for i, correct in enumerate(correct[:9]):
    plt.subplot(3,3,i+1)
    plt.imshow(test_X[correct].reshape(28,28), cmap='gray', interpolation='none')
    plt.title("Predicted {}, Class {}".format(predicted_classes[correct], test_Y[correct]))
    plt.tight_layout()
Found 9188 correct labels

सही परिधान लेबल्स

incorrect = np.where(predicted_classes!=test_Y)[0]
print "Found %d incorrect labels" % len(incorrect)
for i, incorrect in enumerate(incorrect[:9]):
    plt.subplot(3,3,i+1)
    plt.imshow(test_X[incorrect].reshape(28,28), cmap='gray', interpolation='none')
    plt.title("Predicted {}, Class {}".format(predicted_classes[incorrect], test_Y[incorrect]))
    plt.tight_layout()
Found 812 incorrect labels

गलत परिधान लेबल्स

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

क्लासिफिकेशन रिपोर्ट

क्लासिफिकेशन रिपोर्ट हमें मिसक्लासिफाइड कक्षाओं की अधिक विस्तार से पहचान करने में मदद करेगी। आप देख पाएंगे कि दी गई दस कक्षाओं में से किस कक्षा के लिए मॉडल का प्रदर्शन कमजोर रहा।

from sklearn.metrics import classification_report
target_names = ["Class {}".format(i) for i in range(num_classes)]
print(classification_report(test_Y, predicted_classes, target_names=target_names))
             precision    recall  f1-score   support

    Class 0       0.77      0.90      0.83      1000
    Class 1       0.99      0.98      0.99      1000
    Class 2       0.88      0.88      0.88      1000
    Class 3       0.94      0.92      0.93      1000
    Class 4       0.88      0.87      0.88      1000
    Class 5       0.99      0.98      0.98      1000
    Class 6       0.82      0.72      0.77      1000
    Class 7       0.94      0.99      0.97      1000
    Class 8       0.99      0.98      0.99      1000
    Class 9       0.98      0.96      0.97      1000

avg / total       0.92      0.92      0.92     10000

आप देख सकते हैं कि क्लास 6 के लिए क्लासिफायर प्रिसिजन और रिकॉल दोनों में कमज़ोर है। क्लास 0 और क्लास 2 के लिए क्लासिफायर में प्रिसिजन की कमी है। साथ ही, क्लास 4 के लिए प्रिसिजन और रिकॉल, दोनों में हल्की कमी है।

और आगे बढ़ें!

यह ट्यूटोरियल Python में Keras के साथ कॉन्वोल्यूशनल न्यूरल नेटवर्क्स का अच्छा आरंभ था। यदि आप आसानी से या थोड़े अतिरिक्त प्रयास के साथ भी साथ चल पाए, बहुत बढ़िया! कुछ प्रयोग करने की कोशिश करें — हो सकता है वही मॉडल आर्किटेक्चर रखें, लेकिन अलग-अलग प्रकार के सार्वजनिक डेटासेट्स का उपयोग करें।

अभी भी बहुत कुछ कवर करना बाकी है, तो क्यों न DataCamp का Deep Learning in Python कोर्स कर लें? इसी बीच, यदि आपने अभी तक नहीं देखा है, तो Keras डोक्यूमेंटेशन भी ज़रूर देखें। वहां आपको और उदाहरण मिलेंगे, साथ ही सभी फंक्शंस, आर्ग्युमेंट्स, अधिक लेयर्स आदि की जानकारी। Python में न्यूरल नेटवर्क्स के साथ काम करना सीखते समय यह निस्संदेह एक अनिवार्य संसाधन साबित होगा!

यदि आप एक ऐसी किताब पढ़ना चाहते हैं जो डीप लर्निंग (Keras के साथ) की बुनियादी बातों को समझाती हो और यह भी बताती हो कि व्यवहार में इसका उपयोग कैसे होता है, तो आपको François Chollet की Deep Learning in Python किताब ज़रूर पढ़नी चाहिए।

विषय