गहन शिक्षण मॉडल का प्रशिक्षण देते समय मिनी-बैच मेमोरी प्रभाव की गणना कैसे करें?


17

मैं GPU की आवश्यकता की मात्रा की गणना करने की कोशिश कर रहा हूं, जो मेरे मॉडल को कारपहाटी के इस नोट्स के आधार पर प्रशिक्षित करने के लिए है: http://cs231n.github.io/convolutional-networks/#computational-considerations

मेरे नेटवर्क में 532,752 सक्रियण और 19,072,984 पैरामीटर (वज़न और पूर्वाग्रह) हैं। ये सभी 32 बिट फ्लोट मान हैं, इसलिए प्रत्येक मेमोरी में 4 बाइट्स लेता है।

मेरी इनपुट छवि 180x50x1 (चौड़ाई x ऊँचाई x गहराई) = 9,000 फ़्लोट 32 मान है। मैं छवि वृद्धि का उपयोग नहीं करता हूं, इसलिए मुझे लगता है कि विविध मेमोरी केवल मिनी-बैच आकार से संबंधित होगी। मैं 128 छवियों के एक मिनी-बैच आकार का उपयोग कर रहा हूं।

फ़ोरम की सिफारिश के आधार पर, मुझे निम्नलिखित मेमोरी साइज़ मिलते हैं:

सक्रियण: 532,752 * 4 / (1024 ^ 2) = 2.03 एमबी

पैरामीटर: 19,072,984 * 4 / (1024 ^ 2) * 3 = 218.27 एमबी

विविध: 128 * 9,000 * 4 / (1024 ^ 2) = 4.39 एमबी

तो इस नेटवर्क को प्रशिक्षित करने की कुल मेमोरी 224,69 एमबी होगी

मैं TensorFlow का उपयोग कर रहा हूं और मुझे लगता है कि मुझे कुछ याद आ रहा है। मैंने अभी तक प्रशिक्षण नहीं चलाया है, लेकिन मुझे पूरा यकीन है (पिछले अनुभवों के आधार पर) कि मैं उपयोग की गई मेमोरी की गणना मेरे द्वारा की गई गणना से बहुत अधिक होगी।

यदि मिनी-बैच में प्रत्येक छवि के लिए, TensorFlow अपने ग्रेडिएंट रखता है तो यह बाद में उन्हें एक वेट / बायेस अपडेट अपडेट के लिए सामान्य कर सकता है, तो मुझे लगता है कि मेमोरी को प्रत्येक छवि के लिए 532,752 * 128 मान (ग्रेडिएंट) को ध्यान में रखना चाहिए। मिनी बैच)। अगर ऐसा है, तो मुझे इस मॉडल को 128 छवियों / मिनी-बैच के साथ प्रशिक्षित करने के लिए अधिक 260.13 एमबी की आवश्यकता होगी।

क्या आप मेरे गहन शिक्षण मॉडल के प्रशिक्षण के लिए स्मृति के विचारों को समझने में मेरी मदद कर सकते हैं? क्या उपरोक्त विचार सही हैं?


कृपया अपने प्रश्न का मेरा (प्रस्तावित) उत्तर यहाँ देखें
एडम हेन्ड्री

जवाबों:


5

मुझे लगता है कि आप सही रास्ते पर हैं।

हां, आपको बैकप्रोपेगेशन के लिए सक्रियण और मापदंडों के डेरिवेटिव को संग्रहीत करने की आवश्यकता होगी।

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

तो सब के सब, आप एक आगे पास के लिए स्मृति आवश्यकताओं की गणना करने लगते हैं। लेडी करपैथी का उल्लेख है कि आगे की पास की मेमोरी को बैकवर्ड पास 3x तक ले सकता है, इसलिए यह हो सकता है कि आप ऐसा अंतर देखें (वीजीनेट के लिए एक उदाहरण देखने के लिए वेबसाइट पर 'केस स्टडीज पर स्क्रॉल करें')।


5

@StatsSorceress TL; DR:

मैं इस गतिविधि से गुजर रहा हूँ कि क्या मैं स्वयं आवश्यक मेमोरी की गणना कर सकता हूँ:

सक्रियण: 532,752 * 2 * 4 / (1024 ^ 2) = 4.06 एमबी

पैरामीटर: 19,072,984 * 4 / (1024 ^ 2) * 3 = 218.27 एमबी

विविध: 128 * 9,000 * 4 / (1024 ^ 2) = 4.39 एमबी

कुल मेमोरी: (4.06 * 128 ) + 218.27 + 4.39 = 742.34 एमबी

( अगर कोई गलत है तो कृपया मुझे इस पर सही करें। FYI करें, आप पहले से ही कई गुणा गुणा कर चुके हैं, इसीलिए मैंने इसे 128 से ऊपर नहीं बढ़ाया है )


मैं आपको इस लेख और संबंधित वीडियो की ओर इशारा करता हूं । उन्होंने मुझे यह समझने में मदद की कि क्या बहुत बेहतर चल रहा है।

नोट: पूर्वानुमानों के लिए नेटवर्क का उपयोग करने के लिए आवश्यक मेमोरी दो कारणों से प्रशिक्षण के लिए आवश्यक से बहुत कम है:

  • भविष्यवाणी करते समय, हम केवल नेटवर्क के माध्यम से एक छवि आगे भेजते हैं और पिछड़े नहीं (इसलिए हम मेमोरी एक्स 3 को गुणा नहीं करते हैं; नीचे देखें;
  • प्रति चित्र एक भविष्यवाणी है (इसलिए हमें एक छवि के लिए आवश्यक आकार को एक बैच आकार से गुणा करने की आवश्यकता नहीं है क्योंकि हम भविष्यवाणी में बैचों का उपयोग नहीं करते हैं)।

प्रक्रिया (ट्रेन की मेमोरी)

  1. एक छवि पर प्रशिक्षित करने के लिए आवश्यक मेमोरी की गणना करें
  2. अपने बैच में छवियों की संख्या से इस संख्या को गुणा करें

( रिमेम्बर: मिनी-बैचिंग का कहना है कि हम अपने डेटा का सबसेट लेते हैं, सब्मिट में हर इमेज के लिए ग्रेडिएंट्स और एरर की गणना करते हैं, फिर इनको एवरेज करते हैं और एवरेज की दिशा में आगे बढ़ते हैं। कॉननेट्स, वेट और बायसेज के लिए साझा किया जाता है, लेकिन सक्रियणों की संख्या को बैच में छवियों की संख्या से गुणा किया जाता है। )।

चरण 1: 1 छवि के लिए मेमोरी

एक छवि को प्रशिक्षित करने के लिए, आपको स्मृति को आरक्षित करना होगा:

  • मॉडल पैरामीटर:

    वजन और पूर्वाग्रहों प्रत्येक परत, उनके पर ढ़ाल , और उनके गति चर (एडम, Adagrad, RMSProp, आदि, अनुकूलक इस्तेमाल कर रहे हैं तो)

    इसके लिए मेमोरी को अनुमानित करने के लिए, वेट और बायसेस को स्टोर करने के लिए आवश्यक मेमोरी की गणना करें और 3 से गुणा करें (अर्थात "3 से" क्योंकि हम कह रहे हैं कि वेट और बायसेस को स्टोर करने के लिए आवश्यक मेमोरी की मात्रा (लगभग) के बराबर है कि गति के लिए आवश्यक है और गति के लिए चर)

    समीकरण:

    convolutions:

    वज़न (n) = गहराई (n) * (कर्नेल_प्रवेशन * कर्नेल_हाइट) * गहराई (n-1)

    biases (n) = गहराई (n)

    पूरी तरह से जुड़े (घने) परतें:

    भार (n) = आउटपुट (n) * इनपुट (n)

    biases (n) = आउटपुट (n)

जहाँ n वर्तमान परत है और n-1 पिछली परत है, और आउटपुट एफसी परत से आउटपुट की संख्या है और इनपुट एफसी परत के इनपुट की संख्या है (यदि पिछली परत पूरी तरह से कनेक्टेड परत नहीं है, निविष्टियों की संख्या उस परत के आकार के बराबर होती है जो चपटी होती है)।

नोट: अकेले वज़न और पूर्वाग्रह के लिए स्मृति, प्लस एक छवि के लिए सक्रियण के लिए मेमोरी (नीचे देखें), मेमोरी की कुल राशि है जो आपको भविष्यवाणियों के लिए चाहिए (दृढ़ संकल्प और कुछ अन्य चीजों के लिए स्मृति के लिए कुछ ओवरहेड को छोड़कर)।

  • सक्रियण (ये कैफ़ में "ब्लब्स" हैं):

(मैं यहाँ शब्दों का प्रयोग कर रहा हूँ, मेरे साथ सहन करो)

एक कनवल्शन लेयर में प्रत्येक कन्वेक्शन " इमेज में पिक्सल्स की संख्या " उत्पन्न करता है (यानी आप एक कॉनवोल्यूशन के माध्यम से एक इमेज पास करते हैं, आपको " एम " एक्टीवेशन से मिलकर एक सिंगल फ़ीचर मैप मिलता है , जहाँ " एम " आपकी पिक्सल्स की संख्या है) छवि / इनपुट)।

पूरी तरह से जुड़ी हुई परतों के लिए, आपके द्वारा उत्पादित सक्रियणों की संख्या आपके आउटपुट के आकार के बराबर होती है।

convolutions:

सक्रियण (n) = image_width * image_height * image_num_channels

पूरी तरह से जुड़े (घने) परतें:

सक्रियण (n) = आउटपुट (n)

ध्यान दें कि नेटवर्क की शुरुआत में आपका इनपुट वास्तव में केवल एक छवि है। दृढ़ संकल्प के बाद, यह कुछ और (फीचर मैप्स) में बदल जाता है। तो वास्तव में "input_width", "image_height", और "image_num_channels" को "input_width", "input_height", और "layer_depth" से और अधिक सटीक होने के लिए बदलें। (छवियों के संदर्भ में इस अवधारणा के बारे में सोचना मेरे लिए आसान है।)

चूँकि हमें प्रत्येक लेयर (बैकवर्ड पास में उपयोग की जाने वाली एक्टिविटीज) के लिए एरर को स्टोर करने की आवश्यकता होती है, इसलिए हमें अपने स्टोरेज स्पेस में जगह बनाने के लिए कुल एक्टिविटीज़ की संख्या को 2 से गुणा करना होगा। बैच में छवियों की संख्या के साथ सक्रियण की संख्या बढ़ जाती है, इसलिए आप इस संख्या को बैच आकार से गुणा करते हैं।

चरण 2: ट्रेन बैच को मेमोरी

भार और पूर्वाग्रहों की संख्या (3 बार) और सक्रियणों की संख्या (2 बार बैच आकार)। इसे 4 से गुणा करें, और आपको बैच को प्रशिक्षित करने के लिए आवश्यक बाइट्स की संख्या मिलती है। GB में उत्तर पाने के लिए आप 1024 ^ 2 से भाग कर सकते हैं।


आप क्यों कहते हैं "हम भविष्यवाणी में चमगादड़ों का उपयोग नहीं करते हैं"? यदि उपयोगकर्ता को बड़ी संख्या में छवियों पर भविष्यवाणियां करने की आवश्यकता होती है, तो यह पूर्वानुमानों में बैचों का उपयोग करने के लिए समझ में आता है।
user3731622

1

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

आप अपने प्रोग्राम के उस हिस्से को चला सकते हैं जिसे आप एक अलग उप-प्रक्रिया में पॉपेन का उपयोग करके मॉनिटर करना चाहते हैं और यह पीआईडी ​​का उपयोग करके मेमोरी और सीपीयू उपयोग की निगरानी करना चाहते हैं।

psutil मुझे ऐसे काम के लिए अच्छा लगता है। हालांकि कई अन्य हैं।

मुझे उम्मीद है कि इससे सहायता मिलेगी।


3
उत्तर के लिए धन्यवाद, @ अनवर। मैं अनुभवजन्य अवलोकन के बजाय एक विश्लेषणात्मक गणना की तलाश कर रहा हूं।
बारबेलो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.