راهنمای جامع برای درک عملکرد در OpenVINO
مقدمه ای بر OpenVINO راهنمای جامع برای درک عملکرد OpenVINO که مخفف Open Visual Inference و Neural Network Optimization است. این مجموعه ابزاری است که توسط اینتل برای تسهیل استنتاج سریعتر مدل های یادگیری عمیق ارائه شده است. این به توسعه دهندگان کمک می کند تا برنامه های بینایی کامپیوتری مقرون به صرفه و قوی ایجاد کنند. این استنتاج یادگیری عمیق را در لبه امکان پذیر می کند و از اجرای ناهمگن در شتاب دهنده های بینایی رایانه – CPU، GPU، Intel® Movidius™ Neural Compute Stick و FPGA پشتیبانی می کند.
از تعداد زیادی مدل یادگیری عمیق خارج از جعبه پشتیبانی می کند. برای آشنایی بیشتر با مدل می توانید این لینک را بررسی کنید. پیش نیازها اگر می خواهید نمونه کد ارائه شده در انتهای این مقاله را اجرا کنید، مطمئن شوید که جعبه ابزار OpenVINO را به درستی دانلود و پیکربندی کرده اید.
روند اجرا به شرح زیر است –
ما یک مدل از پیش آموزش دیده را به Model Optimizer تغذیه می کنیم. این مدل را بهینه می کند و آن را به نمایش میانی آن (فایل xml و .bin) تبدیل می کند.Inference Engine به اجرای صحیح مدل در دستگاه های مختلف کمک می کند. کتابخانه های مورد نیاز برای اجرای صحیح کد در پلتفرم های مختلف را مدیریت می کند.دو جزء اصلی جعبه ابزار OpenVINO عبارتند از Model Optimizer و Inference Engine. بنابراین، ما به جزئیات آنها خواهیم پرداخت تا نقش و عملکرد داخلی آنها را بهتر درک کنیم.
بهینه ساز مدل
بهینه ساز مدل یک ابزار خط فرمان چند پلتفرمی است که انتقال بین محیط آموزشی و استقرار را تسهیل می کند. این مدلهای یادگیری عمیق را برای اجرای بهینه در دستگاههای هدف نقطه پایانی تنظیم میکند.
کار کردن
Model Optimizer یک مدل را در حافظه بارگذاری می کند، آن را می خواند، نمایش داخلی مدل را ایجاد می کند، آن را بهینه می کند و نمایش میانی را تولید می کند. نمایش متوسط تنهاقالبی است که Inference Engine می پذیرد و می فهمد.Model Optimizer مدل ها را استنتاج نمی کند. این یک ابزار آفلاین است که قبل از انجام استنتاج اجرا می شود.
Model Optimizer دو هدف اصلی دارد:
یک نمایندگی متوسط معتبر تولید کنید. مسئولیت اصلی Model Optimizer تولید دو فایل (xml. و .bin) است که نمایش میانی را تشکیل می دهند.
یک نمایندگی میانی بهینه تولید کنید. مدل های از قبل آموزش دیده حاوی لایه هایی هستند که برای آموزش مهم هستند، مانند لایه Dropout. این لایه ها در هنگام استنتاج بی فایده هستندو ممکن است. زمان استنتاج را افزایش دهند. در بسیاری از موارد، این لایه ها را می توان به طور خودکار از نمایش میانی حاصل حذف کرد. با این حال، اگر گروهی از لایه ها را بتوان به عنوان یک عملیات ریاضی و بنابراین به عنوان یک لایه نشان داد، مدل Optimizer چنین الگوهایی را تشخیص می دهد و این لایه ها را تنها با یک لایه جایگزین می کند. نتیجه یک نمایش متوسط است که لایه های کمتری نسبت به مدل اصلی دارد. این باعث کاهش زمان استنتاج می شود.
عملیات تغییر شکل –
Model Optimizer به ما اجازه می دهد تا تصاویر ورودی خود را تغییر شکل دهیم. فرض کنید مدل خود را با اندازه تصویر 256 * 256 آموزش داده اید و می خواهید اندازه تصویر را به 100 * 100 تبدیل کنید، سپس می توانید به سادگی اندازه تصویر جدید را به عنوان یک آرگومان خط فرمان ارسال کنید و Model Optimizer این کار را انجام می دهد.
دسته بندی –
ما می توانیم اندازه دسته ای مدل خود را در زمان استنتاج تغییر دهیم. ما فقط می توانیم مقدار Batch size را به عنوان آرگومان خط فرمان ارسال کنیم.همچنین میتوانیم .اندازه تصویر خود را مانند این [4،3،100،100] منتقل کنیم. در اینجا مشخص می کنیم که به 4 تصویر با ابعاد 100*100*3 نیاز داریم، یعنی تصاویر RGB دارای 3 کانال و دارایعرض و ارتفاع 100. نکته مهمی که در اینجا باید به آن توجه داشت .این است که در حال حاضر استنتاج کندتر خواهد بود زیرا ما از یک دسته استفاده می کنیم. 4 تصویر برای استنتاج به جای استفاده از یک تصویر واحد.
اصلاح ساختار شبکه –
ما می توانیم ساختار شبکه خود را تغییر دهیم، یعنی می توانیم لایه ها را از بالا یا از پایین حذف کنیم. میتوانیم یک لایه خاص را از جایی که میخواهیم اجرا شروع شود یا جایی که میخواهیم اجرا به پایان برسد را مشخص کنیم.
استانداردسازی و مقیاس بندی –
ما می توانیم عملیاتی مانند نرمال سازی (تفریق میانگین) و استانداردسازی را روی داده های ورودی خود انجام دهیم.
کوانتیزاسیون
این یک مرحله مهم در فرآیند بهینه سازی است. اکثر مدل های یادگیری عمیق معمولا از فرمت FP32 برای داده های ورودی خود استفاده می کنند. فرمت FP32 حافظه زیادی مصرف می کندو در نتیجه زمان استنتاج را افزایش می دهد. بنابراین، به طور شهودی ممکن است فکر کنیم که می توانیم زمان استنتاج خود را با تغییر قالب داده های ورودی خود کاهش دهیم. فرمتهای مختلف دیگری مانند FP16 و INT8 وجود دارد که میتوانیم از آنها استفاده کنیم، اما در حین اجرای کوانتیزه کردن باید مراقب باشیم زیرا میتواند منجر به کاهش دقت شود.استفاده از قالب INT8 می تواند به ما در کاهش قابل توجه زمان استنتاج کمک کند، اما در حال حاضر، تنها لایه های خاصی با فرمت INT8 سازگار هستند: Convolution، ReLU، Pooling، Eltwise و Concat. بنابراین، ما اساساً اجرای ترکیبی را انجام می دهیم که در آن برخی از لایه ها از فرمت FP32 استفاده می کنند در حالی که برخی از لایه ها از فرمت INT8 استفاده می کنند. یک لایه جداگانه وجود دارد.که این تبدیل ها را مدیریت می کند. یعنی ما مجبور نیستیم به صراحت نوع تبدیل از یک لایه به لایه دیگر را مشخص کنیم.
لایه کالیبره تمام این تبدیل های پیچیده را مدیریت می کند.
روش کار به شرح زیر است –
در ابتدا باید یک مقدار آستانه تعریف کنیم. این افت دقت را تعیین می کند که مایل به پذیرش آن هستیم.
سپس لایه Calibrate زیر مجموعه ای از داده ها را می گیرد و سعی می کند فرمت داده لایه ها را از FP32 به INT8 یا FP16 تبدیل کند.
سپس افت دقت را بررسی می کند و اگر کمتر از مقدار آستانه تعیین شده باشد، تبدیل انجام می شود.
موتور استنتاج
پس از استفاده از Model Optimizer برای ایجاد یک نمایش میانی (IR)، از Inference Engine برای استنتاج داده های ورودی استفاده می کنیم.Inference Engine یک کتابخانه C++ با مجموعه ای از کلاس های C++ برای استنتاج داده های ورودی (تصاویر) و گرفتن نتیجه است. کتابخانه ++C یک API برای خواندن بازنمایی میانی،تنظیم فرمت های ورودی و خروجی و اجرای مدل بر روی دستگاه ها ارائه می دهد.اجرای ناهمگن مدل به دلیل موتور استنتاج امکان پذیر است. از پلاگین های مختلفی برای دستگاه های مختلف استفاده می کند.
پلاگین ناهمگن
ما می توانیم یک برنامه را روی چندین دستگاه اجرا کنیم. ما فقط باید به عنوان یک آرگومان خط فرمان در دستگاه هدف ارسال کنیم و موتور استنتاج بقیه کارها را انجام می دهد، یعنی می توانیم همان قطعه کد را روی یک CPU، GPU، VPU یا هر دستگاه دیگری که با جعبه ابزار OpenVINO سازگار است اجرا کنیم. ما همچنین میتوانیم بخشهایی از برنامه خود را در دستگاههای مختلف اجرا کنیم، یعنی ممکن است بخشی از برنامه ما روی CPU اجرا شود و قسمتهای دیگر ممکن است روی یک FPGA یا یک GPU اجرا شود. اگر HETERO: FPGA، CPU را مشخص کنیم، کد اساساً روی یک FPGA اجرا میشود، اما اگر فرض کنیم با عملیات خاصی مواجه شود که با FPGA سازگار نیست، به CPU سوئیچ میکند.
همچنین میتوانیم لایههای خاصی را روی یک دستگاه خاص اجرا کنیم. فرض کنید می خواهید لایه Convolution را فقط روی GPU خود اجرا کنید، سپس می توانید آن را به صراحت مشخص کنید.نکته مهمی که در اینجا باید به آن توجه کرد این است که هنگام تعیین سخت افزارهای مختلف باید مراقب قالب داده باشیم. همه دستگاه ها با همه انواع داده کار نمی کنند. مثال – Neural Compute Stick NCS2 که با تراشه Movidius عرضه می شود، از فرمت INT8 پشتیبانی نمی کند. برای دریافت اطلاعات کامل در مورد دستگاه های پشتیبانی شده و فرمت های مربوطه می توانید این پیوند را بررسی کنید.
نمونه کد
نمونه کد اصلی ارائه شده توسط اینتل را می توانید در اینجا بیابید.
من نمونه کد را تغییر دادم تا ساده تر شود و نسخه من را می توانید در اینجا پیدا کنید.
من فقط در اینجا کد خاص OpenVINO را توضیح خواهم داد.
# Initialize the class infer_network = Network() # Load the network to IE plugin to get shape of input layer n, c, h, w = infer_network.load_model(args.model, args.device, 1, 1, 2, args.cpu_extension)[1]
کلاس Network را مقداردهی اولیه می کنیم و مدل را با استفاده از تابع load_model بارگذاری می کنیم.
تابع load_model افزونه را به همراه شکل ورودی برمی گرداند.
ما فقط به شکل ورودی نیاز داریم، به همین دلیل است که [1] را بعد از فراخوانی تابع مشخص کردهایم.
infer_network.exec_net(next_request_id, in_frame)
تابع exec_net یک درخواست استنتاج ناهمزمان را شروع می کند.
باید شناسه درخواست و فریم ورودی را پاس کنیم.
res = infer_network.get_output(cur_request_id) for obj in res[0][0]: if obj[2] > args.prob_threshold: xmin = int(obj[3] * initial_w) ymin = int(obj[4] * initial_h) xmax = int(obj[5] * initial_w) ymax = int(obj[6] * initial_h) class_id = int(obj[1])
این مهمترین قسمت کد است.
تابع get_output نتیجه مدل را به ما می دهد.
هر تشخیص در قالب زیر نشان داده شده است –
[image_id,class_label,confidence,x_min,y_min,x_max,y_max]
در اینجا، مختصات باندینگ باکس و شناسه کلاس را استخراج کرده ایم.
دیدگاهتان را بنویسید