फ़िट करने के लिए इसे छोटा करना
int8 quantisation हर वज़न (weight) को चार बाइट्स के बजाय एक बाइट में स्टोर करता है। इसे खुद numpy में करके देखें, और मापें कि आपने कितना साइज़ बचाया और कितनी एक्यूरेसी खोई।
60 सेकंड में
फ़िट करने के लिए इसे छोटा करना
int8 quantisation हर वज़न (weight) को चार बाइट्स के बजाय एक बाइट में स्टोर करता है। इसे खुद numpy में करके देखें, और मापें कि आपने कितना साइज़ बचाया और कितनी एक्यूरेसी खोई।
सिमेट्रिक int8 quantisation, सिलसिलेवार तरीके से
- 1
सबसे बड़ा weight खोजें
लेयर में सबसे बड़ा absolute मान लें, उदाहरण के लिए 1.3। - 2
एक scale चुनें
scale = सबसे बड़ा ÷ 127। अब int8 में 127 का मतलब सबसे बड़ा weight है। - 3
भाग दें और राउंड करें
q = round(weight ÷ scale), जिसे −127 … 127 तक क्लिप किया गया है, int8 के रूप में स्टोर करें। - 4
इसका उपयोग करें
लगभग वैसा ही weight वापस पाने के लिए: weight ≈ q × scale। इसमें एरर ज़्यादा से ज़्यादा आधे स्टेप (step) की होती है।
import numpy as np
w = np.array([0.83, -0.312, 0.051, -1.3, 0.644, 0.002])
scale = np.abs(w).max() / 127 # one float for the whole layer
q = np.round(w / scale).astype(np.int8)
back = q * scale
print("scale:", round(scale, 5))
print("int8: ", q)
print("back: ", back.round(4))
print("error:", np.abs(w - back).round(4))scale जितना बदला। अपने आकार के अनुपात में, सबसे छोटे weights को सबसे ज़्यादा नुकसान होता है। आखिरी weight, 0.002, 0 बन गया: यह आधे स्टेप से छोटा था।असली TinyML quantisation कुछ और भी चीज़ें करता है
- Activations भी। चिप पर, इनपुट्स और बीच के मान भी int8 होते हैं, ताकि पूरा मॉडल integer मैथ्स में चले। कन्वर्टर को उनके लिए scales चुनने के लिए असली उदाहरण इनपुट्स के एक छोटे सेट की ज़रूरत होती है, जिसे अक्सर representative dataset कहा जाता है।
- Zero points। जो मान शून्य पर केन्द्रित नहीं होते (उदाहरण के लिए, सभी पॉज़िटिव), वे zero point नामक एक अतिरिक्त ऑफ़सेट का उपयोग करते हैं, ताकि int8 रेंज बेकार न जाए।
- Per-channel scales। किसी लेयर का प्रत्येक आउटपुट चैनल अपना खुद का scale प्राप्त कर सकता है, जिससे आमतौर पर पूरी लेयर के लिए एक scale रखने की तुलना में कम एक्यूरेसी खोती है।
- Biases को अक्सर उच्च प्रिसिजन (उदाहरण के लिए int32) पर रखा जाता है, क्योंकि वे कम होते हैं और बहुत मायने रखते हैं।
- Quantisation-aware training मॉडल को ट्रेनिंग के दौरान राउंडिंग के साथ अभ्यास करने देती है, जो ट्रेनिंग के बाद साधारण राउंडिंग से होने वाले भारी एक्यूरेसी नुकसान की भरपाई कर सकती है।
- बिना मापे quantise करना और डिप्लॉय कर देना
- केवल कुल एक्यूरेसी जाँचना
- कुछ रैंडम इनपुट्स को representative dataset के रूप में उपयोग करना
- मान लेना कि Python और बोर्ड एक ही जवाब देंगे
- पहले और बाद के साइज़ तथा हेल्ड-आउट डेटा पर एक्यूरेसी को मापना
- प्रत्येक क्लास को जाँचना, खासकर दुर्लभ (rare) वाली
- ऐसे वास्तविक इनपुट्स का उपयोग करना जो उन सभी स्थितियों को कवर करते हैं जो डिवाइस देखेगा
- समान इनपुट्स पर बोर्ड के आउटपुट्स की तुलना Python के आउटपुट्स से करना
और देखें और पढ़ें
लैब
आपके अपने int8 quantise और dequantise फ़ंक्शन्स, जिसमें बचाए गए साइज़ और एक्यूरेसी में हुए बदलाव को मापा गया हो।
समस्या
स्टार्टर कोड scikit-learn के इन-बिल्ट 8×8 हस्तलिखित अंकों पर एक छोटा न्यूरल नेटवर्क ट्रेन करता है: एक मीटर डिस्प्ले को पढ़ने वाले छोटे कैमरे का विकल्प।
quantise(w)लिखें: scale = सबसे बड़ा absolute weight ÷ 127; q = round(w ÷ scale), जिसेnp.int8के रूप में −127 … 127 तक क्लिप किया गया हो।(q, scale)रिटर्न करें।dequantise(q, scale)लिखें: floats के रूप में q × scale रिटर्न करें।- इसे रन करें। पहले और बाद के weights का साइज़ बाइट्स में, और पहले और बाद की एक्यूरेसी लिखें।
- यहाँ केवल weights को quantise किया गया है; biases float ही रहते हैं। एक वाक्य लिखें कि एक वास्तविक बोर्ड activations को भी quantise क्यों करेगा।
प्रैक्टिस लैब
कोड में बदलाव करें और इसे रन करें। Python आपके ब्राउज़र में चलता है — हमारे सर्वर पर कुछ नहीं भेजा जाता।
कोई आउटपुट नहीं। वैल्यूज़ देखने के लिए print(...) जोड़ें।
आपका काम तब पूरा होगा जब
कठिन सवाल
उत्तर देखने से पहले ख़ुद जवाब देने की कोशिश करें। अगर आप इनके जवाब दे सकते हैं, तो आप पाठ समझ गए हैं।
Q1हम केवल दशमलव हटाने (कट ऑफ़ करने) के बजाय राउंड क्यों करते हैं?दिखाएं
राउंडिंग निकटतम int8 मान चुनती है, इसलिए एरर ज़्यादा से ज़्यादा आधा स्टेप होती है। कट ऑफ़ (ट्रंकेट) करने से मान हमेशा शून्य की ओर चले जाते हैं, इसलिए एरर लगभग एक पूरा स्टेप हो सकती है और एक ही दिशा में बायस्ड हो सकती है। वह बायस कई weights में जुड़ता जाता है और एक्यूरेसी को अधिक नुकसान पहुँचाता है।
Q2आपका quantised मॉडल Python में सटीक है, लेकिन बोर्ड के जवाब अलग हैं। इसका क्या कारण हो सकता है?दिखाएं
हो सकता है कि बोर्ड इनपुट को अलग तरीके से quantise करता हो: एक अलग scale या zero point, या इनपुट को उसी तरह int8 में न बदला गया हो। रनटाइम लेयर्स के बीच activations को भी राउंड करता है, जो Python में केवल-weights वाला टेस्ट नहीं दिखाता है। दोनों में समान इनपुट दें, और कदम दर कदम इनपुट टेन्सर और आउटपुट्स की तुलना करें। कन्वर्टर के अपने टूल्स अक्सर इस तुलना के लिए आपके कंप्यूटर पर quantised मॉडल चला सकते हैं।
अक्सर पूछे जाने वाले सवाल
क्या quantisation से हमेशा एक्यूरेसी कम होती है?
लगभग हमेशा थोड़ी बहुत, कभी-कभी इतनी कम कि आप माप भी नहीं सकते, और कभी-कभी बहुत ज़्यादा। यह मॉडल और डेटा पर निर्भर करता है। इसीलिए आप पहले और बाद में हेल्ड-आउट डेटा पर मापते हैं।
−127 से 127 ही क्यों, −128 से 127 क्यों नहीं?
सिमेट्रिक स्कीम्स अक्सर −127 से 127 का उपयोग करती हैं ताकि पॉज़िटिव और नेगेटिव मानों की रेंज समान हो और शून्य पूरी तरह से शून्य रहे। कुछ टूल्स विशेष मामलों के लिए −128 का उपयोग करते हैं। चाहे जो भी हो, आपका रनटाइम जो अपेक्षा करता है उसका पालन करें।
क्या मैं int8 से भी छोटा कर सकता हूँ?
कुछ रिसर्च और कुछ टूल्स प्रति weight 4-बिट या उससे भी कम बिट्स का उपयोग करते हैं, और कुछ चिप्स विशेष फ़ॉर्मेट्स का समर्थन करते हैं। यह अधिक जगह बचाता है लेकिन अधिक एक्यूरेसी खो देता है और microcontrollers पर इसका समर्थन कम है। int8 आज का सामान्य और अच्छी तरह से समर्थित विकल्प है; अपने टूल के दस्तावेज़ देखें।
quantisation के अलावा मॉडल को और क्या छोटा करता है?
कम या छोटी लेयर्स का उपयोग करना, कम इनपुट फ़ीचर्स, प्रूनिंग (कम महत्व वाले weights को हटाना) और डिस्टिलेशन (एक बड़े मॉडल की नकल करने के लिए एक छोटे मॉडल को ट्रेन करना)। TinyML के लिए, एक छोटे डिज़ाइन से शुरुआत करना आमतौर पर सबसे बड़ा फ़ायदा होता है।
पाठ का टेस्ट
5 सवाल। पास होने और इस पाठ को पूरा करने के लिए 3 सही होने चाहिए (60%)।