1. खास जानकारी
इस लैब में, आपको Keras और Tensorflow 2 की मदद से, अपने कॉन्वलूशनल न्यूरल नेटवर्क को बनाने, ट्रेनिंग देने, और ट्यून करने का तरीका बताया जाएगा. अब टीपीयू की मदद से, यह काम कुछ ही मिनटों में किया जा सकता है. इसके अलावा, आपको ट्रांसफ़र करने के बहुत आसान तरीकों से लेकर, Squeezenet जैसे मॉडर्न कॉन्वलूशनल आर्किटेक्चर के बारे में भी जानने का मौका मिलेगा. इस लैब में न्यूरल नेटवर्क के बारे में सैद्धांतिक व्याख्याएं शामिल हैं और यह डीप लर्निंग के बारे में सीखने वाले डेवलपर के लिए एक अच्छा शुरुआती पॉइंट है.
डीप लर्निंग पेपर पढ़ना मुश्किल और भ्रम की स्थिति पैदा करने वाला हो सकता है. आइए, कॉन्वोल्यूशनल न्यूरल नेटवर्क के आधुनिक आर्किटेक्चर के बारे में जानें.
आपको क्या सीखने को मिलेगा
- Keras और Tensor प्रोसेसिंग यूनिट (टीपीयू) का इस्तेमाल करके, अपने कस्टम मॉडल तेज़ी से बनाए जा सकते हैं.
- ट्रेनिंग डेटा को बेहतर तरीके से लोड करने के लिए, tf.data.Dataset API और TFRecord फ़ॉर्मैट का इस्तेमाल करें.
- धोखाधड़ी करने के लिए 😈, अपने मॉडल बनाने के बजाय ट्रांसफ़र लर्निंग का इस्तेमाल करना.
- Keras के सीक्वेंशियल और फ़ंक्शनल मॉडल स्टाइल का इस्तेमाल करने के लिए.
- सॉफ़्टमैक्स लेयर और क्रॉस-एन्ट्रोपी लॉस की मदद से, अपना Keras क्लासिफ़ायर बनाने के लिए.
- कॉन्वलूशनल लेयर के अच्छे विकल्प के साथ, अपने मॉडल को बेहतर बनाने के लिए.
- मॉड्यूल, ग्लोबल औसत पूलिंग वगैरह जैसे आधुनिक कॉन्वेंट आर्किटेक्चर के आइडिया एक्सप्लोर करने के लिए.
- Squeezenet आर्किटेक्चर का इस्तेमाल करके, एक आसान आधुनिक कॉन्वेंट बनाना.
सुझाव, राय या शिकायत
अगर आपको इस कोड लैब में कुछ गड़बड़ी दिखती है, तो कृपया हमें बताएं. GitHub की समस्याओं [ सुझाव/राय देने या शिकायत करने के लिए लिंक] के ज़रिए सुझाव, शिकायत या राय दी जा सकती है.
2. Google Colaboratory क्विक स्टार्ट
यह लैब, Google Collaboratory का इस्तेमाल करता है. इसके लिए, आपको कुछ सेट अप करने की ज़रूरत नहीं है. इसे Chromebook से चलाया जा सकता है. कृपया नीचे दी गई फ़ाइल खोलें और Colab notebook के बारे में जानने के लिए, सेल एक्ज़ीक्यूट करें.
कोई TPU बैकएंड चुनें
Colab मेन्यू में, रनटाइम > रनटाइम का टाइप बदलें को चुनें. इसके बाद, TPU चुनें. इस कोड लैब में, आपको हार्डवेयर की मदद से तेज़ी से ट्रेनिंग देने वाली सुविधा के लिए, बेहतर TPU (टेंसर प्रोसेसिंग यूनिट) का इस्तेमाल करना होगा. पहली बार चलाने पर, रनटाइम से अपने-आप कनेक्ट हो जाएगा. इसके अलावा, ऊपर दाएं कोने में मौजूद "कनेक्ट करें" बटन का इस्तेमाल करके भी कनेक्ट किया जा सकता है.
नोटबुक चलाना
किसी सेल पर क्लिक करके और Shift-Enter का इस्तेमाल करके, सेल को एक-एक करके चलाएं. रनटाइम > सभी चलाएं में जाकर भी पूरी नोटबुक को चलाया जा सकता है.
विषय सूची
सभी नोटबुक में विषय सूची होती है. इसे खोलने के लिए, बाईं ओर मौजूद काले रंग के ऐरो का इस्तेमाल करें.
छिपे हुए सेल
कुछ सेल में सिर्फ़ उनका टाइटल दिखेगा. यह सुविधा, Colab की नोटबुक में ही उपलब्ध है. इन पर दो बार क्लिक करके, इनमें मौजूद कोड देखा जा सकता है. हालांकि, आम तौर पर यह कोड बहुत दिलचस्प नहीं होता. आम तौर पर, सहायता या विज़ुअलाइज़ेशन फ़ंक्शन. अंदर के फ़ंक्शन को तय करने के लिए, आपको अब भी इन सेल को चलाना होगा.
पुष्टि करना
Colab, आपकी निजी Google Cloud Storage बकेट को ऐक्सेस कर सकता है. हालांकि, इसके लिए ज़रूरी है कि आपने किसी ऐसे खाते से पुष्टि की हो जिसके पास बकेट का ऐक्सेस हो. ऊपर दिया गया कोड स्निपेट, पुष्टि करने की प्रोसेस को ट्रिगर करेगा.
3. [INFO] टेन्सर प्रोसेसिंग यूनिट (टीपीयू) क्या हैं ?
कम शब्दों में
Keras में TPU पर मॉडल को ट्रेनिंग देने के लिए कोड (और TPU उपलब्ध न होने पर, जीपीयू या सीपीयू पर फ़ॉलबैक करना):
try: # detect TPUs
tpu = tf.distribute.cluster_resolver.TPUClusterResolver.connect()
strategy = tf.distribute.TPUStrategy(tpu)
except ValueError: # detect GPUs
strategy = tf.distribute.MirroredStrategy() # for CPU/GPU or multi-GPU machines
# use TPUStrategy scope to define model
with strategy.scope():
model = tf.keras.Sequential( ... )
model.compile( ... )
# train model normally on a tf.data.Dataset
model.fit(training_dataset, epochs=EPOCHS, steps_per_epoch=...)
हम आज TPU का इस्तेमाल करके, फूलों को अलग-अलग कैटगरी में बांटने वाले मॉडल को इंटरैक्टिव स्पीड (हर ट्रेनिंग रन में कुछ मिनट) पर बनाने और ऑप्टिमाइज़ करने जा रहे हैं.
TPU क्यों ?
मॉडर्न जीपीयू, प्रोग्राम किए जा सकने वाले "कोर" के आधार पर व्यवस्थित किए जाते हैं. यह एक बेहद सुविधाजनक आर्किटेक्चर है. इसकी मदद से, वे 3D रेंडरिंग, डीप लर्निंग, फ़िज़िकल सिम्युलेशन वगैरह जैसे कई काम कर सकते हैं. वहीं दूसरी ओर TPU, एक क्लासिक वेक्टर प्रोसेसर के साथ खास मैट्रिक्स गुणा वाली यूनिट को जोड़कर, ऐसे किसी भी टास्क को बेहतर बना सकता है जिसमें बड़े मैट्रिक्स गुणन की मुख्य स्थिति हो, जैसे कि न्यूरल नेटवर्क.
इलस्ट्रेशन: मैट्रिक्स मल्टीप्लिकेशन के तौर पर सघन न्यूरल नेटवर्क लेयर. इसमें न्यूरल नेटवर्क से एक साथ प्रोसेस की गई आठ इमेज का बैच है. कृपया एक लाइन x कॉलम को गुणा करें और देखें कि यह असल में किसी इमेज की सभी पिक्सल वैल्यू का वेटेड योग कर रहा है या नहीं. कॉन्वोल्यूशनल लेयर को मैट्रिक्स के गुणन के तौर पर भी दिखाया जा सकता है. हालांकि, यह थोड़ा मुश्किल है ( पहले सेक्शन में यहां इसकी जानकारी दी गई है).
हार्डवेयर
एमएक्सयू और वीपीयू
TPU v2 कोर, मैट्रिक्स मल्टीप्लाई यूनिट (एमएक्सयू) से बना होता है, जो मैट्रिक्स मल्टीप्लिकेशन और वेक्टर प्रोसेसिंग यूनिट (वीपीयू) को अन्य सभी कामों के लिए इस्तेमाल करता है. जैसे, ऐक्टिवेशन, सॉफ़्टमैक्स वगैरह. यह वीपीयू, float32 और int32 कंप्यूटेशन को हैंडल करता है. दूसरी ओर, MXU मिश्रित सटीक 16-32 बिट फ़्लोटिंग पॉइंट फ़ॉर्मैट में काम करता है.
मिक्स्ड प्रिसिज़न फ़्लोटिंग पॉइंट और bfloat16
MXU, bfloat16 इनपुट और float32 आउटपुट का इस्तेमाल करके, मैट्रिक्स गुणन की गणना करता है. बीच के लेवल पर इकट्ठा किए जाने वाले डेटा को float32 सटीक तरीके से प्रोसेस किया जाता है.
आम तौर पर, न्यूरल नेटवर्क ट्रेनिंग, कम फ़्लोटिंग पॉइंट सटीक होने की वजह से होने वाली गड़बड़ी को रोकती है. कुछ मामलों में शोर की वजह से, ऑप्टिमाइज़र को इकट्ठा करने में भी मदद मिलती है. कैलकुलेशन को तेज़ करने के लिए, आम तौर पर 16-बिट फ़्लोटिंग पॉइंट प्रिसीज़न का इस्तेमाल किया जाता है. हालांकि, float16 और float32 फ़ॉर्मैट की रेंज बहुत अलग होती है. float32 से float16 तक की शुद्धता को कम करने से, आम तौर पर ओवर और अंडरफ़्लो बनता है. समाधान मौजूद हैं, लेकिन float16 के काम करने के लिए और काम करने की ज़रूरत है.
इसलिए, Google ने टीपीयू में bfloat16 फ़ॉर्मैट को पेश किया. bfloat16, काटे गए float32 फ़ॉर्मैट का एक वर्शन है. इसमें एक्सपोनेंट बिट और रेंज, float32 फ़ॉर्मैट की तरह ही होती है. इसमें यह बात भी जोड़ी गई है कि TPU, bfloat16 इनपुट की मदद से मिले-जुले सटीक तरीके से मैट्रिक्स मल्टीप्लिकेशन को कंप्यूट करते हैं, लेकिन float32 आउटपुट. इसका मतलब है कि आम तौर पर, कम सटीक परफ़ॉर्मेंस का फ़ायदा पाने के लिए, कोड में किसी तरह के बदलाव की ज़रूरत नहीं होती.
सिस्टोलिक अरे
MXU, कथित "सिस्टोलिक अरे" आर्किटेक्चर का इस्तेमाल करके, हार्डवेयर में मैट्रिक्स गुणन को लागू करता है. इसमें डेटा एलिमेंट, हार्डवेयर कंप्यूटेशन यूनिट के कलेक्शन से होकर गुज़रते हैं. (चिकित्सा में, "सिस्टोलिक" का मतलब दिल के संकुचन और खून के प्रवाह से है, यहां डेटा के प्रवाह तक.)
आव्यूह के गुणन का मूल तत्व, एक आव्यूह की रेखा और दूसरे आव्यूह के कॉलम के बीच बिंदु वाला गुणनफल है (इस सेक्शन के सबसे ऊपर दिया गया उदाहरण देखें). मैट्रिक्स गुणन Y=X*W के लिए, नतीजे का एक एलिमेंट यह होगा:
Y[2,0] = X[2,0]*W[0,0] + X[2,1]*W[1,0] + X[2,2]*W[2,0] + ... + X[2,n]*W[n,0]
जीपीयू पर, इस डॉट प्रॉडक्ट को जीपीयू "कोर" में प्रोग्राम किया जाता है. इसके बाद, इसे उतने "कोर" पर एक साथ चलाया जाता है जितने उपलब्ध हैं, ताकि नतीजे वाले मैट्रिक की हर वैल्यू को एक साथ कैलकुलेट किया जा सके. अगर नतीजा देने वाला मैट्रिक्स 128x128 बड़ा है, तो इसके लिए 128x128=16K "कोर" उपलब्ध होने चाहिए, जो आम तौर पर मुमकिन नहीं है. सबसे बड़े जीपीयू में करीब 4000 कोर होते हैं. वहीं दूसरी ओर, TPU, MXU में कंप्यूट यूनिट के लिए कम से कम हार्डवेयर का इस्तेमाल करता है. इसमें सिर्फ़ bfloat16 x bfloat16 => float32
मल्टी-अक्युमिलेटर हैं, कुछ और नहीं. ये तरीके इतने छोटे होते हैं कि TPU इनमें से 16K कोड को 128x128 MXU में इस्तेमाल कर सकता है. साथ ही, इस मैट्रिक्स गुणा को एक ही बार में प्रोसेस कर सकता है.
इलस्ट्रेशन: MXU सिस्टोलिक अरे. कंप्यूट एलिमेंट, मल्टीप्लाई-ऐक्यूमुलेटर होते हैं. एक मैट्रिक्स की वैल्यू अरे (लाल बिंदु) में लोड होती हैं. अन्य मैट्रिक की वैल्यू, ऐरे (ग्रे बिंदु) से होकर बहती हैं. वर्टिकल लाइनें, वैल्यू को ऊपर की ओर ले जाती हैं. हॉरिज़ॉन्टल लाइन, आंशिक योग को प्रसारित करती हैं. इसे उपयोगकर्ता को कसरत के तौर पर छोड़ दिया जाता है, ताकि यह पुष्टि की जा सके कि जैसे-जैसे डेटा अरे से गुज़रेगा वैसे-वैसे आपको दाईं ओर से मिले मैट्रिक्स गुणा का नतीजा मिलेगा.
इसके अलावा, जहां बिंदु प्रॉडक्ट का हिसाब MXU में लगाया जाता है, वहीं इंटरमीडिएट योग आस-पास की कंप्यूट यूनिटों के बीच ट्रांसफ़र होते हैं. उन्हें मेमोरी या रजिस्टर फ़ाइल में भी स्टोर करने या वापस लाने की ज़रूरत नहीं होती. आखिरी नतीजा यह है कि TPU सिस्टोलिक अरे आर्किटेक्चर को बहुत ज़्यादा सघनता और पावर का फ़ायदा मिलता है. साथ ही, मैट्रिक्स गुणन की गणना करते समय जीपीयू पर गति का अच्छा-सा फ़ायदा मिलता है.
Cloud TPU
Google Cloud Platform पर "Cloud TPU v2" का अनुरोध करने पर, आपको एक वर्चुअल मशीन (VM) मिलती है. इसमें पीसीआई से जुड़ा TPU बोर्ड होता है. TPU बोर्ड में, ड्यूअल-कोर TPU चिप होते हैं. हर TPU कोर में एक VPU (वेक्टर प्रोसेसिंग यूनिट) और 128x128 MXU (मैट्रिक्स मल्टीप्लाई यूनिट) होता है. इसके बाद, आम तौर पर इस "Cloud TPU" को नेटवर्क के ज़रिए उस वीएम से कनेक्ट किया जाता है जिसने इसका अनुरोध किया है. पूरी जानकारी कुछ इस तरह दिखती है:
इमेज: नेटवर्क से जुड़े "Cloud TPU" ऐक्सेलरेटर वाला आपका वीएम. "Cloud TPU", एक वीएम से बना है. इसमें पीसीआई से जुड़ा TPU बोर्ड है, जिस पर चार ड्यूअल-कोर TPU चिप हैं.
TPU पॉड
Google के डेटा सेंटर में, TPU, हाई-परफ़ॉर्मेंस कंप्यूटिंग (एचपीसी) के इंटरकनेक्ट से जुड़े होते हैं. यह उन्हें एक बहुत बड़े एक्सेलरेटर के तौर पर दिखा सकता है. Google उन्हें पॉड कहता है. इनमें 512 TPU v2 कोर या 2048 TPU v3 कोर शामिल हो सकते हैं.
इलस्ट्रेशन: TPU v3 पॉड. एचपीसी इंटरकनेक्ट के ज़रिए जुड़े हुए TPU बोर्ड और रैक.
ट्रेनिंग के दौरान, ऑल-रिड्यूस एल्गोरिदम का इस्तेमाल करके, TPU कोर के बीच ग्रेडिएंट एक्सचेंज किए जाते हैं ( OK-reduce यहां बेहतर तरीके से बताया गया है). जिस मॉडल को ट्रेनिंग दी जा रही है वह बड़े बैच साइज़ पर ट्रेनिंग करके, हार्डवेयर का फ़ायदा ले सकता है.
इलस्ट्रेशन: Google TPU के 2-D टॉरोइडल मेश एचपीसी नेटवर्क पर ऑल-रिड्यूस एल्गोरिदम का इस्तेमाल करके, ट्रेनिंग के दौरान ग्रेडिएंट का सिंक करना.
सॉफ़्टवेयर
बड़े बैच साइज़ की ट्रेनिंग
हर TPU कोर के लिए, TPU के बैच का साइज़ 128 डेटा आइटम होता है. हालांकि, हर TPU कोर के लिए आठ डेटा आइटम होने की वजह से, हार्डवेयर पहले से ही उसका सही इस्तेमाल दिखा सकता है. याद रखें कि एक Cloud TPU में आठ कोर होते हैं.
इस कोड लैब में, हम Keras API का इस्तेमाल करेंगे. Keras में, आपका तय किया गया बैच, पूरे TPU का ग्लोबल बैच साइज़ होता है. आपके बैच अपने-आप आठ हिस्सों में बंट जाएंगे और TPU के आठ कोर पर चलेंगे.
परफ़ॉर्मेंस से जुड़ी अन्य सलाह के लिए, TPU की परफ़ॉर्मेंस गाइड देखें. बहुत बड़े बैच साइज़ के लिए, कुछ मॉडल में खास देखभाल की ज़रूरत हो सकती है. ज़्यादा जानकारी के लिए, LARSOptimizer पर जाएं.
अंदरूनी जानकारी: XLA
Tensorflow प्रोग्राम, कैलकुलेशन ग्राफ़ तय करते हैं. TPU, सीधे Python कोड नहीं चलाता है. यह आपके Tensorflow प्रोग्राम के हिसाब से कंप्यूटेशन ग्राफ़ चलाता है. XLA (accelerated Linear Algebra compiler) नाम का कंपाइलर, कंप्यूटेशन नोड के Tensorflow ग्राफ़ को TPU मशीन कोड में बदलता है. यह कंपाइलर आपके कोड और मेमोरी लेआउट पर कई बेहतर ऑप्टिमाइज़ेशन भी करता है. TPU को काम भेजते ही, डेटा कंपाइल हो जाता है. आपको अपनी बिल्ड चेन में XLA को साफ़ तौर पर शामिल करने की ज़रूरत नहीं है.
इलस्ट्रेशन: TPU पर चलाने के लिए, आपके Tensorflow प्रोग्राम के तय किए गए कंप्यूटेशन ग्राफ़ को सबसे पहले XLA (Accelerated लीनियर Algebra कंपाइलर) के रूप में बदला जाता है. इसके बाद, XLA की मदद से TPU मशीन कोड में उसे कंपाइल किया जाता है.
Keras में TPU इस्तेमाल करना
Tensorflow 2.1 के बाद, TPUs का इस्तेमाल Keras API के ज़रिए किया जा सकता है. Keras की सहायता, TPU और TPU पॉड पर काम करती है. यहां एक ऐसा उदाहरण दिया गया है जो टीपीयू, जीपीयू, और सीपीयू पर काम करता है:
try: # detect TPUs
tpu = tf.distribute.cluster_resolver.TPUClusterResolver.connect()
strategy = tf.distribute.TPUStrategy(tpu)
except ValueError: # detect GPUs
strategy = tf.distribute.MirroredStrategy() # for CPU/GPU or multi-GPU machines
# use TPUStrategy scope to define model
with strategy.scope():
model = tf.keras.Sequential( ... )
model.compile( ... )
# train model normally on a tf.data.Dataset
model.fit(training_dataset, epochs=EPOCHS, steps_per_epoch=...)
इस कोड स्निपेट में:
TPUClusterResolver().connect()
, नेटवर्क पर TPU ढूंढता है. यह Google Cloud के ज़्यादातर सिस्टम (एआई प्लैटफ़ॉर्म जॉब, Colaboratory, Kubeflow, और 'ctpu up' टूल की मदद से बनाए गए डीप लर्निंग वीएम) पर पैरामीटर के बिना काम करता है. TPU_NAME एनवायरमेंट वैरिएबल की मदद से, ये सिस्टम यह जान पाते हैं कि उनका TPU कहां है. अगर आपने खुद TPU बनाया है, तो जिस वीएम से TPU_NAME एनवायरमेंट बनाया गया है उस पर TPU_NAME एनवायरमेंट सेट करें या इन पैरामीटर के साथTPUClusterResolver
को कॉल करें:TPUClusterResolver(tp_uname, zone, project)
TPUStrategy
वह हिस्सा है जो डिस्ट्रिब्यूशन और "all-reduce" ग्रेडिएंट सिंकिंग एल्गोरिदम को लागू करता है.- रणनीति को एक स्कोप की मदद से लागू किया जाता है. मॉडल को 'रणनीति के दायरे' में तय किया जाना चाहिए.
tpu_model.fit
फ़ंक्शन, TPU ट्रेनिंग के लिए इनपुट के तौर पर tf.data.Dataset ऑब्जेक्ट का इस्तेमाल करता है.
TPU पोर्टिंग से जुड़े सामान्य टास्क
- Tensorflow मॉडल में डेटा लोड करने के कई तरीके हैं, लेकिन TPU के लिए,
tf.data.Dataset
API का इस्तेमाल करना ज़रूरी है. - टीपीयू बहुत तेज़ होते हैं और इन पर डेटा डालने में अक्सर समस्या आती है. TPU की परफ़ॉर्मेंस से जुड़ी गाइड में, डेटा की रुकावटों का पता लगाने और परफ़ॉर्मेंस से जुड़ी अन्य सलाह पाने के लिए टूल दिए गए हैं.
- int8 या int16 नंबर को int32 माना जाता है. TPU में इंटीजर हार्डवेयर 32 बिट से कम पर काम नहीं करता.
- Tensorflow के कुछ ऑपरेशन काम नहीं करते. सूची यहां दी गई है. अच्छी बात यह है कि यह पाबंदी सिर्फ़ ट्रेनिंग कोड, जैसे कि आपके मॉडल के आगे और पीछे वाले पास पर लागू होती है. हालांकि, आपकी डेटा इनपुट पाइपलाइन में Tensorflow से जुड़ी सभी कार्रवाइयों का इस्तेमाल, अब भी किया जा सकता है, क्योंकि ये कार्रवाइयां सीपीयू पर की जाएंगी.
- TPU पर
tf.py_func
का इस्तेमाल नहीं किया जा सकता.
4. डेटा लोड हो रहा है
हम फूलों की फ़ोटो के डेटासेट के साथ काम करेंगे. आपका लक्ष्य उन्हें 5 तरह के फूलों की कैटगरी में बांटना सीखना है. डेटा लोड करने के लिए, tf.data.Dataset
एपीआई का इस्तेमाल किया जाता है. सबसे पहले, हमें एपीआई के बारे में बताएं.
खुद करके
कृपया यहां दी गई नोटबुक खोलें, सेल (Shift-ENTER) चलाएं और जहां भी आपको "काम ज़रूरी है" लेबल दिखे वहां निर्देशों का पालन करें.
Fun with tf.data.Dataset (playground).ipynb
ज़्यादा जानकारी
"फूल" डेटासेट के बारे में जानकारी
डेटासेट को पांच फ़ोल्डर में व्यवस्थित किया जाता है. हर फ़ोल्डर में एक तरह के फूल हैं. फ़ोल्डर के नाम सनफ़्लावर, डेज़ी, डैंडलायन, ट्यूलिप, और गुलाब हैं. डेटा को Google Cloud Storage पर सार्वजनिक बकेट में होस्ट किया जाता है. उद्धरण:
gs://flowers-public/sunflowers/5139971615_434ff8ed8b_n.jpg
gs://flowers-public/daisy/8094774544_35465c1c64.jpg
gs://flowers-public/sunflowers/9309473873_9d62b9082e.jpg
gs://flowers-public/dandelion/19551343954_83bb52f310_m.jpg
gs://flowers-public/dandelion/14199664556_188b37e51e.jpg
gs://flowers-public/tulips/4290566894_c7f061583d_m.jpg
gs://flowers-public/roses/3065719996_c16ecd5551.jpg
gs://flowers-public/dandelion/8168031302_6e36f39d87.jpg
gs://flowers-public/sunflowers/9564240106_0577e919da_n.jpg
gs://flowers-public/daisy/14167543177_cd36b54ac6_n.jpg
tf.data.Dataset का इस्तेमाल क्यों करना चाहिए?
Keras और Tensorflow अपने सभी ट्रेनिंग और आकलन फ़ंक्शन में डेटासेट स्वीकार करते हैं. डेटासेट में डेटा लोड करने के बाद, एपीआई उन सभी सामान्य सुविधाओं को उपलब्ध कराता है जो न्यूरल नेटवर्क के ट्रेनिंग डेटा के लिए काम की होती हैं:
dataset = ... # load something (see below)
dataset = dataset.shuffle(1000) # shuffle the dataset with a buffer of 1000
dataset = dataset.cache() # cache the dataset in RAM or on disk
dataset = dataset.repeat() # repeat the dataset indefinitely
dataset = dataset.batch(128) # batch data elements together in batches of 128
AUTOTUNE = tf.data.AUTOTUNE
dataset = dataset.prefetch(AUTOTUNE) # prefetch next batch(es) while training
इस लेख में, परफ़ॉर्मेंस के बारे में सलाह और डेटासेट इस्तेमाल करने के सबसे सही तरीके देखे जा सकते हैं. रेफ़रंस दस्तावेज़ यहां मौजूद है.
tf.data.Dataset के बुनियादी सिद्धांत
आम तौर पर, डेटा कई फ़ाइलों में आता है यानी यहां इमेज दी गई हैं. यहां कॉल करके फ़ाइल नामों का डेटासेट बनाया जा सकता है:
filenames_dataset = tf.data.Dataset.list_files('gs://flowers-public/*/*.jpg')
# The parameter is a "glob" pattern that supports the * and ? wildcards.
इसके बाद, हर फ़ाइल के नाम के साथ एक फ़ंक्शन "मैप" किया जाता है. यह फ़ंक्शन, फ़ाइल को मेमोरी में लोड करके, उसे असली डेटा में बदल देता है:
def decode_jpeg(filename):
bits = tf.io.read_file(filename)
image = tf.io.decode_jpeg(bits)
return image
image_dataset = filenames_dataset.map(decode_jpeg)
# this is now a dataset of decoded images (uint8 RGB format)
डेटासेट पर बार-बार लागू करने के लिए:
for data in my_dataset:
print(data)
ट्यूपल के डेटासेट
सुपरवाइज़्ड लर्निंग में, ट्रेनिंग डेटासेट आम तौर पर ट्रेनिंग डेटा और सही जवाबों के जोड़े से बनता है. ऐसा करने के लिए, डिकोडिंग फ़ंक्शन ट्यूपल दिखा सकता है. इसके बाद, आपके पास ट्यूपल का डेटासेट होगा और उस पर दोहराए जाने पर, ट्यूपल दिखाए जाएंगे. दिखाई गई वैल्यू, TensorFlow के टेंसर हैं और आपके मॉडल का इस्तेमाल करने के लिए तैयार हैं. रॉ वैल्यू देखने के लिए, उन पर .numpy()
कॉल किया जा सकता है:
def decode_jpeg_and_label(filename):
bits = tf.read_file(filename)
image = tf.io.decode_jpeg(bits)
label = ... # extract flower name from folder name
return image, label
image_dataset = filenames_dataset.map(decode_jpeg_and_label)
# this is now a dataset of (image, label) pairs
for image, label in dataset:
print(image.numpy().shape, label.numpy())
निष्कर्ष:एक-एक करके इमेज लोड होना धीमा है !
इस डेटासेट को बार-बार इस्तेमाल करने पर, आपको पता चलेगा कि हर सेकंड में एक से दो इमेज लोड की जा सकती हैं. यह बहुत धीमा है! ट्रेनिंग के लिए इस्तेमाल किए जाने वाले हार्डवेयर एक्सेलेरेटर, इस दर से कई गुना ज़्यादा फ़्रीक्वेंसी पर काम कर सकते हैं. अगले सेक्शन में जानें कि हम ऐसा कैसे करेंगे.
समाधान
यहां समाधान वाली नोटबुक दी गई है. कोई समस्या आने पर, इसका इस्तेमाल किया जा सकता है.
Fun with tf.data.Dataset (solution).ipynb
हमने क्या-क्या शामिल किया है
- 🤔 tf.data.Dataset.list_files
- 🤔 tf.data.Dataset.map
- 🤔 ट्यूपल के डेटासेट
- डेटासेट के ज़रिए 😀 बार-बार दोहराया जा रहा है
कृपया कुछ समय निकालकर इस चेकलिस्ट को देखें.
5. डेटा तेज़ी से लोड हो रहा है
इस लैब में इस्तेमाल किए जाने वाले Tensor Processing Unit (TPU) हार्डवेयर ऐक्सेलरेटर बहुत तेज़ हैं. अक्सर, उन्हें इतना डेटा फ़ीड करना एक चुनौती होती है कि वे व्यस्त रहें. Google Cloud Storage (GCS), बहुत ज़्यादा थ्रूपुट बनाए रखने में सक्षम है. हालांकि, सभी क्लाउड स्टोरेज सिस्टम की तरह, कनेक्शन शुरू करने पर नेटवर्क का कुछ हिस्सा खर्च होता है. इसलिए, हमारे डेटा को हज़ारों अलग-अलग फ़ाइलों के तौर पर सेव रखना सही नहीं होता. हम उन्हें कम फ़ाइलों का बैच बनाने जा रहे हैं. साथ ही, कई फ़ाइलों को साथ-साथ पढ़ने के लिए tf.data.Dataset की पावर का इस्तेमाल करेंगे.
कॉन्टेंट को पढ़कर सुनाना
इमेज फ़ाइलों को लोड करने, उन्हें एक सामान्य साइज़ में बदलने, और फिर उन्हें 16 TFRecord फ़ाइलों में सेव करने वाला कोड, यहां दी गई नोटबुक में मौजूद है. कृपया इसे तुरंत पढ़ें. इसे एक्ज़ीक्यूट करना ज़रूरी नहीं है, क्योंकि बाकी कोडलैब के लिए, TFRecord-फ़ॉर्मैट किया गया डेटा सही तरीके से दिया जाएगा.
Flower pictures to TFRecords.ipynb
जीसीएस के बेहतर थ्रूपुट के लिए सबसे सही डेटा लेआउट
TFRecord फ़ाइल फ़ॉर्मैट
डेटा सेव करने के लिए, Tensorflow का पसंदीदा फ़ाइल फ़ॉर्मैट प्रोटोबफ़ पर आधारित TFRecord फ़ॉर्मैट है. सीरियलाइज़ेशन के अन्य फ़ॉर्मैट भी काम करेंगे, लेकिन सीधे TFRecord फ़ाइलों से डेटासेट लोड करने के लिए, यह लिखें:
filenames = tf.io.gfile.glob(FILENAME_PATTERN)
dataset = tf.data.TFRecordDataset(filenames)
dataset = dataset.map(...) # do the TFRecord decoding here - see below
हमारा सुझाव है कि बेहतर परफ़ॉर्मेंस के लिए, नीचे दिए गए ज़्यादा मुश्किल कोड का इस्तेमाल करें, ताकि आप कई TFRecord फ़ाइलों को एक साथ पढ़ सकें. यह कोड, N फ़ाइलों को साथ-साथ पढ़ेगा और पढ़ने की स्पीड के लिए, डेटा के क्रम को अनदेखा करेगा.
AUTOTUNE = tf.data.AUTOTUNE
ignore_order = tf.data.Options()
ignore_order.experimental_deterministic = False
filenames = tf.io.gfile.glob(FILENAME_PATTERN)
dataset = tf.data.TFRecordDataset(filenames, num_parallel_reads=AUTOTUNE)
dataset = dataset.with_options(ignore_order)
dataset = dataset.map(...) # do the TFRecord decoding here - see below
TFRecord की चीट शीट
TFRecords में तीन तरह का डेटा सेव किया जा सकता है: बाइट स्ट्रिंग (बाइट की सूची), 64 बिट इंटीजर और 32 बिट फ़्लोट. इन्हें हमेशा सूचियों के तौर पर सेव किया जाता है. एक डेटा एलिमेंट, साइज़ 1 की सूची होगी. TFRecords में डेटा सेव करने के लिए, नीचे दिए गए हेल्पर फ़ंक्शन का इस्तेमाल करें.
बाइट स्ट्रिंग लिखना
# warning, the input is a list of byte strings, which are themselves lists of bytes
def _bytestring_feature(list_of_bytestrings):
return tf.train.Feature(bytes_list=tf.train.BytesList(value=list_of_bytestrings))
इंटीजर लिखना
def _int_feature(list_of_ints): # int64
return tf.train.Feature(int64_list=tf.train.Int64List(value=list_of_ints))
राइटिंग फ़्लोट
def _float_feature(list_of_floats): # float32
return tf.train.Feature(float_list=tf.train.FloatList(value=list_of_floats))
ऊपर बताए गए हेल्पर का इस्तेमाल करके TFRecord लिखना
# input data in my_img_bytes, my_class, my_height, my_width, my_floats
with tf.python_io.TFRecordWriter(filename) as out_file:
feature = {
"image": _bytestring_feature([my_img_bytes]), # one image in the list
"class": _int_feature([my_class]), # one class in the list
"size": _int_feature([my_height, my_width]), # fixed length (2) list of ints
"float_data": _float_feature(my_floats) # variable length list of floats
}
tf_record = tf.train.Example(features=tf.train.Features(feature=feature))
out_file.write(tf_record.SerializeToString())
TFRecords का डेटा पढ़ने के लिए, आपको सबसे पहले उन रिकॉर्ड के लेआउट का एलान करना होगा जिन्हें आपने सेव किया है. एलान में, नाम वाले किसी भी फ़ील्ड को तय लंबाई वाली सूची या वैरिएबल की लंबाई वाली सूची के तौर पर ऐक्सेस किया जा सकता है:
TFRecords से पढ़ना
def read_tfrecord(data):
features = {
# tf.string = byte string (not text string)
"image": tf.io.FixedLenFeature([], tf.string), # shape [] means scalar, here, a single byte string
"class": tf.io.FixedLenFeature([], tf.int64), # shape [] means scalar, i.e. a single item
"size": tf.io.FixedLenFeature([2], tf.int64), # two integers
"float_data": tf.io.VarLenFeature(tf.float32) # a variable number of floats
}
# decode the TFRecord
tf_record = tf.io.parse_single_example(data, features)
# FixedLenFeature fields are now ready to use
sz = tf_record['size']
# Typical code for decoding compressed images
image = tf.io.decode_jpeg(tf_record['image'], channels=3)
# VarLenFeature fields require additional sparse.to_dense decoding
float_data = tf.sparse.to_dense(tf_record['float_data'])
return image, sz, float_data
# decoding a tf.data.TFRecordDataset
dataset = dataset.map(read_tfrecord)
# now a dataset of triplets (image, sz, float_data)
काम के कोड स्निपेट:
एकल डेटा एलिमेंट को पढ़ना
tf.io.FixedLenFeature([], tf.string) # for one byte string
tf.io.FixedLenFeature([], tf.int64) # for one int
tf.io.FixedLenFeature([], tf.float32) # for one float
एलिमेंट के तय साइज़ की सूचियों को पढ़ना
tf.io.FixedLenFeature([N], tf.string) # list of N byte strings
tf.io.FixedLenFeature([N], tf.int64) # list of N ints
tf.io.FixedLenFeature([N], tf.float32) # list of N floats
डेटा आइटम की अलग-अलग संख्या को पढ़ना
tf.io.VarLenFeature(tf.string) # list of byte strings
tf.io.VarLenFeature(tf.int64) # list of ints
tf.io.VarLenFeature(tf.float32) # list of floats
VarLenFeature, स्पैर्स वेक्टर दिखाता है. TFRecord को डिकोड करने के बाद, एक और चरण पूरा करना ज़रूरी है:
dense_data = tf.sparse.to_dense(tf_record['my_var_len_feature'])
TFRecords में वैकल्पिक फ़ील्ड भी रखे जा सकते हैं. अगर किसी फ़ील्ड को पढ़ते समय आपने कोई डिफ़ॉल्ट वैल्यू तय की है, तो फ़ील्ड मौजूद न होने पर गड़बड़ी के बजाय डिफ़ॉल्ट वैल्यू दिखती है.
tf.io.FixedLenFeature([], tf.int64, default_value=0) # this field is optional
इसमें हमने इन विषयों के बारे में बताया
- 🤔 GCS से तेज़ी से ऐक्सेस करने के लिए, डेटा फ़ाइलों को अलग-अलग हिस्सों में बांटना
- 🎊 TFRecords लिखने का तरीका जानें. (क्या आपको सिंटैक्स याद नहीं है? कोई बात नहीं, इस पेज को चीट शीट के तौर पर बुकमार्क करें)
- 🤔 TFRecordDataset का इस्तेमाल करके TFRecords से डेटासेट लोड करना
कृपया कुछ समय निकालकर इस चेकलिस्ट को देखें.
6. [जानकारी] न्यूरल नेटवर्क क्लासिफ़ायर के बारे में बुनियादी जानकारी
कम शब्दों में
अगर अगले पैराग्राफ़ में बोल्ड में लिखे गए सभी शब्द आपको पहले से ही पता हैं, तो अगले एक्सरसाइज़ पर जाएं. अगर आपने डीप लर्निंग की शुरुआत अभी-अभी की है, तो आपका स्वागत है. कृपया आगे पढ़ें.
लेयर के क्रम में बनाए गए मॉडल के लिए, Keras Sequential API उपलब्ध कराता है. उदाहरण के लिए, तीन सघन लेयर वाले इमेज क्लासिफ़ायर को Keras में इस तरह लिखा जा सकता है:
model = tf.keras.Sequential([
tf.keras.layers.Flatten(input_shape=[192, 192, 3]),
tf.keras.layers.Dense(500, activation="relu"),
tf.keras.layers.Dense(50, activation="relu"),
tf.keras.layers.Dense(5, activation='softmax') # classifying into 5 classes
])
# this configures the training of the model. Keras calls it "compiling" the model.
model.compile(
optimizer='adam',
loss= 'categorical_crossentropy',
metrics=['accuracy']) # % of correct answers
# train the model
model.fit(dataset, ... )
डेंस न्यूरल नेटवर्क
यह इमेज को अलग-अलग कैटगरी में बांटने के लिए सबसे आसान न्यूरल नेटवर्क है. यह लेयर में व्यवस्थित "न्यूरॉन" से बना होता है. पहली लेयर, इनपुट डेटा को प्रोसेस करती है और अपने आउटपुट को अन्य लेयर में फ़ीड करती है. इसे "डेंस" इसलिए कहा जाता है, क्योंकि हर न्यूरॉन पिछली लेयर के सभी न्यूरॉन से जुड़ा होता है.
किसी इमेज को इस तरह के नेटवर्क में फ़ीड करने के लिए, उसके सभी पिक्सल की आरजीबी वैल्यू को एक लंबे वेक्टर में फ़्लैट करें और उसे इनपुट के तौर पर इस्तेमाल करें. इमेज को पहचानने के लिए, यह सबसे अच्छी तकनीक नहीं है. हालांकि, हम इसे बाद में बेहतर बनाएंगे.
न्यूरोन, ऐक्टिवेशन, RELU
एक "न्यूरॉन" अपने सभी इनपुट के वेटेड योग की गणना करता है, "बायस" नाम की एक वैल्यू जोड़ता है, और एक तथाकथित "ऐक्टिवेशन फ़ंक्शन" के ज़रिए नतीजे को फ़ीड करता है. शुरुआत में, वेट और बायस की जानकारी नहीं होती. न्यूरल नेटवर्क को कई तरह के डेटा के आधार पर ट्रेनिंग देकर, उन्हें किसी भी क्रम में शुरू किया जाएगा और "सीखना" होगा.
सबसे ज़्यादा लोकप्रिय ऐक्टिवेशन फ़ंक्शन को रेक्टिफ़ाइड लीनियर यूनिट के लिए RELU कहा जाता है. यह एक बहुत ही आसान फ़ंक्शन है, जिसे ऊपर दिए गए ग्राफ़ में देखा जा सकता है.
सॉफ़्टमैक्स ऐक्टिवेशन
ऊपर दिया गया नेटवर्क एक 5-न्यूरॉन लेयर पर खत्म होता है, क्योंकि हम फूलों को पांच कैटगरी (रोज़, ट्यूलिप, डैंडलायन, डेज़ी, सनफ़्लावर) में बांट रहे हैं. इंटरमीडिएट लेयर में न्यूरॉन, क्लासिक RELU ऐक्टिवेशन फ़ंक्शन का इस्तेमाल करके चालू किए जाते हैं. हालांकि, आखिरी लेयर में हम 0 और 1 के बीच की संख्याओं का हिसाब लगाना चाहते हैं. इससे पता चलता है कि इस फूल के गुलाब, ट्यूलिप वगैरह होने की संभावना है. इसके लिए, हम "softmax" नाम के ऐक्टिवेशन फ़ंक्शन का इस्तेमाल करेंगे.
किसी वेक्टर पर सॉफ़्टमैक्स लागू करने के लिए, हर एलिमेंट का एक्सपोनेंशियल लेते हैं. इसके बाद, वेक्टर को सामान्य करते हैं. आम तौर पर, L1 नॉर्म (एब्सोल्यूट वैल्यू का योग) का इस्तेमाल करके ऐसा किया जाता है, ताकि वैल्यू 1 हो जाए और उन्हें संभावनाओं के तौर पर समझा जा सके.
क्रॉस-एंट्रॉपी लॉस
अब हमारा न्यूरल नेटवर्क, इनपुट इमेज से अनुमान लगाता है.इसलिए, हमें यह मेज़र करना होगा कि ये अनुमान कितने सही हैं. इसका मतलब है कि नेटवर्क के बताए गए अनुमान और सही जवाबों के बीच की दूरी, जिसे अक्सर "लेबल" कहा जाता है. याद रखें कि हमारे पास डेटासेट में मौजूद सभी इमेज के लिए सही लेबल हैं.
कोई भी डिस्टेंस काम करेगी, लेकिन कैटगरी तय करने से जुड़ी समस्याओं के लिए, "क्रॉस-एन्ट्रोपी डिस्टेंस" सबसे असरदार है. हम इसे अपनी गड़बड़ी या "लॉस" फ़ंक्शन कहेंगे:
ग्रेडिएंट डिसेंट
न्यूरल नेटवर्क को "ट्रेनिंग" देने का मतलब है, ट्रेनिंग इमेज और लेबल का इस्तेमाल करके वेट और बायस में बदलाव करना, ताकि क्रॉस-एन्ट्रोपी लॉस फ़ंक्शन को कम किया जा सके. यह सुविधा इस तरह काम करती है.
क्रॉस-एन्ट्रोपी, ट्रेनिंग इमेज और उसकी क्लास के पिक्सल, वेट, और बायस का फ़ंक्शन है.
अगर हम सभी वेट और सभी पूर्वाग्रहों के सापेक्ष क्रॉस-एंट्रॉपी के आंशिक डेरिवेटिव का हिसाब लगाते हैं, तो हमें दी गई इमेज, लेबल, और भार और पक्षपात के मौजूदा मान के लिए एक "ग्रेडिएंट" मिलता है. याद रखें कि हमारे पास लाखों वज़न और पूर्वाग्रह हो सकते हैं, इसलिए ग्रेडिएंट की गणना करना बहुत बड़ा काम है. अच्छी बात यह है कि Tensorflow यह काम हमारे लिए करता है. ग्रेडिएंट की गणितीय प्रॉपर्टी यह है कि यह "ऊपर" की ओर इंगित करता है. हमें क्रॉस-एन्ट्रापी कम करने के लिए, इसके उलट दिशा में जाना होगा. हम वज़न और बायस को ग्रेडिएंट के एक हिस्से से अपडेट करते हैं. इसके बाद, हम ट्रेनिंग लूप में ट्रेनिंग इमेज और लेबल के अगले बैच का इस्तेमाल करके, यही काम बार-बार करते हैं. उम्मीद है कि यह ऐसी जगह इकट्ठा होता है जहां क्रॉस-एंट्रॉपी बहुत कम होती है. हालांकि, इस बात की गारंटी नहीं है कि यह कम से कम यूनीक होगा.
छोटी-छोटी बैच और मोमेंटम
आप सिर्फ़ एक उदाहरण इमेज पर अपने ग्रेडिएंट का हिसाब लगा सकते हैं और महत्व और पक्षपात को तुरंत अपडेट कर सकते हैं, लेकिन उदाहरण के लिए, 128 इमेज के बैच पर ऐसा करने से ग्रेडिएंट मिलता है, जो अलग-अलग उदाहरण वाली इमेज के ज़रिए लागू किए गए कंस्ट्रेंट को बेहतर तरीके से दिखाता है और इससे समाधान ज़्यादा तेज़ी से जुड़ सकता है. मिनी-बैच का साइज़, अडजस्ट किया जा सकने वाला पैरामीटर होता है.
इस तकनीक को कभी-कभी "स्टोकास्टिक ग्रेडिएंट डिसेंट" कहा जाता है. इसका एक और फ़ायदा है: बैच के साथ काम करने का मतलब है कि बड़े मैट्रिक्स के साथ काम करना. आम तौर पर, जीपीयू और टीपीयू पर इन मैट्रिक्स को ऑप्टिमाइज़ करना आसान होता है.
हालांकि, कन्वर्ज़न अब भी थोड़ा गड़बड़ा हो सकता है और अगर ग्रेडिएंट वेक्टर में सभी वैल्यू शून्य हैं, तो यह रुक भी सकता है. क्या इसका मतलब यह है कि हमें कम से कम इतना डेटा मिल गया है? हमेशा नहीं. ग्रेडिएंट कॉम्पोनेंट, कम से कम या ज़्यादा से ज़्यादा वैल्यू पर शून्य हो सकता है. लाखों तत्वों वाले ग्रेडिएंट वेक्टर के साथ, अगर वे सभी शून्य हैं, तो इस बात की संभावना है कि हर शून्य एक न्यूनतम बिंदु से मेल खाता है और उनमें से कोई भी अधिकतम बिंदु से नहीं जुड़ा है. कई डाइमेंशन के क्षेत्र में, सैडल पॉइंट काफ़ी आम हो गए हैं और हम इन पर ही नहीं रुकना चाहते.
इलस्ट्रेशन: सैडल पॉइंट. ग्रेडिएंट 0 है लेकिन यह सभी दिशाओं में कम से कम नहीं है. (इमेज एट्रिब्यूशन Wikimedia: by Nicoguro - खुद का काम, CC BY 3.0)
इसका समाधान यह है कि ऑप्टिमाइज़ेशन एल्गोरिदम में कुछ मोमेंटम जोड़ा जाए, ताकि वह बिना रुके सैडल पॉइंट को पार कर सके.
शब्दावली
बैच या मिनी-बैच: ट्रेनिंग, हमेशा ट्रेनिंग डेटा और लेबल के बैच पर की जाती है. ऐसा करने से एल्गोरिदम को एक जैसी चीज़ों के बारे में जानने में मदद मिलती है. आम तौर पर, "बैच" डाइमेंशन, डेटा टेंसर का पहला डाइमेंशन होता है. उदाहरण के लिए, [100, 192, 192, 3] शेप वाले टेंसर में, 192x192 पिक्सल की 100 इमेज होती हैं. हर पिक्सल में तीन वैल्यू (आरजीबी) होती हैं.
क्रॉस-एंट्रॉपी लॉस: एक खास लॉस फ़ंक्शन जिसका इस्तेमाल अक्सर क्लासिफ़ायर में किया जाता है.
डेंस लेयर: यह न्यूरॉन की एक ऐसी लेयर होती है जिसमें हर न्यूरॉन, पिछली लेयर के सभी न्यूरॉन से जुड़ा होता है.
features: न्यूरल नेटवर्क के इनपुट को कभी-कभी "सुविधाएं" कहा जाता है. "फ़ीचर इंजीनियरिंग", यह पता लगाने की कला को "फ़ीचर इंजीनियरिंग" कहा जाता है. इसकी मदद से यह पता लगाया जा सकता है कि बेहतर अनुमान पाने के लिए, न्यूरल नेटवर्क में डेटासेट के किन हिस्सों या हिस्सों के कॉम्बिनेशन को फ़ीड किया जाए.
लेबल: "क्लास" के लिए कोई अन्य नाम या निगरानी में रखे गए क्लासिफ़िकेशन की समस्या में सही जवाब
लर्निंग रेट: ग्रेडिएंट का वह हिस्सा जिससे ट्रेनिंग लूप के हर दोहराव पर वेट और बायस अपडेट होते हैं.
लॉगिट: ऐक्टिवेशन फ़ंक्शन लागू करने से पहले, न्यूरॉन की लेयर के आउटपुट को "लॉगिट" कहा जाता है. यह शब्द, "लॉजिस्टिक फ़ंक्शन" से लिया गया है. इसे "सिगमोइड फ़ंक्शन" भी कहा जाता है. यह सबसे लोकप्रिय ऐक्टिवेशन फ़ंक्शन था. "लॉजिस्टिक फ़ंक्शन से पहले न्यूरॉन आउटपुट" को छोटा करके "लॉगिट" कर दिया गया.
लॉस: गड़बड़ी का फ़ंक्शन, न्यूरल नेटवर्क आउटपुट की तुलना सही जवाबों से करता है
न्यूरॉन: यह अपने इनपुट के भारित योग का आकलन करता है, पूर्वाग्रह जोड़ता है और ऐक्टिवेशन फ़ंक्शन के ज़रिए नतीजे को फ़ीड करता है.
वन-हॉट एन्कोडिंग: पांच में से तीसरी क्लास को पांच एलिमेंट के वेक्टर के तौर पर एन्कोड किया जाता है. इसमें तीसरे एलिमेंट को छोड़कर सभी एलिमेंट शून्य होते हैं.
relu: रिक्टिफ़ाइड लीनियर यूनिट. न्यूरॉन के लिए एक लोकप्रिय ऐक्टिवेशन फ़ंक्शन.
sigmoid: ऐक्टिवेशन का एक और ऐसा फ़ंक्शन जो पहले लोकप्रिय हुआ था और खास मामलों में अब भी काम का है.
सॉफ़्टमैक्स: यह एक खास ऐक्टिवेशन फ़ंक्शन है, जो वेक्टर पर काम करता है. यह सबसे बड़े कॉम्पोनेंट और बाकी सभी के बीच के अंतर को बढ़ाता है. साथ ही, वेक्टर को 1 का योग करने के लिए नॉर्मलाइज़ करता है, ताकि इसे प्रॉबबिलिटी के वेक्टर के रूप में समझा जा सके. इसका इस्तेमाल, क्लासिफ़ायर में आखिरी चरण के तौर पर किया जाता है.
टेंसर: "टेंसर", मैट्रिक्स की तरह ही होता है. हालांकि, इसमें डाइमेंशन की संख्या ज़रूरी नहीं होती. एक डाइमेंशन वाला टेंसर, एक वेक्टर होता है. 2-डाइमेंशन टेंसर एक मैट्रिक्स होता है. इसके बाद, आपके पास तीन, चार, पांच या उससे ज़्यादा डाइमेंशन वाले टेंसर हो सकते हैं.
7. ट्रांसफ़र लर्निंग
किसी चित्र वर्गीकरण समस्या के लिए, सघन परतें संभवतः पर्याप्त नहीं होंगी. हमें कॉन्वोल्यूशनल लेयर और उन्हें व्यवस्थित करने के कई तरीकों के बारे में जानना होगा.
हालांकि, हम एक शॉर्टकट भी अपना सकते हैं! डाउनलोड करने के लिए पूरी तरह से ट्रेन किए गए कॉन्वोलूशनल न्यूरल नेटवर्क उपलब्ध हैं. इसकी आखिरी लेयर यानी सॉफ़्टमैक्स क्लासिफ़िकेशन हेड को काटकर, उसकी जगह अपनी खुद की लेयर लगाई जा सकती है. ट्रेन किए गए सभी वेट और बायस पहले जैसे ही रहते हैं. सिर्फ़ जोड़ी गई सॉफ़्टमैक्स लेयर को फिर से ट्रेन किया जाता है. इस तकनीक को ट्रांसफ़र लर्निंग कहा जाता है. यह तब तक काम करती है, जब तक कि जिस डेटासेट पर न्यूरल नेट को पहले से ट्रेन किया गया है वह आपके डेटासेट से "काफ़ी मिलता-जुलता" हो.
हाथों से सीखना
कृपया यहां दी गई नोटबुक खोलें, सेल (Shift-ENTER) चलाएं और जहां भी आपको "काम ज़रूरी है" लेबल दिखे वहां निर्देशों का पालन करें.
Keras Flowers transfer learning (playground).ipynb
ज़्यादा जानकारी
ट्रांसफ़र लर्निंग की मदद से, आपको टॉप रिसर्चर के बनाए गए बेहतर कन्वोल्यूशनल न्यूरल नेटवर्क आर्किटेक्चर और इमेज के बड़े डेटासेट पर प्री-ट्रेनिंग, दोनों का फ़ायदा मिलता है. हमारे मामले में, हम ImageNet पर ट्रेन किए गए नेटवर्क से ट्रांसफ़र लर्निंग करेंगे. यह इमेज का एक डेटाबेस है, जिसमें कई पौधे और बाहरी जगहों की इमेज शामिल हैं. ये इमेज, फूलों से काफ़ी मिलती-जुलती हैं.
इलस्ट्रेशन: ब्लैक बॉक्स के तौर पर ट्रेन किए गए जटिल कॉन्वलूशन न्यूरल नेटवर्क का इस्तेमाल करके, सिर्फ़ क्लासिफ़िकेशन हेड को फिर से ट्रेनिंग दें. इसे ट्रांसफ़र लर्निंग कहते हैं. हम बाद में देखेंगे कि कॉन्वोल्यूशनल लेयर की ये जटिल व्यवस्थाएं कैसे काम करती हैं. फ़िलहाल, यह किसी और की समस्या है.
Keras में ट्रांसफ़र लर्निंग
Keras में, tf.keras.applications.*
कलेक्शन से पहले से ट्रेन किए गए मॉडल को इंस्टैंशिएट किया जा सकता है. उदाहरण के लिए, MobileNet V2 एक बहुत अच्छा कॉन्वोल्यूशनल आर्किटेक्चर है, जो साइज़ में कम रहता है. include_top=False
को चुनने पर, आपको फ़ाइनल सॉफ़्टमैक्स लेयर के बिना पहले से ट्रेन किए गए मॉडल का ऐक्सेस मिलता है, ताकि आप अपना खुद का मॉडल जोड़ सकें:
pretrained_model = tf.keras.applications.MobileNetV2(input_shape=[*IMAGE_SIZE, 3], include_top=False)
pretrained_model.trainable = False
model = tf.keras.Sequential([
pretrained_model,
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(5, activation='softmax')
])
pretrained_model.trainable = False
सेटिंग पर भी ध्यान दें. यह पहले से ट्रेन किए गए मॉडल के वेट और बायस को फ़्रीज़ कर देता है, ताकि आप सिर्फ़ अपनी सॉफ़्टमैक्स लेयर को ट्रेन कर सकें. आम तौर पर, इसमें कम वज़न शामिल होते हैं. साथ ही, इसे तेज़ी से और बहुत बड़े डेटासेट की ज़रूरत के बिना किया जा सकता है. हालांकि, अगर आपके पास ज़्यादा डेटा है, तो ट्रांसफ़र लर्निंग pretrained_model.trainable = True
के साथ बेहतर तरीके से काम कर सकती है. इसके बाद, पहले से ट्रेन किए गए वेट से बेहतर शुरुआती वैल्यू मिलती हैं. साथ ही, ट्रेनिंग की मदद से इन वैल्यू में बदलाव करके, उन्हें आपकी समस्या के हिसाब से बनाया जा सकता है.
आखिर में, अपनी डेंस सॉफ़्टमैक्स लेयर से पहले डाली गई Flatten()
लेयर पर ध्यान दें. डेंस लेयर, डेटा के फ़्लैट वैक्टर पर काम करती हैं. हालांकि, हमें नहीं पता कि पहले से ट्रेन किया गया मॉडल क्या दिखाता है. इसलिए, हमें फ़्लैट करने की ज़रूरत है. अगले चैप्टर में कॉन्वोलूशनल आर्किटेक्चर के बारे में विस्तार से बात करने पर, हम कॉन्वलूशन लेयर के डेटा के फ़ॉर्मैट के बारे में बताएंगे.
इस तरीके से, आपको करीब 75% सटीक जानकारी मिल सकती है.
समाधान
यहां समाधान वाली नोटबुक दी गई है. कोई समस्या आने पर, इसका इस्तेमाल किया जा सकता है.
Keras Flowers transfer learning (solution).ipynb
इसमें हमने इन विषयों के बारे में बताया
- 🤔 Keras में क्लासिफ़ायर लिखने का तरीका
- 🤓 सॉफ़्टमैक्स आखिरी लेयर के साथ कॉन्फ़िगर किया गया और क्रॉस-एंट्रॉपी लॉस
- 😈 ट्रांसफ़र लर्निंग
- 🤔 अपने पहले मॉडल को ट्रेनिंग देना
- 🧐 ट्रेनिंग के दौरान, हार-जीत और सटीक नतीजे का पता लगाना
कृपया एक मिनट निकालकर, इस चेकलिस्ट को ध्यान से पढ़ें.
8. [INFO] कॉन्वोलूशनल न्यूरल नेटवर्क
कम शब्दों में
अगर अगले पैराग्राफ़ में बोल्ड में दिए गए सभी शब्दों के बारे में आपको पहले से पता है, तो अगले अभ्यास पर जाएं. अगर आपने अभी-अभी कॉन्वोल्यूशनल न्यूरल नेटवर्क का इस्तेमाल शुरू किया है, तो कृपया आगे पढ़ें.
इलस्ट्रेशन: किसी इमेज को दो फ़िल्टर से फ़िल्टर किया जा रहा है. हर फ़िल्टर में 4x4x3=48 लर्न किए जा सकने वाले वेट हैं.
Keras में ऐसा सिंपल कॉन्वोलूशन न्यूरल नेटवर्क दिखता है:
model = tf.keras.Sequential([
# input: images of size 192x192x3 pixels (the three stands for RGB channels)
tf.keras.layers.Conv2D(kernel_size=3, filters=24, padding='same', activation='relu', input_shape=[192, 192, 3]),
tf.keras.layers.Conv2D(kernel_size=3, filters=24, padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=2),
tf.keras.layers.Conv2D(kernel_size=3, filters=12, padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=2),
tf.keras.layers.Conv2D(kernel_size=3, filters=6, padding='same', activation='relu'),
tf.keras.layers.Flatten(),
# classifying into 5 categories
tf.keras.layers.Dense(5, activation='softmax')
])
model.compile(
optimizer='adam',
loss= 'categorical_crossentropy',
metrics=['accuracy'])
कन्वोल्यूशनल न्यूरल नेट के बारे में बुनियादी जानकारी
कॉन्वलूशनल नेटवर्क की एक लेयर में, एक "न्यूरॉन" इमेज के एक छोटे से क्षेत्र में इसके ठीक ऊपर पिक्सल का वेटेड योग करता है. यह पूर्वाग्रह जोड़ता है और ऐक्टिवेशन फ़ंक्शन के ज़रिए योग को फ़ीड करता है, जैसा कि किसी नियमित सघन परत में मौजूद न्यूरॉन करता है. इसके बाद, इसी वेट का इस्तेमाल करके पूरी इमेज में यह प्रोसेस दोहराई जाती है. याद रखें कि घनी लेयर में, हर न्यूरॉन का अपना वेट होता है. यहां, वज़न का एक "पैच" पूरी इमेज पर दोनों दिशाओं में स्लाइड होता है ("संकलन"). आउटपुट में उतनी ही वैल्यू होती हैं जितने पिक्सल इमेज में होते हैं. हालांकि, किनारों पर कुछ पैडिंग ज़रूरी है. यह एक फ़िल्टरिंग ऑपरेशन है, जिसमें 4x4x3=48 वेट के फ़िल्टर का इस्तेमाल किया जाता है.
हालांकि, 48 भार काफ़ी नहीं होंगे. ज़्यादा आज़ादी की कार्रवाई जोड़ने के लिए, हम इसी कार्रवाई को एक नए सेट के साथ दोहराते हैं. इससे फ़िल्टर आउटपुट का एक नया सेट बनता है. इनपुट इमेज में R,G,B चैनलों की तरह ही, इसे आउटपुट का "चैनल" कहें.
नया डाइमेंशन जोड़कर, वेट के दो (या उससे ज़्यादा) सेट को एक टेंसर के तौर पर जोड़ा जा सकता है. इससे हमें कॉन्वोल्यूशनल लेयर के लिए, वेट टेंसर का सामान्य आकार मिलता है. इनपुट और आउटपुट चैनल की संख्या पैरामीटर हैं. इसलिए, हम कॉन्वोलूशनल लेयर को स्टैक और चेन करना शुरू कर सकते हैं.
इलस्ट्रेशन: कॉन्वलूशनल न्यूरल नेटवर्क, डेटा के "क्यूब्स" को डेटा के अन्य "क्यूब्स" में बदलता है.
स्टैंडेड कॉन्वोलूशन, ज़्यादा से ज़्यादा पूल करना
दो या तीन की स्ट्राइड के साथ कॉन्वोल्यूशन करने पर, हम नतीजे वाले डेटा क्यूब को उसके हॉरिज़ॉन्टल डाइमेंशन में भी छोटा कर सकते हैं. ऐसा करने के दो सामान्य तरीके हैं:
- स्ट्राइड वाला कन्वोल्यूशन: ऊपर बताए गए स्लाइडिंग फ़िल्टर की तरह ही, लेकिन स्ट्राइड >1 के साथ
- अधिकतम पूलिंग: MAX ऑपरेशन लागू करने वाली स्लाइड करने वाली विंडो (आम तौर पर 2x2 पैच पर, हर 2 पिक्सेल में दोहराया जाता है)
इलस्ट्रेशन: कंप्यूटिंग विंडो को तीन पिक्सल स्लाइड करने से आउटपुट वैल्यू कम हो जाती है. स्ट्राइड्ड कन्वर्ज़न या मैक्स पूलिंग, हॉरिज़ॉन्टल डाइमेंशन में डेटा क्यूब को छोटा करने का एक तरीका है. मैक्स पूलिंग का मतलब है कि विंडो को 2x2 वाली विंडो पर ले जाना, ज़्यादा से ज़्यादा दो लाइनों के साथ स्लाइड करना है.
ऑनवोलूशनल क्लासिफ़ायर
आखिर में, हम आखिरी डेटा क्यूब को समतल करके और उसे एक सघन, सॉफ़्टमैक्स-एक्टिव लेयर के ज़रिए फ़ीड करके, क्लासिफ़िकेशन हेड को अटैच करते हैं. एक सामान्य कॉन्वोलूशनल क्लासिफ़ायर ऐसा दिख सकता है:
इलस्ट्रेशन: इमेज की कैटगरी तय करने वाला एल्गोरिदम, जिसमें कन्वर्ज़न और सॉफ़्टमैक्स लेयर का इस्तेमाल किया गया है. इसमें 3x3 और 1x1 फ़िल्टर का इस्तेमाल किया जाता है. मैक्सपूल लेयर, 2x2 डेटा पॉइंट के ग्रुप में से सबसे ज़्यादा डेटा पॉइंट लेती हैं. क्लासिफ़िकेशन हेड को सॉफ़्टमैक्स ऐक्टिवेशन वाली डेंस लेयर के साथ लागू किया जाता है.
Keras में
ऊपर दिखाए गए कॉन्वोल्यूशनल स्टैक को Keras में इस तरह लिखा जा सकता है:
model = tf.keras.Sequential([
# input: images of size 192x192x3 pixels (the three stands for RGB channels)
tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu', input_shape=[192, 192, 3]),
tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=2),
tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu'),
tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=2),
tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu'),
tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=2),
tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu'),
tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=2),
tf.keras.layers.Conv2D(kernel_size=3, filters=16, padding='same', activation='relu'),
tf.keras.layers.Conv2D(kernel_size=1, filters=8, padding='same', activation='relu'),
tf.keras.layers.Flatten(),
# classifying into 5 categories
tf.keras.layers.Dense(5, activation='softmax')
])
model.compile(
optimizer='adam',
loss= 'categorical_crossentropy',
metrics=['accuracy'])
9. आपका कस्टम कन्वर्ज़न
हाथों से सीखना
आइए, शुरू से ही एक कॉन्वोल्यूशनल न्यूरल नेटवर्क बनाएं और उसे ट्रेनिंग दें. TPU का इस्तेमाल करने से, हमें तेज़ी से बदलाव करने में मदद मिलेगी. कृपया यहां दी गई नोटबुक खोलें, सेल (Shift-ENTER) चलाएं और जहां भी आपको "काम ज़रूरी है" लेबल दिखे वहां निर्देशों का पालन करें.
Keras_Flowers_TPU (playground).ipynb
इसका लक्ष्य, ट्रांसफ़र लर्निंग मॉडल की 75% सटीकता को बेहतर बनाना है. उस मॉडल का एक फ़ायदा यह था कि उसे लाखों इमेज के डेटासेट की मदद से पहले से ट्रेनिंग दी गई, जबकि हमारे पास यहां सिर्फ़ 3670 इमेज हैं. क्या कम से कम इसकी बराबरी की जा सकती है?
ज़्यादा जानकारी
कितनी लेयर, कितनी बड़ी हैं?
लेयर का साइज़ चुनना, विज्ञान से ज़्यादा कला है. आपको बहुत कम और बहुत ज़्यादा पैरामीटर (वेट और पूर्वाग्रह) के बीच सही संतुलन बनाना होगा. बहुत कम भार के साथ, न्यूरल नेटवर्क फूलों के आकारों की जटिलता को प्रस्तुत नहीं कर सकता. बहुत ज़्यादा इमेज होने पर, मशीन लर्निंग मॉडल "ओवरफ़िट" हो सकता है. इसका मतलब है कि मॉडल, ट्रेनिंग इमेज में मौजूद खास जानकारी को ही समझता है और सामान्य जानकारी को समझने में सक्षम नहीं होता. बहुत ज़्यादा पैरामीटर होने पर, मॉडल की ट्रेनिंग भी धीमी हो जाएगी. Keras में, model.summary()
फ़ंक्शन आपके मॉडल का स्ट्रक्चर और पैरामीटर की संख्या दिखाता है:
Layer (type) Output Shape Param #
=================================================================
conv2d (Conv2D) (None, 192, 192, 16) 448
_________________________________________________________________
conv2d_1 (Conv2D) (None, 192, 192, 30) 4350
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 96, 96, 30) 0
_________________________________________________________________
conv2d_2 (Conv2D) (None, 96, 96, 60) 16260
_________________________________________________________________
...
_________________________________________________________________
global_average_pooling2d (Gl (None, 130) 0
_________________________________________________________________
dense (Dense) (None, 90) 11790
_________________________________________________________________
dense_1 (Dense) (None, 5) 455
=================================================================
Total params: 300,033
Trainable params: 300,033
Non-trainable params: 0
_________________________________________________________________
कुछ सुझाव:
- एक से ज़्यादा लेयर होना, "डीप" न्यूरल नेटवर्क को असरदार बनाता है. फूल की पहचान करने से जुड़ी इस आसान समस्या के लिए, पांच से 10 लेयर का इस्तेमाल करना सही रहेगा.
- छोटे फ़िल्टर का इस्तेमाल करें. आम तौर पर, 3x3 फ़िल्टर हर जगह अच्छे होते हैं.
- 1x1 फ़िल्टर का इस्तेमाल भी किया जा सकता है और ये सस्ते होते हैं. ये किसी भी चीज़ को "फ़िल्टर" नहीं करते, बल्कि चैनलों के लीनियर कॉम्बिनेशन का हिसाब लगाते हैं. असली फ़िल्टर की मदद से उन्हें चुनें. (अगले सेक्शन में "1x1 कॉन्वोल्यूशन" के बारे में ज़्यादा जानकारी दी गई है.)
- इस तरह की क्लासिफ़िकेशन वाली समस्या के लिए, मैक्स-पूलिंग लेयर (या स्ट्राइड >1 वाले कॉन्वोल्यूशन) के साथ अक्सर डाउनसैंपल करें. आपको यह नहीं पता कि फूल कहां है, सिर्फ़ यह पता है कि यह गुलाब है या डैंडेलियन. इसलिए, x और y की जानकारी खोना ज़रूरी नहीं है और छोटे इलाकों को फ़िल्टर करना सस्ता है.
- आम तौर पर, फ़िल्टर की संख्या नेटवर्क के आखिर में मौजूद क्लास की संख्या के बराबर हो जाती है. ऐसा क्यों होता है? इसके बारे में जानने के लिए, नीचे "ग्लोबल औसत पूलिंग" ट्रिक देखें. अगर कैटगरी को सैकड़ों में बांटा गया है, तो फ़िल्टर की गिनती लगातार लेयर में बढ़ाई जा सकती है. फूलों के डेटासेट के लिए, सिर्फ़ पांच फ़िल्टर इस्तेमाल करना काफ़ी नहीं है. ज़्यादातर लेयर में फ़िल्टर की एक ही संख्या का इस्तेमाल किया जा सकता है, जैसे कि 32 और उसे आखिर तक कम किया जा सकता है.
- सबसे घनी लेयर वाली लेयर महंगी है/हैं. इसमें सभी कन्वोल्यूशनल लेयर की तुलना में ज़्यादा वेट हो सकते हैं. उदाहरण के लिए, 24x24x10 डेटा पॉइंट के आखिरी डेटा क्यूब से मिलने वाले आउटपुट के बावजूद, 100 न्यूरॉन डेंसिटी लेयर की लागत 24x24x10x100=5,76, 000 वेट !!! सोच-समझकर बनाएं या ग्लोबल औसत पूलिंग आज़माएं (नीचे देखें).
दुनिया भर में औसत पूलिंग
कॉन्वोलूशनल न्यूरल नेटवर्क के आखिर में महंगी लेयर का इस्तेमाल करने के बजाय, आने वाले डेटा "क्यूब" को अलग-अलग हिस्सों में बांटा जा सकता है, क्योंकि आपके पास क्लास हैं. साथ ही, उनकी वैल्यू का औसत किया जा सकता है और उन्हें सॉफ़्टमैक्स ऐक्टिवेशन फ़ंक्शन की मदद से फ़ीड किया जा सकता है. क्लासिफ़िकेशन हेड बनाने के इस तरीके में कोई वज़न नहीं होगा. Keras में, सिंटैक्स tf.keras.layers.GlobalAveragePooling2D().
है
समाधान
यहां समाधान वाली नोटबुक दी गई है. कोई समस्या आने पर, इसका इस्तेमाल किया जा सकता है.
Keras_Flowers_TPU (solution).ipynb
इसमें हमने इन विषयों के बारे में बताया
- 🤔 कन्वर्ज़न लेयर के साथ चलाया गया
- 🤓 मैक्स पूलिंग, स्ट्राइड, ग्लोबल औसत पूलिंग वगैरह के साथ एक्सपेरिमेंट किया गया
- 😀 TPU पर, असल दुनिया के मॉडल पर तेज़ी से काम किया
कृपया कुछ समय निकालकर इस चेकलिस्ट को देखें.
10. [जानकारी] आधुनिक कॉन्वोल्यूशनल आर्किटेक्चर
कम शब्दों में
इलस्ट्रेशन: कॉन्वोलूशनल "मॉड्यूल". इस समय क्या करना सबसे सही होगा ? मैक्स-पूल लेयर के बाद, 1x1 कॉन्वोल्यूशन लेयर या अलग-अलग लेयर का कॉम्बिनेशन ? सभी को आज़माएं, नतीजों को जोड़ें, और नेटवर्क को तय करने दें. दाईं ओर: ऐसे मॉड्यूल का इस्तेमाल करने वाला " inception" कॉन्वोल्यूशनल आर्किटेक्चर.
Keras में, ऐसे मॉडल बनाने के लिए जिनमें डेटा फ़्लो, दो हिस्सों में बंटे हो सकता है, आपको "फ़ंक्शनल" मॉडल स्टाइल का इस्तेमाल करना होगा. उदाहरण के लिए:
l = tf.keras.layers # syntax shortcut
y = l.Conv2D(filters=32, kernel_size=3, padding='same',
activation='relu', input_shape=[192, 192, 3])(x) # x=input image
# module start: branch out
y1 = l.Conv2D(filters=32, kernel_size=1, padding='same', activation='relu')(y)
y3 = l.Conv2D(filters=32, kernel_size=3, padding='same', activation='relu')(y)
y = l.concatenate([y1, y3]) # output now has 64 channels
# module end: concatenation
# many more layers ...
# Create the model by specifying the input and output tensors.
# Keras layers track their connections automatically so that's all that's needed.
z = l.Dense(5, activation='softmax')(y)
model = tf.keras.Model(x, z)
अन्य गलत तरीके
छोटे 3x3 फ़िल्टर
इस इलस्ट्रेशन में, आपको लगातार दो 3x3 फ़िल्टर का नतीजा दिख रहा है. यह पता लगाने की कोशिश करें कि नतीजे में किन डेटा पॉइंट का योगदान रहा: ये दो लगातार 3x3 फ़िल्टर, 5x5 वाले रीजन के कुछ कॉम्बिनेशन को कंप्यूट करते हैं. यह कॉम्बिनेशन, 5x5 के जैसा नहीं है. हालांकि, इसे आज़माना फ़ायदेमंद है, क्योंकि 5x5 वाले फ़िल्टर के मुकाबले, लगातार 3x3 वाले दो फ़िल्टर सस्ते होते हैं.
1x1 कॉन्वोल्यूशन ?
गणित के हिसाब से, "1x1" कॉन्वोल्यूशन, किसी स्थिर वैल्यू से गुणा करने जैसा है. यह बहुत काम का कॉन्सेप्ट नहीं है. हालांकि, कॉन्वलूशनल न्यूरल नेटवर्क में यह याद रखें कि फ़िल्टर, सिर्फ़ 2D इमेज पर ही नहीं, बल्कि डेटा क्यूब पर लागू किया जाता है. इसलिए, "1x1" फ़िल्टर, डेटा के 1x1 कॉलम का वेटेड योग (इमेज देखें) कैलकुलेट करता है. साथ ही, डेटा पर इसे स्लाइड करने पर, आपको इनपुट के चैनलों का लीनियर कॉम्बिनेशन मिलेगा. यह असल में काम का है. अगर चैनलों को अलग-अलग फ़िल्टर करने के ऑपरेशन के नतीजों के तौर पर देखा जाए, तो "1x1" कॉन्वोल्यूशनल लेयर इन फ़ीचर के कई संभावित लीनियर कॉम्बिनेशन कैलकुलेट करेगी. ये "बिल्ली" खोजते समय काम आ सकते हैं. उदाहरण के लिए, "नुकीले कान", "मूंछ", और "छोटी आंखें" के लिए फ़िल्टर. सबसे बड़ी बात यह है कि 1x1 लेयर पर कम ट्रैफ़िक मिलता है.
11. Squeezenet
इन आइडिया को एक साथ इस्तेमाल करने का आसान तरीका, "Squeezenet" पेपर में दिखाया गया है. लेखकों ने एक बहुत ही आसान कॉन्वोल्यूशनल मॉड्यूल डिज़ाइन का सुझाव दिया है. इसमें सिर्फ़ 1x1 और 3x3 कॉन्वोल्यूशनल लेयर का इस्तेमाल किया गया है.
इलस्ट्रेशन: "फ़ायर मॉड्यूल" पर आधारित स्क्वीज़नेट आर्किटेक्चर. वे एक 1x1 लेयर को वैकल्पिक तौर पर इस्तेमाल करते हैं, जो इनकमिंग डेटा को वर्टिकल डाइमेंशन में "कम करता है". इसके बाद, दो पैरलल 1x1 और 3x3 कॉन्वोल्यूशनल लेयर का इस्तेमाल किया जाता है, जो डेटा की डेप्थ को फिर से "बढ़ाती" हैं.
हाथों से सीखना
अपनी पिछली नोटबुक में जारी रखें और स्क्वीज़नेट से प्रेरित कॉन्वलूशनल न्यूरल नेटवर्क बनाएं. आपको मॉडल कोड को Keras "फ़ंक्शनल स्टाइल" में बदलना होगा.
Keras_Flowers_TPU (playground).ipynb
ज़्यादा जानकारी
इस एक्सरसाइज़ के लिए, स्क्वाइज़नेट मॉड्यूल के लिए हेल्पर फ़ंक्शन तय करना मददगार होगा:
def fire(x, squeeze, expand):
y = l.Conv2D(filters=squeeze, kernel_size=1, padding='same', activation='relu')(x)
y1 = l.Conv2D(filters=expand//2, kernel_size=1, padding='same', activation='relu')(y)
y3 = l.Conv2D(filters=expand//2, kernel_size=3, padding='same', activation='relu')(y)
return tf.keras.layers.concatenate([y1, y3])
# this is to make it behave similarly to other Keras layers
def fire_module(squeeze, expand):
return lambda x: fire(x, squeeze, expand)
# usage:
x = l.Input(shape=[192, 192, 3])
y = fire_module(squeeze=24, expand=48)(x) # typically, squeeze is less than expand
y = fire_module(squeeze=32, expand=64)(y)
...
model = tf.keras.Model(x, y)
इस बार हमारा मकसद 80% सटीक अनुमान देना है.
इन तरीकों को आज़माएं
एक कॉन्वोलूशन लेयर से शुरू करें, फिर MaxPooling2D(pool_size=2)
लेयर के साथ बदलते हुए "fire_modules
" के साथ फ़ॉलो करें. नेटवर्क में दो से चार मैक्स पूलिंग लेयर का इस्तेमाल किया जा सकता है. साथ ही, मैक्स पूलिंग लेयर के बीच एक, दो या तीन फ़ायर मॉड्यूल का भी इस्तेमाल किया जा सकता है.
फ़ायर मॉड्यूल में, "स्क्वीज़" पैरामीटर आम तौर पर "बड़ा करें" पैरामीटर से छोटा होना चाहिए. ये पैरामीटर, असल में फ़िल्टर की संख्याएं होती हैं. आम तौर पर, यह संख्या 8 से 196 तक हो सकती है. ऐसे आर्किटेक्चर के साथ एक्सपेरिमेंट किया जा सकता है जिनमें नेटवर्क के ज़रिए, फ़िल्टर की संख्या धीरे-धीरे बढ़ती है. इसके अलावा, ऐसे सीधे आर्किटेक्चर इस्तेमाल किए जा सकते हैं जिनमें सभी फ़ायर मॉड्यूल में एक जैसे फ़िल्टर हों.
उदाहरण के लिए:
x = tf.keras.layers.Input(shape=[*IMAGE_SIZE, 3]) # input is 192x192 pixels RGB
y = tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu')(x)
y = fire_module(24, 48)(y)
y = tf.keras.layers.MaxPooling2D(pool_size=2)(y)
y = fire_module(24, 48)(y)
y = tf.keras.layers.MaxPooling2D(pool_size=2)(y)
y = fire_module(24, 48)(y)
y = tf.keras.layers.GlobalAveragePooling2D()(y)
y = tf.keras.layers.Dense(5, activation='softmax')(y)
model = tf.keras.Model(x, y)
इस स्थिति में, आपको लग सकता है कि आपके एक्सपेरिमेंट ठीक से काम नहीं कर रहे हैं. साथ ही, 80% सटीक नतीजे पाने का मकसद आपको रिमोट तरीके से दिख रहा है. कुछ और आसान तरकीबें आज़माने का समय आ गया है.
बैच नॉर्मलाइज़ेशन
बैच नॉर्म की मदद से, आपको कन्वर्ज़न से जुड़ी समस्याओं को हल करने में मदद मिलेगी. अगली वर्कशॉप में इस तकनीक के बारे में पूरी जानकारी दी जाएगी. फ़िलहाल, कृपया अपने नेटवर्क में हर कॉन्वोल्यूशनल लेयर के बाद यह लाइन जोड़कर, इसे ब्लैक बॉक्स "मैजिक" हेल्पर के तौर पर इस्तेमाल करें. इसमें fire_module फ़ंक्शन के अंदर मौजूद लेयर भी शामिल हैं:
y = tf.keras.layers.BatchNormalization(momentum=0.9)(y)
# please adapt the input and output "y"s to whatever is appropriate in your context
मोमेंटम पैरामीटर को उसकी डिफ़ॉल्ट वैल्यू 0.99 से घटाकर 0.9 करना होगा, क्योंकि हमारा डेटासेट छोटा है. फ़िलहाल, इस जानकारी को न दें.
डेटा बढ़ाना
सैचुरेशन बदलावों के बाएं-दाएं फ़्लिप जैसे आसान बदलावों से डेटा को बेहतर बनाने से आपको कुछ और प्रतिशत पॉइंट मिलेंगे:
Tensorflow में, tf.data.Dataset API की मदद से ऐसा करना काफ़ी आसान है. अपने डेटा के लिए, ट्रांसफ़ॉर्मेशन का नया फ़ंक्शन तय करें:
def data_augment(image, label):
image = tf.image.random_flip_left_right(image)
image = tf.image.random_saturation(image, lower=0, upper=2)
return image, label
इसके बाद, इसे अपने आखिरी डेटा ट्रांसफ़ॉर्मेशन (सेल "ट्रेनिंग और पुष्टि करने वाले डेटासेट", फ़ंक्शन "get_batched_dataset") में इस्तेमाल करें:
dataset = dataset.repeat() # existing line
# insert this
if augment_data:
dataset = dataset.map(data_augment, num_parallel_calls=AUTO)
dataset = dataset.shuffle(2048) # existing line
डेटा बढ़ाने की सुविधा को वैकल्पिक बनाना न भूलें. साथ ही, ज़रूरी कोड जोड़कर यह पक्का करें कि सिर्फ़ ट्रेनिंग डेटासेट को बढ़ाया गया हो. पुष्टि करने के लिए ज़्यादा डेटासेट का इस्तेमाल करने का कोई मतलब नहीं है.
35 युगों में 80% सटीक जानकारी अब पहुंच में होनी चाहिए.
समाधान
यहां समाधान वाली नोटबुक दी गई है. कोई समस्या आने पर, इसका इस्तेमाल किया जा सकता है.
Keras_Flowers_TPU_squeezenet.ipynb
इसमें हमने इन विषयों के बारे में बताया
- 🤔 Keras "फ़ंक्शनल स्टाइल" मॉडल
- 🤓 स्क्वीज़नेट आर्किटेक्चर
- 🤓 tf.data.datset की मदद से डेटा बढ़ाना
कृपया कुछ समय निकालकर इस चेकलिस्ट को देखें.
12. Xception को फ़ाइन-ट्यून किया गया
अलग-अलग कॉन्वोल्यूशन
हाल ही में, कॉन्वोल्यूशनल लेयर लागू करने का एक अलग तरीका लोकप्रिय हो रहा है: डेप्थ-सेपरेबल कॉन्वोल्यूशन. मुझे पता है कि यह समझने में मुश्किल है, लेकिन इसका कॉन्सेप्ट बहुत आसान है. इन्हें Tensorflow और Keras में tf.keras.layers.SeparableConv2D
के तौर पर लागू किया जाता है.
अलग-अलग कॉन्वोल्यूशन, इमेज पर फ़िल्टर भी चलाता है. हालांकि, यह इनपुट इमेज के हर चैनल के लिए, वेट के अलग-अलग सेट का इस्तेमाल करता है. यह "1x1 कन्वलूशन" के साथ फ़ॉलो किया जाता है. डॉट प्रॉडक्ट की एक सीरीज़, जो फ़िल्टर किए गए चैनलों का कुल योग तय करती है. हर बार नए वेट के साथ, चैनल के वेटेड रीकॉम्बिनेशन को ज़रूरत के मुताबिक कैलकुलेट किया जाता है.
इलस्ट्रेशन: अलग किए जा सकने वाले कन्वर्ज़न. पहला चरण: हर चैनल के लिए अलग फ़िल्टर के साथ कॉन्वोल्यूशन. दूसरा फ़ेज़: चैनलों का लीनियर रीकॉम्बिनेशन. जब तक आउटपुट चैनलों की ज़रूरी संख्या नहीं मिल जाती, तब तक वेट के नए सेट के साथ दोहराया जाता है. पहले चरण को भी दोहराया जा सकता है और हर बार नए वेट लागू किए जा सकते हैं. हालांकि, ज़्यादातर मामलों में ऐसा बहुत कम होता है.
अलग-अलग कॉन्वोल्यूशन का इस्तेमाल, हाल ही के कॉन्वोल्यूशनल नेटवर्क आर्किटेक्चर में किया जाता है: MobileNetV2, Xception, EfficientNet. वैसे, MobileNetV2 का इस्तेमाल ट्रांसफ़र लर्निंग के लिए पहले किया जाता था.
ये सामान्य कॉन्वोल्यूशन की तुलना में सस्ते होते हैं और इनकी परफ़ॉर्मेंस भी उतनी ही अच्छी होती है. ऊपर दिए गए उदाहरण के लिए, यहां वेट की संख्या दी गई है:
कॉन्वोल्यूशन लेयर: 4 x 4 x 3 x 5 = 240
अलग करने लायक कॉन्वलूशनल लेयर: 4 x 4 x 3 + 3 x 5 = 48 + 15 = 63
इसे पढ़ने वालों के लिए एक अभ्यास के तौर पर इस्तेमाल किया जाता है. इसमें, कॉन्वोलूशनल लेयर स्केल की हर स्टाइल को एक ही तरीके से लागू करने के लिए, मल्टीप्लिकेशन की संख्या के मुकाबले इसका कैलकुलेशन करना ज़रूरी है. अलग किए जा सकने वाले कन्वर्ज़न छोटे होते हैं और कंप्यूटेशनल तौर पर ज़्यादा असरदार होते हैं.
हैंड्स-ऑन
"ट्रांसफ़र लर्निंग" प्लेलैंड नोटबुक से फिर से शुरू करें. हालांकि, इस बार पहले से ट्रेन किए गए मॉडल के तौर पर Xception चुनें. Xception में सिर्फ़ अलग-अलग कॉन्वोल्यूशन का इस्तेमाल किया जाता है. सभी वेट को ट्रेनिंग के लिए उपलब्ध रखें. हम पहले से ट्रेन किए गए लेयर का इस्तेमाल करने के बजाय, अपने डेटा पर पहले से ट्रेन किए गए वेट को फ़ाइन-ट्यून करेंगे.
Keras Flowers transfer learning (playground).ipynb
लक्ष्य: 95% से ज़्यादा सटीक होना (वाकई, ऐसा हो सकता है!)
यह आखिरी कसरत है. इसके लिए, कोड और डेटा साइंस पर कुछ और काम करने की ज़रूरत है.
फ़ाइन-ट्यून करने के बारे में ज़्यादा जानकारी
Xception, tf.keras.application में पहले से ट्रेन किए गए स्टैंडर्ड मॉडल में उपलब्ध है.* इस बार, सभी वेट को ट्रेनिंग के लिए उपलब्ध रखना न भूलें.
pretrained_model = tf.keras.applications.Xception(input_shape=[*IMAGE_SIZE, 3],
include_top=False)
pretrained_model.trainable = True
किसी मॉडल को बेहतर बनाने के दौरान अच्छे नतीजे पाने के लिए, आपको लर्निंग रेट पर ध्यान देना होगा. साथ ही, रैंप-अप पीरियड के साथ लर्निंग रेट के शेड्यूल का इस्तेमाल करना होगा. इस तरह:
स्टैंडर्ड लर्निंग रेट से शुरू करने पर, मॉडल के पहले से ट्रेन किए गए वेट में रुकावट आएगी. डेटा को धीरे-धीरे अपडेट करने की सुविधा तब तक डेटा को सुरक्षित रखती है, जब तक मॉडल आपके डेटा को समझकर उसमें सही तरीके से बदलाव नहीं कर लेता. रैंप के बाद, लर्निंग रेट को एक जैसा या तेज़ी से घटते हुए रखा जा सकता है.
Keras में, लर्निंग रेट को कॉलबैक के ज़रिए तय किया जाता है. इसमें हर एपिसोड के लिए सही लर्निंग रेट का हिसाब लगाया जा सकता है. Keras, हर एपच के लिए ऑप्टिमाइज़र को सही लर्निंग रेट भेजेगा.
def lr_fn(epoch):
lr = ...
return lr
lr_callback = tf.keras.callbacks.LearningRateScheduler(lr_fn, verbose=True)
model.fit(..., callbacks=[lr_callback])
समाधान
यहां समाधान वाली नोटबुक दी गई है. कोई समस्या आने पर, इसका इस्तेमाल किया जा सकता है.
07_Keras_Flowers_TPU_xception_fine_tuned_best.ipynb
हमने क्या-क्या शामिल किया है
- 🤔 डेप्थ-सेपरेबल कन्वोल्यूशन
- 🤓 सीखने की दर के शेड्यूल
- 😈 पहले से ट्रेन किए गए मॉडल को बेहतर बनाना.
कृपया कुछ समय निकालकर इस चेकलिस्ट को देखें.
13. बधाई हो!
आपने अपना पहला आधुनिक कॉन्वोलूशनल न्यूरल नेटवर्क बना लिया है और उसे 90% + सटीक तरीके से ट्रेनिंग दी है. TPU की बदौलत, आप कुछ ही मिनटों में ट्रेनिंग रन कर चुके हैं.
TPU का इस्तेमाल
TPU और जीपीयू, Google Cloud के Vertex AI पर उपलब्ध हैं:
- डीप लर्निंग वीएम पर
- Vertex AI Notebooks में
- Vertex AI Training Jobs में नौकरियां
आखिर में, हमें आपके सुझाव, शिकायत या राय पाकर खुशी होगी. अगर आपको इस लैब में कुछ गड़बड़ी दिखती है या आपको लगता है कि इसमें सुधार किया जाना चाहिए, तो कृपया हमें बताएं. GitHub की समस्याओं [ सुझाव/राय देने या शिकायत करने के लिए लिंक] के ज़रिए सुझाव, शिकायत या राय दी जा सकती है.
|