TensorFlow 1.8 - Fixed Point Quantization

निश्चित बिंदु परिमाणीकरण




tensorflow

निश्चित बिंदु परिमाणीकरण

परिमाणीकरण तकनीक अधिक कॉम्पैक्ट प्रारूपों में संख्याओं को संग्रहीत और गणना करती है। TensorFlow Lite एक 8-बिट फिक्स्ड पॉइंट प्रतिनिधित्व का उपयोग करने वाले परिमाणीकरण को जोड़ता है।

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

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

परिमाणीकरण लाभ

8-बिट गणना का उपयोग करने से आपके मॉडल तेजी से चलने और कम शक्ति का उपयोग करने में मदद करते हैं। यह मोबाइल उपकरणों और एम्बेडेड अनुप्रयोगों के लिए विशेष रूप से महत्वपूर्ण है जो फ्लोटिंग पॉइंट कोड को कुशलता से नहीं चला सकते हैं, उदाहरण के लिए, इंटरनेट ऑफ थिंग्स (IoT) और रोबोटिक्स डिवाइस। इस समर्थन को अधिक बैकेंड में विस्तारित करने और कम सटीक नेटवर्क के अनुसंधान के लिए अतिरिक्त अवसर हैं।

छोटे फ़ाइल आकार

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

संख्यात्मक मूल्यों की बड़ी परतों में वजन होता है। प्रत्येक परत के लिए, वज़न सामान्य रूप से एक सीमा के भीतर वितरित किया जाता है। मात्रा का ठहराव प्रत्येक परत के लिए न्यूनतम और अधिकतम वजन का भंडारण करके फ़ाइल के आकार को छोटा कर सकता है, फिर प्रत्येक वजन के फ्लोट मूल्य को सीमा के भीतर 256 के रैखिक सेट में निकटतम वास्तविक संख्या का प्रतिनिधित्व करते हुए 8-बिट पूर्णांक में संपीड़ित करता है।

तेज आक्रमण

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

मेमोरी क्षमता

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

आमतौर पर, SIMD संचालन उपलब्ध होते हैं जो प्रति घड़ी चक्र में अधिक संचालन चलाते हैं। कुछ मामलों में, एक डीएसपी चिप उपलब्ध है जो 8-बिट गणना को तेज करता है जिसके परिणामस्वरूप बड़े पैमाने पर स्पीडअप होता है।

निश्चित बिंदु परिमाणीकरण तकनीक

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

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

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

TensorFlow के साथ परिमाणीकरण प्रशिक्षण

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

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

# Build forward pass of model.
loss = tf.losses.get_total_loss()

# Call the training rewrite which rewrites the graph in-place with
# FakeQuantization nodes and folds batchnorm for training. It is
# often needed to fine tune a floating point model for quantization
# with this training tool. When training from scratch, quant_delay
# can be used to activate quantization after training to converge
# with the float graph, effectively fine-tuning the model.
tf.contrib.quantize.create_training_graph(quant_delay=2000000)

# Call backward pass optimizer as usual.
optimizer = tf.train.GradientDescentOptimizer(learning_rate)
optimizer.minimize(loss)

पुनर्विकसित eval ग्राफ गैर-तुच्छ रूप से प्रशिक्षण ग्राफ से अलग है क्योंकि परिमाणीकरण ऑप्स बैच सामान्यीकरण चरण को प्रभावित करता है। इस वजह से, हमने eval ग्राफ के लिए एक अलग पुनर्लेखन जोड़ा है:

# Build eval model
logits = tf.nn.softmax_cross_entropy_with_logits(...)

# Call the eval rewrite which rewrites the graph in-place with
# FakeQuantization nodes and fold batchnorm for eval.
tf.contrib.quantize.create_eval_graph()

# Save the checkpoint and eval graph proto to disk for freezing
# and providing to TFLite.
with open(eval_graph_file, ‘w’) as f:
  f.write(str(g.as_graph_def()))
saver = tf.train.Saver()
saver.save(sess, checkpoint_name)

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

पूरी तरह से परिमाणित मॉडल बनाना

पहले प्रदर्शन के बाद फिर से लिखना eval ग्राफ केवल परिमाणीकरण अनुकरण करता है । एक प्रशिक्षित परिमाणीकरण मॉडल से वास्तविक निश्चित बिंदु गणना उत्पन्न करने के लिए, इसे एक निश्चित बिंदु कर्नेल में परिवर्तित करें। Tensorflow Lite इस रूपांतरण को create_eval_graph के ग्राफ़ के रूपांतरण का समर्थन करता है।

सबसे पहले, एक जमे हुए ग्राफ बनाएं जो TensorFlow Lite टूलकिन के लिए इनपुट होगा:

bazel build tensorflow/python/tools:freeze_graph && \
  bazel-bin/tensorflow/python/tools/freeze_graph \
  --input_graph=eval_graph_def.pb \
  --input_checkpoint=checkpoint \
  --output_graph=frozen_eval_graph.pb --output_node_names=outputs

एक पूरी तरह से निर्धारित TensorFLow लाइट मॉडल प्राप्त करने के लिए TensorFlow Lite ऑप्टिमाइज़िंग कन्वर्टर (TOCO) को इसे प्रदान करें:

bazel build tensorflow/contrib/lite/toco:toco && \
  ./bazel-bin/third_party/tensorflow/contrib/lite/toco/toco \
  --input_file=frozen_eval_graph.pb \
  --output_file=tflite_model.tflite \
  --input_format=TENSORFLOW_GRAPHDEF --output_format=TFLITE \
  --inference_type=QUANTIZED_UINT8 \
  --input_shape="1,224, 224,3" \
  --input_array=input \
  --output_array=outputs \
  --std_value=127.5 --mean_value=127.5

tf.contrib.quantize और TensorFlow Lite के लिए दस्तावेज़ देखें।

परिमाणित सटीकता

फिक्स्ड पॉइंट MobileNet मॉडल 8-बिट वज़न और सक्रियण के साथ जारी किए जाते हैं। रीराइटर्स का उपयोग करते हुए, ये मॉडल तालिका 1 में सूचीबद्ध टॉप -1 सटीकता को प्राप्त करते हैं। तुलना के लिए, अस्थायी बिंदु एक ही मॉडल के लिए सूचीबद्ध हैं। इन मॉडलों को जेनरेट करने के लिए इस्तेमाल किया जाने वाला कोड, प्रीटेन्डेड मोबिलनेट_v1 मॉडल के सभी लिंक के साथ उपलब्ध है

छवि का आकार गहराई शीर्ष -1 सटीकता:
तैरनेवाला स्थल
शीर्ष -1 सटीकता:
निश्चित बिंदु: 8 बिट वज़न और सक्रियण
128 0.25 0.415 0.399
128 0.5 0.563 0.549
128 0.75 0.621 0.598
128 1 0.652 0.64
160 0.25 0.455 0.435
160 0.5 0.591 0.577
160 0.75 0.653 0.639
160 1 0.68 0.673
192 0.25 0.477 0.458
192 0.5 0.617 0.604
192 0.75 0.672 0.662
192 1 0.7 0.69
224 0.25 0.498 0.482
224 0.5 0.633 0.622
224 0.75 0.684 0.679
224 1 0.709 0.697
तालिका 1 : मोबाइलनेट टॉप -1 सटीकता इमेनेटेट वैलिडेशन डेटासेट पर।

परिमाणित दसियों के लिए प्रतिनिधित्व

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

यह दो फ़्लोट्स के साथ दर्शाया गया है जो न्यूनतम और उच्चतम मात्रा वाले मूल्य के अनुरूप समग्र न्यूनतम और अधिकतम मूल्यों को संग्रहीत करता है। परिमाणित सरणी में प्रत्येक प्रविष्टि उस श्रेणी में एक फ्लोट मान का प्रतिनिधित्व करती है, जिसे न्यूनतम और अधिकतम के बीच रैखिक रूप से वितरित किया जाता है। उदाहरण के लिए, न्यूनतम -10.0 और अधिकतम 30.0f और एक 8-बिट सरणी के साथ, परिमाणित मान निम्न का प्रतिनिधित्व करते हैं:

मात्रा निर्धारित फ्लोट
0 -10.0
255 30.0
128 10.0
तालिका 2 : उदाहरण मात्रात्मक मूल्य सीमा

इस प्रतिनिधित्व प्रारूप के लाभ हैं:

  • यह कुशलता से सीमाओं के एक मनमाने परिमाण का प्रतिनिधित्व करता है।
  • मूल्यों को सममित नहीं होना चाहिए।
  • प्रारूप हस्ताक्षरित और अहस्ताक्षरित दोनों मानों का प्रतिनिधित्व करता है।
  • रैखिक प्रसार गुणा को सीधा बनाता है।

वैकल्पिक तकनीकें गैर-रेखीय रूप से फ्लोट मानों को प्रतिनिधित्व में वितरित करके कम बिट गहराई का उपयोग करती हैं, लेकिन वर्तमान में गणना समय के संदर्भ में अधिक महंगी हैं। (हान एट अल, 2016 ।)

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