چگونه یک مدل برای شناسایی مکان‌ها آموزش دادیم؟

نویسندگان ‌: محیا مهدیان و محمد حسن ستاریان

مقدمه

deeplearning

در هر مسئله دسته‌بندی (Classification)، پیاده‌سازی یک مدل مناسب -از جهت صحت پیش‌بینی- به مولفه‌های متفاوتی وابسته است؛ داشتن ورودی‌های -با ویژگی‌های- گوناگون و به تعداد زیاد یکی از مولفه‌های مهم برای آموزش مدلی که دقیق (Accurate) بوده و قادر به عمومیت بخشی (Generalization) به دانش خود و راستی آزمایی آن در محیط واقعی است می‌باشد. با این حال جمع آوری داده زیاد کاری سخت و نیازمند زمان و هزینه زیاد، بسته به شرایط و نوع داده مورد نیاز خواهد بود. در این شرایط و با توجه به اینکه کار‌های پیشین زیادی انجام شده اند، استفاده از روش‌های یادگیری انتقال (Transfer learning)، درواقع استفاده از یک مدل از پیش آموزش دیده و استفاده از آن به عنوان استخراج کننده ویژگی (Feature Extractor) یا به عنوان شبکه Fine Tuning کمک بسیار زیادی در ساخت مدلی دقیق و مناسب خواهد داشت. همچنین استفاده از روش‌های افزایش داده (Data augmentation) باعث افزایش چشم‌گیر داده شده و در آموزش بهتر مدل موثر خواهد بود؛ با این‌حال در استفاده از این روش باید توجه داشت از روش‌هایی برای تغییر عکس استفاده کرد که عکس خروجی خارج از فضای حالت مسئله نبوده و در شرایط واقعی مسئله وجود داشته باشد. به علاوه در جمع‌آوری داده باید داده‌های جمع آوری شده بررسی و در صورت نیاز پاکسازی‌هایی نیز انجام شود، تا داده‌های نامناسب، نامربوط و بی‌تاثیر حذف شوند اما از عمومیت داده‌ها کم نشده و داده‌های مختلفی در شرایط مختلف آزمون مسئله وجود داشته باشد؛ چرا که هرچه داده‌ها متفاوت‌تر باشند مدل قابلیت عمومیت بخشی بیشتری خواهد داشت. استفاده از پارامترهای (Hyperparameter)‌ مناسب در آموزش مدل، انتخاب دقیق و بسته به شرایط -و داده‌- پارامترها نیز از اهمیت زیادی برخوردار است و شاید نیاز باشد تغییر دقت مدل با تغییر این پارامترها بررسی شود که در این‌صورت نیاز است مدل چندین دفعه آموزش داده شود.

مراحل پیاده‌سازی مدل

هدف ما آموزش مدلی بود تا بتواند مکان‌های دانشگاه را تشخیص بدهد؛ برای پیاده‌سازی مدل خود از فریم‌ورک کراس (Keras) و زبان پایتون استفاده کردیم. از آنجایی که تعداد کلاس‌ها کم بوده و امکان جمع‌آوری داده زیادی که بتواند مدل را خوب آموزش بدهد نبود، مدلی برای استفاده به عنوان مدل پایه (Base Model)‌ برای Fine Tuning انتخاب شد. سپس داده‌های مورد نیاز جمع‌آوری شده، تمیز شده و آماده آموزش شدند. مدل روی گوگل کولب (Google Colab) به همراه استفاده از روش‌های افزایش داده آموزش داده شده و ذخیره شد. برای استفاده از مدل برنامه‌ای برای اجرای آن روی سرور و گرفتن خروجی با میکروفریم‌ورک فلسک نوشته شده و اپلیکیشن اندرویدی نیز برای گرفتن عکس و پیش‌بینی آن در لحظه ساخته شد. هر مرحله به تفضیل توضیح داده خواهد شد:

کد تمامی مراحل در ریپوزتوری «SRU-Place-Recognizer» قابل دسترسی است.

پیدا کردن مدل پایه

VGG16 + places365

همانطور که گفته شد از آنجایی که تعداد کلاس‌ها کم بوده و امکان جمع‌آوری داده زیادی که بتواند مدل را خوب آموزش بدهد نبود، از روش یادگیری انتقال (Transfer learning) استفاده کرده و مدل VGG16 Places365  برای استفاده به عنوان مدل پایه (Base Model)‌ برای Fine Tuning انتخاب شد. این مدل یک شبکه VGG16 است که از پیش با داده‌های دیتاست Places365 که شامل بیش از ۱۰ میلیون عکس در بیش از ۴۰۰ موضوع است آموزش داده شده است؛ پس نه تنها ویژگی‌های اولیه مورد نیاز مسئله در لایه‌های ابتدایی شناسایی شده‌اند بلکه در لایه‌های جلوتر نیز ویژگی‌های بصری عمیقی شناسایی شده اند و مدلی بسیار مناسب برای این مسئله خواهد بود. بنابراین ما از این مدل به عنوان مدل پایه آموزش خود استفاده کردیم به صورتی که تنها لایه‌های کانولوشنی استفاده شده و از میان‌ آن‌ها ۵ لایه آخر را نیز از حالت فریز (freeze) خارج کردیم. در قسمت ساخت مدل بیشتر بخوانید.

جمع‌آوری داده

برای مسئله شش کلاس -شش مکان برای آموزش مدل- در نظر گرفته شد: دانشکده کامپیوتر، دانشکده معماری، سلف، بوفه، ساختمان امور فرهنگی و زمین ورزشی؛ برای جمع‌آوری داده از این مکان‌ها عکس و فیلم از تمامی زوایای ساختمان‌ها گرفته شد. همچنین سعی شد در زمان‌های متفاوتی عکس‌برداری انجام شود تا تصاویر از تنوع قابل قبولی در نور محیط برخوردار باشند. فریم‌های فیلم‌ها بعدا با استفاده از اسکریپت پایتونی زیر جدا شد تا نهایتا در هر کلاس (از هر مکان) ۸۰۰ عکس شامل ۵۰۰ عکس برای آموزش و ۳۰۰ عکس برای تست و مجموعا ۴۸۰۰ عکس تولید شود.

از این اسکریپت به صورت زیر استفاده می‌کنیم (با این فرض که کدهای بالا را در فایلی با نام frameExtractor.py ذخیره کرده اید)؛ پارامتر اول آدرس فایل ویدئو و پارامتر دوم عددی برای شروع نام‌گذاری تصاویر اسکریپت است برای مواقعی که فریم‌های چندین فایل ویدئو را می‌خواهیم جدا کنیم:

آماده‌سازی داده‌ها

از آنجایی که روش جمع‌آوری داده ما، جدا کردن فریم‌ از فیلم‌های گرفته شده بود، تصاویر نامربوط، برای نمونه از محیط اطراف ساختمان و یا تصاویر تار شده نیز در میان عکس‌ها وجود داشت. همچنین تصاویر با کیفیت ۲۱۶۰*۳۸۴۰ گرفته شده بودند و هر کدام تقریبا حجمی بیش از ۳ مگابایت داشتند که برای آموزش شبکه بسیار سنگین بوده و ویژگی‌های (features) بسیار زیادی تولید می‌کردند که برای برنامه خود تا این حد نیاز به جزئیات نداشتیم؛ همچنین عکس‌ها به صورت landscape جدا شده بودند و نیاز به چرخواندن (rotate) داشتند. برای همین، با استفاده از برنامه ImageMagick تصاویر را ۹۰ درجه چرخوانده و سپس همگی را به سایز ۱۹۲*۱۰۸ تبدیل کردیم تا مدل در حین سبک شدن از ویژگی‌های کافی برای آموزش برخوردار باشد.

برای آشنایی با Image Magick و نحوه انجام کار پست «کار با تصاویر توسط ImageMagick» را بخوانید.

در نهایت تصاویر در فولدرهای مربوطه Train و تست و زیرفولدرهایی با اسامی کلاس‌ها قرار داده شدند. این اسم فولدرها بعدا در آموزش مدل و استفاده از دیتا جنریتور (Data Generator) به عنوان اسامی کلاس‌های مدل تعریف می‌شوند. ساختار فولدربندی داده‌ها به صورت زیر شد:

 

ساخت مدل

همانطور که قبلا اشاره شد برای مسئله از Fine Tuning استفاده شد. مدل نهایی تشکیل شده است از لایه‌های کانولوشنی شبکه VGG16 Places365 که به عنوان مدل پایه استفاده شده است و ۵ لایه آخر آن از حالت حالت فریز (freeze) خارج شده و به دو لایه تماما متصل (Fully connected) با ۲۵۶ نود و ۲ نود که به ترتیب از Activation function های Relu (برای شناسایی nonlinearities) و Softmax (برای کد کردن نتیجه در ۶ کلاس) استفاده می‌کنند متصل شدند.

آموزش مدل

google colab

برای آموزش سریعتر مدل و استفاده از GPU که امکان استفاده آن در سیستم خودمان فعلا وجود نداشت، از سرویس گوگل کولب (Google Colab)‌ استفاده کردیم. برای همین منظور فایل‌های لازم برای آموزش مدل به گوگل درایو منتقل شدند -فایل‌ها آپلود شده و از طریق سرویس SavetoDrive به گوگل درایو منتقل شدند- سپس فایل‌ها را در نوت‌بوکی که در گوگل کولب ساخته بودیم وارد کردیم تا مدل را آموزش دهیم.

آموزش نحوه انتقال فایل از گوگل کولب به گوگل درایو را در پست «اتصال مستقیم سرویس کولب (Google Colab) به درایو (Google Drive) از طریق فایل سیستم FUSE» بخوانید.

برای آموزش مدل پس از تعریف ساختار مدل (که در قسمت ساخت مدل توضیح داده شد)، چون که تعداد داده‌ها زیاد بود از دیتا جنریتور (Data Generator) هایی برای خواندن تصاویر از فولدر‌های مربوطه استفاده شده و برای داده‌های آموزش (Train) از روش‌های افزایش داده (Data augmentation) استفاده شد. تصاویر در گروه‌های ۲۰ تایی به شبکه تغذیه (Feed) شده ( batch_size = 20 )، مقادیر steps_per_epoch  و validation_steps  با توجه به تعداد داده‌های Train و Test و تعداد عکس‌های هر گروه ( batch_size) محاسبه شده و با ۱۰ بار تکرار ( epochs = 10 ) شبکه آموزش دید.

بررسی مدل

برای بررسی مدل نمودارهای روند تغییر accuracy و loss در هر epoch چاپ شد تا از نبود over-fitting مطمئن شویم.

accuracy and loss Plots

به علاوه دقت مدل با پیش‌بینی تصاویری از مکان‌های آموزش دیده که مدل قبلا آن عکس‌ها را در دیتاست آموزش یا تست خود نداشته بررسی شد.

تصویر با استفاده از تابع load_img در سایز مورد استفاده مدل خوانده شده و سپس به آرایه تبدیل شده، آرایه تبدیل به آرایه تک بعدی شده و پیش پردازشی رو آن توسط تابع  preprocess_input انجام شده است. این تابع در فایل  places_utils که مدل پایه (VGG16 Places365در اختیار گذاشته موجود است.

ذخیره مدل

در نهایت برای استفاده‌های آتی، مدل را ذخیره کردیم.

 

کد آموزش مدل و نوت‌بوک استفاده شده برای آموزش مدل در گوگل کولب در ریپازیتوری در دسترس اند.

استفاده از مدل در عمل

اسکریپت پیش‌بینی

برای اینکه از مدل استفاده کنیم، برنامه‌ای لازم داشتیم تا تصویر را دریافت کرده و نتیجه پیش‌بینی را برگرداند. برای این منظور اسکریپت زیر نوشته شد:

اسکریپت در ریپازیتوری در دسترس است.

سرور پیش‌بینی

از آنجایی که برنامه بالا باید حتما به همراه عکسی که قرار است پیش‌بینی شود در یک سیستم باشند و درواقع به صورت لوکال اجرا می‌شود، محدود بوده و نیازهای استفاده عملی از مدل را فراهم نمی‌کند. برای همین با استفاده از میکروفریک ورک فلسک برنامه سرور زیر نوشته شد تا بتوان با آپلود عکس، نتیجه پیش‌بینی را دریافت کرد.

برای آشنایی با فلسک و نحوه ایجاد یک برنامه سرور پست «آموزش مقدماتی فلسک (Flask)»‌ را بخوانید.

سه endpoint برای کار با مدل تعریف شدند؛  upload/  برای آپلود عکس (عکس را به صورت base64 دریافت کرده و آن را ذخیره می‌کند)، imagetopredict/  دریافت آخرین عکسی که برای پیش‌بینی فرستاده شده و  predictagain/  برای پیش‌بینی دوباره آخرین عکس آپلود شده. سپس، این برنامه روی سرور دپلوی شده و مدل آماده استفاده عملی شد.

کد برنامه سرور در ریپازیتوری در دسترس است.

برای آشنایی با نحوه دپلوی مدل پست «دپلوی کردن و استفاده از مدل در عمل (Model deployment)» را بخوانید (ما از روش سوم استفاده کردیم).

اپلیکیشن اندروید

حال که سروری داشتیم که با فرستادن عکس می‌توانستیم نتیجه پیش‌بینی را دریافت کنیم، میخواستیم از هر جایی امکان فرستادن عکس را داشته باشیم؛ برای این منظور با استفاده از فریم‌ورک Nativescript-Vue که ترکیب فریم‌ورک‌های Nativescript که برای ساخت اپلیکیشن‌های اندروید و ios با استفاده از زبان جاوااسکریپت (javascript) است و Vue که یک فریم‌ورک جاوااسکریپتی برای ساخت Progressive Web App هاست، اپلیکیشن اندرویدی برای پیش‌بینی تصاویر توسط مدل و با اتصال به سرور تولید شد.

کد اپلیکیشن در ریپازیتوری در دسترس است.

دپلوی کردن و استفاده از مدل در عمل (Model deployment)

10نویسندگان ‌: محیا مهدیان و محمد حسن ستاریان

پس از اینکه یک مدل را آموزش دادیم، می‌خواهیم یک سرور سبک و کوچک داشته باشیم تا بتوانیم با فرستادن عکس نتیجه پیش‌بینی (Predict) مدل را دریافت کنیم، درواقع کاری می‌کنیم که امکان پیش‌بینی از هرجایی از طریق اینترنت فراهم باشد. اینکار کمک می‌کند بتوانیم سرویس‌ها و حتی اپلیکیشن‌‌هایی برای استفاده عملی از مدل خود داشته باشیم.

برای اینکار چندین راه وجود دارد؛ در این پست ما روش‌‌های اجرای لوکال، دپلوی با Heroku و اجرا از سرور ریموت را بررسی می‌کنیم.

 

اجرای لوکال


اگر در فکرید که اجرای لوکال به دسترسی از طریق اینترنت چه ربطی دارد، اجازه بدید ابزار مورد نیاز این روش را معرفی کنیم:

ابزار‌ها

ngrok – ابزاری رایگان برای ایجاد تونل از اینترنت به یک پورت در سیستم لوکال است. ngrok یک آدرس قابل دسترس از اینترنت به پورت مشخص شده می‌دهد تا بتوان ترافیک پورت را از خارج سیستم از طریق اینترنت دریافت کرد.

Flask – فلسک یک میکروفریم‌ورک سبک برای راه‌اندازی سریع و راحت وب‌سرور است. آموزش مقدماتی فلسک را بخوانید.

قبل از شروع، طبق این مراحل ngrok را نصب کرده و آن‌را به PATH سیستم خود اضافه کنید.

طبق آموزش مقدماتی فلسک، کدی مانند نمونه کد زیر برای سروری که قادر به گرفتن عکس (upload)، لود مدل آموزش داده‌شده (Load model)، پیش‌بینی عکس (Predict)‌ و برگرداندن خروجی است، بنویسید.

سپس، سرور فلسک را با وارد کردن دستور زیر در ترمینال اجرا کنید:

پس از اجرا، سرور در آدرس http://localhost:5000 در دسترس می‌شود.

حال با استفاده از ngrok به این سرور یک آدرس قابل دسترس در اینترنت اختصاص می‌دهیم؛ برای اینکار یک ترمینال جدید باز کرده و دستور زیر را وارد می‌کنیم:

در این دستور با فراخوانی ngrok گفته ایم به برنامه درحال اجرا در پورت ۵۰۰۰ میخواهیم دسترسی از طریق پروتکل http بدهیم. پس از اجرای دستور بالا مطابق شکل زیر آدرسی که می‌توان برای دسترسی به سرور استفاده کرد به همراه آدرس مدیریت سرویس ngrok به نمایش در‌می‌آید:

ngrok output

پس از آن می‌توانید از طریق این آدرس و endpoint های تعریف شده از مدل خود استفاده کنید.

 

دپلوی با Heroku


شاید سخت‌ترین روش بین دو روش دیگر این روش و استفاده از Heroku است و مفاهیمی که این روش به عنوان پیش‌نیاز لازم دارد تا آشنا باشید کم نیستند. اما شاید از روش‌های دیگر سخت‌تر باشد اما می‌تواند جذاب‌تر و حتی پرکاربرد تر باشد. همچنین لازم به ذکر است این سرویس فعلا برای استفاده مسدود بوده و نیاز به اتصال غیر مستقیم است و در استفاده رایگان حجم پروژه نباید از ۵۰۰ مگابایت بیشتر باشد.

ابزار‌ها

Heroku – سرویس (PaaS (Platform as a service ای و درواقع بستری به عنوان سرویس ابری است که از زبان‌های برنامه نویسی زیادی پشتیبانی می‌کند که برنامه نویس را از کارهای DevOps لازم برای راه‌اندازی یک سرور بی‌نیاز می‌کند.

Flask – فلسک یک میکروفریم‌ورک سبک برای راه‌اندازی سریع و راحت وب‌سرور است. آموزش مقدماتی فلسک را بخوانید.

Github – گیت‌هاب سرویس میزبانی و کنترل نسخه تحت وب قدرت گرفته از گیت (git) است.

GitLFS – سیستم مدیریت فایل‌های حجیم گیت.

GitLFS سرویس ارائه شده توسط GitHub برای کنترل نسخه فایل‌های حجیم (حجیم تر از ۵۰ مگابایت) است و چون ما در پروژه خود فایل‌های نظیر فایل مدل آموزش داده شده و شاید فایل‌های دیگر داشته باشیم به این برنامه احتیاج داریم.

در ادامه مطابق آموزش شروع استفاده از Heroku با زبان پایتون، دلپوی برنامه خود (سرور پیش‌بینی) را، با استفاده از خط فرمان -و با شروع از سیستم خود- بررسی می‌کنیم؛ اما، این مراحل از طریق داشبورد Heroku که پس از ساخت اکانت در هروکو به آن دسترسی دارید نیز قابل انجام است. خوب است برای برنامه خود یک محیط مجازی پایتون ایجاد کرده، پیش‌نیاز‌های آن را نصب کرده از اجرای لوکال آن مطمئن شده و سپس اقدام به دپلوی آن کنید.برای آشنایی بیشتر آموزش ایجاد محیط مجازی پایتون و آموزش ایجاد سرور فلسک را بخوانید.

ورود

قبل از هر چیز یک اکانت رایگان در Heroku بسازید. اگر پایتون را به صورت لوکال نصب ندارید از اینجا دریافت کنید. در ادامه رابط خط فرمان Heroku را نصب کنید.

پس از نصب موارد فوق، ترمیتال را باز کرده و با استفاده از دستور زیر در Heroku لاگین می‌کنیم:

پس از اجرای دستور، ایمیل و رمزعبور خود را وارد کرده تا وارد شوید.

آماده‌سازی

اگر برنامه شما توسط git مدیریت نمی‌شود با استفاده از دستور git init  آن‌را فعال کنید. همچنین فایل‌های حجیم خود را مشخص کنید تا GitLFS آن‌ها را مدیریت کند:

در این مثال فایل model.h5  را که فایل مدل ذخیره شده است و حجم بیشتر از ۵۰ مگابایت دارد را با استفاده از GitLFS مدیریت می‌کنیم.

سپس، با استفاده از دستور زیر یک اپلیکیشن در Heroku درست می‌کنید که آماده دریافت سورس و اجرای آن‌ است:

با اجرای این دستور یک git remote  به نام heroku مرتبط با ریپوزیتوری گیت لوکال شما اضافه خواهد شد. همچنین، یک نام تصادفی (در این مثال lit-bastion-5032 ) به این برنامه تخصیص داده می‌شود. همچنین می‌توان با وارد کردن یک نام دلخواه نام مورد نظر خود را به اپلیکیشن اختصاص داد.

هروکو با استفاده از چند فایل تنظیم، تصمیم می‌گیرد برنامه را به چه صورت و با استفاده از چه سرویسی اجرا کند. برای آن‌که مشخص کنیم برنامه چگونه باید اجرا شود به سه کانفیگ فایل runtime.txt و requirements.txt به همراه فایل Procfile نیاز داریم.

runtime.txt

این فایل شامل توضیحاتی در مورد محیط اجرای برنامه و درواقع زبان مورد استفاده است.

ما این فایل را با محتوی زیر ایجاد می‌کنیم:

requirements.txt

این فایل، پیش‌نیازهای اجرای برنامه را مشخص می‌کند.

ما این فایل را با خروجی دستور pip freeze  که پکیج‌های نصب شده برای پروژه را چاپ می‌کند به صورت زیر ایجاد می‌کنیم:

Procfile

این فایل، شامل توضیحات نحوه اجرای برنامه است.

ما ابن فایل را با دستور زیر ایجاد خواهیم کرد:

این دستور بیان می‌کند که برنامه ما یک برنامه از نوع web بوده و لازم است با استفاده از برنامه سرور gunicorn اجرا شود و فایل اجرایی اپلیکیشنی به نام server است.

دلیل استفاده از سرور gunicorn بجای سرور پیش‌فرض پایتون این است که هروکو از این سرور برای اجرا، بخصوص برای اجرای فلسک استفاده می‌کند.

نکته مهم استفاده از gunicorn این است که این برنامه ابتدا یک سرور اجرا کرده سپس برنامه ما را در آن import می‌کند. از آنجایی که برنامه ما خود سرو خواهد شد نیازی به دستور ()app.run  نخواهد بود و اگر در کد خود از این دستور استفاده کرده ایم باید آن را مانند مثال زیر در شرط بررسی import شدن یا نشدن ماژول قرار دهیم:

با اعمال تغییرات فوق و اضافه کردن کانیفگ فایل‌ها، این تغییرات را با استفاده از گیت کنترل می‌کنیم:

قبل از ادامه دپلوی با استفاده از دستور heroku local web  می‌توانیم سرور خود را به صورت لوکال تست کنیم، اما از آنجایی که برنامه gunicorn در ویندوز قابل اجرا نیست اگر از ویندوز استفاده می‌کنید این امکان وجود نخواهد داشت.

حال اگر برنامه ما نیاز به تغییر نداشته و آماده push  کردن هستیم، با دستور زیر برنامه را در ریپوزیتوری ریموتی که هروکو در اختیارمان گذاشته بود push  می‌کنیم:

readme_assets/images/heroku-git-push.gif

اگر همه چیز موفقیت آمیز باشد، برنامه ما دپلوی شده و آماده استفاده است. قبل از آن با استفاده از دستور زیر مطمئن می‌شویم که حداقل یک نمونه از این برنامه درحال اجرا باشد:

با استفاده از دستور زیر می‌توانیم آدرس اختصاص داده شده به برنامه را در مرورگر باز کنیم:

برنامه آماده استفاده است!

روش بهتر استفاده از هروکو این است که ابتدا فایل‌های پروژه را در گیت‌هاب قرار دهیم. حتی می‌توان یک branch به پروژه آماده شده برای دپلوی روی هروکو اختصاص داد. سپس از طریق داشبور هروکو مستقیما به گیت‌هاب وصل شده و پروژه را دپلوی کرد.

heroku deploy options

اجرا از سرور ریموت


مراحل این روش تا حدود زیادی شبیه روش اول است، چراکه باز نیز با استفاده از flask یک برنامه سرور اجرا می‌کنیم. برای این روش لازم است از یکی از سرویس‌های ارائه دهنده سرور‌های ابری (Cloud servers) و یا سرور‌های اختصاصی (VPS)، سروری تهیه کنید. پس از تهیه سرور IP ای برای دسترسی به سرور به شما داده می‌شود. با استفاده از این سرور و از آنجایی که این IP یک IP عمومی (Public IP)‌ است، تنها کافی است با استفاده از فلسک سروری در سیستم اجرا کرده و host آن را برابر ‘0.0.0.0’ قرار دهیم تا از طریق اینترنت قابل دسترس باشد.

ابزار‌ها

Flask – فلسک یک میکروفریم‌ورک سبک برای راه‌اندازی سریع و راحت وب‌سرور است. آموزش مقدماتی فلسک را بخوانید.

SSH – پروتکل شبکه‌ای برای اتصال امن که یکی از کاربرد‌های آن ورود به یک سیستم ریموت است.

برای اتصال به سرور از SSH استفاده می‌کنیم. برای همین اگر از ویندوز استفاده می‌کنید از نرم‌افزار PuTTY استفاده کرده و اگر از لینوکس استفاده می‌کنید و یا در سیستم ویندوز خود کرنل لینوکس را فعال کرده‌اید (WSL) -از طریق کرنل لینوکس موجود در سیستم- به آی‌پی سرور از طریق SSH متصل شوید.

سپس، پیش‌نیاز‌های لازم برای اجرای اسکریپت‌های پایتون را نصب کرده و فایل‌های لازم برای اجرای مدل شامل، کد اجرای سرور فلسک، فایل مدل و دیگر فایل‌های مورد نیاز را به سرور انتقال دهید (از طریق راه‌اندازی گیت سرور روی سرور و یا آپلود کردن فایل‌ها و دانلود آن‌ها روی سرور).

پس از آن تنها کار لازم اجرای اسکریپت سرور فلسک است. توجه کنیم که برای اجرای سرور فلسک host آن‌را برابر ‘0.0.0.0’ و پورت دلخواه (پیش فرض ۵۰۰۰) تنظیم می‌کنیم:

برنامه در آدرس سرور و پورت تعیین شده اجرا شده و از طریق endpointها در دسترس خواهد بود.

 

منابع

مقاله‌های «پلوی کردن مدل کراس» و «دپلوی مدل‌های کراس» در مدیوم

رپوزیتوری گیت «مثال دپلوی اپلیکیشن پایتون در هروکو»، tl;dr

آموزش مقدماتی فلسک (Flask)

Flask, web development one drop at a time

نویسندگان ‌: محیا مهدیان و محمد حسن ستاریان

مقدمه و آشنایی

فلسک یک فریم‌ورک وب مبتنی بر پایتون است برای ایجاد سریع و ساده وب‌سرور که توسط آرمین‌روناچر توسعه داده‌شده است. تلاش برای ساده‌نگه داشتن طراحی فلسک و کوچکی فریم‌ورک و قائل نشدن بسیاری از پیش‌فرض ها برای برنامه‌نویسان دلیلی‌است که این بسته‌نرم افزار را یک میکروفریم‌ورک می‌نامند. فلسک رایگان و متن‌باز بوده و  با مجوز آزاد BSD منتشر شده است.

کار با فلسک به قدری ساده است که اگر کمی با زبان پایتون آشنا باشید با دیدن اولین کدهای فلسک با ساختار این فریم‌ورک آشنا می‌شوید. فریم‌ورک فلسک با همه‌ی سادگی خود بسیار قدرتمند و کاراست و به هیچ عنوان کوچک بودن فریم‌ورک را نمی‌توان با ضعیف بودن آن برابر دانست و امکانات فریم‌ورک‌هایی مثل جنگو و ریلز را با اندکی جستوجو به دست می‌دهد. برای مثال از سرویس‌های بزرگی که از فلسک استفاده می‌کنند می‌توان از Pinterest و Linkedin نام برد که به مناسب بودن فلسک برای توسعه‌ی سرویس‌های اینترنتی اشاره دارد.

دو کتابخانه‌ی اساسی پایه‌‌های قدرتمند فلسک را ساخته‌اند؛ به عنوان واسط وب‌سرور ( WSGI ) از کتابخانه‌ی werkzeug و برای تمپلیت‌انجین از Jinja2 استفاده کرده اند که هردو کتابخانه توسط تیم توسعه ی فلسک توسعه یافته شده است.

بطور پیش‌فرض برای کار با دیتابیس‌ها، اعتبارسنجی فرم ها و کاربران و از این دست کارها ابزار مشخصی در فلسک تعریف نشده است و می‌توان از ابزار‌های شخص ثالث (Third party applications) که برای آن توسعه داده شده‌اند استفاده کرد.

نصب

آماده کردن محیط مجازی

برای نصب و راه‌انداری پروژه‌ها معقول‌ است یک محیط‌ مجازی توسعه ساخت تا در حین کار و حتی یادگیری، مفسر عمومی و پکیج‌های عمومی سیستم دچار تغییر و کانفلیکت نشوند. محیط‌های توسعه‌مجازی یک کپی از مفسر پایتون را بصورت خصوصی در دایرکتوری پروژه شما ایجاد می‌کنند و بعد از فعال کردن این مفسر پکیج‌ها هم بصورت خصوصی در دایرکتوری پروژه نصب می‌شوند.

نحوه ایجاد و فعال‌سازی محیط مجازی را از اینجا بخوانید.

نصب فلسک

حالا نوبت نصب بسته ی فلسک است. متداول ترین روش نصب بسته‌های پایتون استفاده از مدیر بسته‌ی pip است که با استفاده از آن فلسک با دستور زیر نصب می‌شود :

برای بررسی صحت نصب فلسک مفسر پایتون را بصورت تعاملی در ترمینال باز کنید ( تنها دستور python را نوشته و  اینتر کنید ) و بسته‌ی فلسک را با دستور زیر فراخوانی کنید :

اگر خطایی رخ نداد فلسک درست نصب شده است و می‌توانید با اجرای دستور زیر نسخه نصب شده را بررسی کنید:

ساختار برنامه‌ها در فلسک

فلسک هیچ محدودیتی درمورد ساختاربندی فایل‌های پروژه برای شما ایجاد نمی‌کند و می‌توانید ساختار خودتان را داشته باشید یا از رول‌های متداول جامعه ی فلسک استفاده کنید.

ساخت برنامه های فلسک

شروع سریع

کدهای یک اپلیکیشن ساده‌ی فلسک که عبارت  Hello World  را در یک صفحه ی وب نمایان می‌کند بصورت زیر است :

این برنامه از چند بخش تشکیل شده است : فراخوانی و تعریف فلسک ، تعریف مسیرها، اجرای فلسک.

فراخوانی و تعریف فلسک

برای ساخت برنامه‌های فلسک نیاز است ابتدا فلسک را در فایل پایتون خود لود کنید و سپس یک نمونه (instance) از Flask بسازید یعنی این بخش :

تنها آرگومان مورد نیاز برای کانستراکتور فلسک نام ماژول یا پکیج main است که برای بیشتر برنامه ها __name__ در پایتون مقدار درستی است.

می‌توانیم بجای نام اینستنس فلسک ( در مثال بالا app ) هر نام متغیر معتبری استفاده کنیم.

فلسک روی pip یک بسته از ماژول‌های مرتبط به هم است و نه یک ماژول و به همین دلیل هر ماژول باید از درون بسته ی flask جداگانه ایمپورت بشود.

تعریف مسیرها

مسیرها همان آدرس‌های (url های) مختلفی هستند که عملیات‌های متفاوتی بر اساس آن‌‌ها انجام می‌شود. مثلا  site.domain  مسیر ریشه و  site.domain/subdomain  یک مسیر دیگر در همان سایت تعریف می‌کند. در کد مثال ما مسیر بصورت زیر تعریف شده بود :

در اینجا یک دکوریتور نوع ()route  از app (که در قسمت قبل ساختیم) برای تابع Hello world  تعریف می‌کند و آدرس مسیر ('/') را به آن می‌فرستد. مسیرها در فلسک اساس ساخت برنامه‌ها هستند. با استفاده از مسیر‌ها می‌توانید به سادگی بخش‌های مختلف وب‌اپلیکیشن خود را بسازید و مدیریت کنید.

اجرای فلسک

در آخر به پایتون می‌گوییم که فلسک را روی یک وب‌سرور اجرا کند که دستورات آن بصورت زیر است :

این شرط برای بررسی این موضوع است که آیا این فایل پایتون مستقیما اجرا می‌شود (برقراری شرط) و یا به عنوان یک ماژول در یک برنامه دیگر وارد شده است (عدم برقراری شرط).

این کد را در یک فایل مانند app.py ذخیره کرده و در خط فرمان با دستور  python app.py  اجرا کنید. خروجی روی ترمینال چیزی شبیه این است :

که آدرس 127.0.0.1:5000  را که در خروجی مشخص شده است اگر در مرورگر خود امتحان کنید روی صفحه عبارت Hello World  نمایان می‌شود. فلسک به صورت پیش‌فرض پورت ۵۰۰۰ را برای اجرا در نظر می‌گیرد.

تابع run می‌تواند پارامتر‌ ای با عنوان host  داشته باشد که مشخص می‌کند سرور برروی چه آدرسی اجرا شود، همچنین توسط پارامتر  port  می‌توان پورتی که سرور روی آن اجرا شود را مشخص کرد و توسط پارامتر  debug و دادن مقدار true  به آن می‌توان مشخص کرد که لاگ‌ها و گزارشات مربوط به اشکال یابی برنامه نیز چاپ شوند.

برای اینکه سرور از طریق کامپیوتر‌های متصل به همین شبکه قابل مشاهده و استفاده باشد به پارامتر  host  مقدار 0.0.0.0  را می‌دهیم.

توجه کنید که پارامتر host از جنس string، پارامتر port از جنس integer و پارامتر debug از جنس boolean است.

برنامه‌های کاربردی‌تر

استفاده از متغیرها در آدرس

در تعریف قوانین آدرس‌دهی می‌توان به آدرس‌ها با استفاده از عملگرهای <>  متغیر اضافه کرد مانند  <variable_name>  تا بخشی از آدرس به صورت متغیر توسط تابع در دسترس باشد.همچنین می‌توان نوع متغیر را با استفاده از یک مبدل مانند  <converter:variable_name>  مشخص کرد:

نوع پیش‌فرص برای متغیرها string  است.

آدرس‌های منحصر به فرد و هدایت آدرس

به نحوه آدرس دهی در برنامه زیر دقت کنید:

آدرس تعریف شده برای  projects  شبیه آدرس دایرکتوی است و در انتهای خود یک ‘/’ دارد. اگر به این آدرس بدون ‘/’ برویم فلسک ما را به آدرس اصلی (آدرس با ‘/’) هدایت می‌کند.

آدرس تعریف شده برای  about  شبیه آدرس فایل است و در انتهای خود ‘/’ ندارد.  اگر به این آدرس با ‘/’ برویم با خطای ۴۰۴ (صفحه‌ای یافت نشد) مواجه خواهیم شد. این امر این امکان را می‌دهد تا آدرس‌های تعریف شده به این سبک منحصر به فرد بوده و کمک می‌کند موتورهای جستوجو یک صفحه را دوبار ایندکس نکنند.

متدهای HTTP

برنامه‌ها هنگام دسترسی به آدرس‌ها از متد‌های HTTP مختلفی استفاده می‌کنند. به صورت پیش‌فرض یک آدرس تنها به متد GET  پاسخ می‌دهد، اما با استفاده از مشخص کردن متدهای لازم در پارامتر methods  از دکوریتور ()route  می‌توان به متدهای مختلف پاسخ داد:

در کد با بررسی نوع (method) درخواست (request) عملیات متفاوتی انجام می‌شود. این بدین معنی است که اگر به یک آدرس با متد GET درخواست بدیم یک پاسخ و اگر به همان صفحه با متد دیگری مانند POST درخواست بدیم پاسخ دیگری دریافت خواهیم کرد.

استفاده از قالب‌ها (templates)

می‌توان مشخص کرد با مراجعه به صفحه‌ای یک فایل HTML رندر شده و به نمایش درآید. برای اینکار فلسک از فولدربندی خاصی استفاده می‌کند. در فولدر پروژه باید دو فولدر به نام های static و templates ایجاد کنید که در فولدر templates فایل های html و در فولدر static فایل های css و js خودتون رو قرار بدهید.

حال  اگر کاربر به صفحه welcome/ برود فانکشن به جای متن خالی، فایل HTML رو return می‌کند. توجه داشته باشید که این فایل HTML باید داخل پوشه templates قرار گرفته باشد تا فلسک اون رو شناسایی بکند.

استفاده در بخشی از برنامه

از آنجایی که فلسک تنها به عنوان دکوریتور برای توابعی که خود مشحص می‌کنیم قرار می‌گیرد و آن‌‌ها را به آدرس‌های مشخص شده مرتبط می‌کند، می‌توان از آن در یک برنامه در کنار دیگر توابع استفاده کرد و نیازی به جدا سازی فایل مربوط به serve و اجرای برنامه از فایلی که عملیات برنامه در آن پیاده‌سازی شده نیست. به عنوان مثال به فایل زیر توجه کنید:

این برنامه یک برنامه یادگیری ماشین است که عکس ارسالی به endpoint با آدرس predict/  و متد POST  را آپلود کرده و با predict آن نتیجه را برمی‌گرداند. با اجرای کد مدل مربوطه لود شده و سرور شروع به گوش دادن به endpoint ذکر شده برای دریافت درخواست‌ها می‌کند و در صورت دریافت درخواستی حاوی تصویر، توابع مربوطه برای predict عکس را صدا زده و نتیجه را برمی‌گرداند.

افرونه‌ها

فلسک یک فریم‌ورک بسیار توسعه پذیر است و می‌توانید بصورت ماژولار کدهای آن را تقسیم بندی و استفاده کنید. همچنین پلاگین‌های بسیاری هم‌اکنون برای آن نوشته شده است که میتوانید در صفحه‌ی extension های فلسک تعدادی از بهترین افزونه‌های فلسک را بیابید و استفاده کنید.

 

منابع

مقاله «میکروفریم‌ورک فلسک – معرفی» از سایت کدرز

مقاله «آشنایی با میکرو-فریمورک فلسک»‌ از سایت هایو

 

مطالعه بیشتر

سری آموزش «The Flask Mega-Tutorial» از miguelgrinberg

محیط‌های مجازی پایتون (Python virtual environments)

python virtual environments visualization

نویسندگان ‌: محیا مهدیان و محمد حسن ستاریان

مقدمه

محیط‌های مجازی (virtual environments) از مهمترین شیوه‌های آزموده شده (Best practice) در توسعه نرم‌افزار تحت پایتون هستند. از آنجایی که با نصب پکیج‌های پایتون، همگی این پکیج‌ها در مسیر‌های مشخصی نصب می‌شوند ممکن است باعث ایجاد مشکلاتی شوند. برای مثال حالتی را در نظر بگیرید که در ایجاد پروژه‌های مختلف به نسخه‌های متفاوتی از برخی کتابخانه‌ها نیاز دارید؛ در این صورت چگونه می‌توانید چندین نسخه‌ متفاوت از یک کتابخانه‌ را در پایتون نصب کنید؟ فرض کنید می‌خواهیم بر روی توسعه دو وب‌سایت؛ یکی توسط نسخه جدید (۱.۸) وب فریم‌ورک جنگو (Django) و دیگری بر روی یک نسخه قدیمی (۰.۹۶) از آن کار کنیم، ولی نمی‌توانیم! چراکه نمی‌شود هر دوی این نسخه‌ها را با هم در پایتون (دایرکتوری site-packages) نصب داشت. یا فرض کنید که برای تست پکیج‌هایی می‌خواهیم بدون نصب آن‌ها در کنار پروژه اصلی، از آن‌ها استفاده کنیم؛ در این وضعیت راه حل ایجاد محیط‌هایی مجازی (Virtual Environments) برای توسعه پروژه‌های مورد نظر است، ابزاری که محیط توسعه و اجرای هر پروژه پایتون را به همراه تمام وابستگی‌های (Dependencies) آن از پروژه‌های دیگر جدا یا ایزوله (AKA. Sandboxing) می‌کند.

در ادامه به بررسی ابزارهای زیر می‌پردازیم:

  • conda
  • virtualenv
  • virtualenvwrapper
  • pyvenv

کوندا (Conda)


یکی از روش‌های مدیریت ورژن‌های پایتون و همچنین ایجاد محیط‌های مجازی پایتون استفاده از کوندا است.

از مزایای conda می‌شود به موارد زیر اشاره کرد:

  • ساختار مشخص و ساده : شناخت ساختار فولدربندی آن بسیار ساده است.
  • مدیریت پنهان فایل‌ها : فایل‌های مربوطه را خارج از فولدر خود نصب نمی‌کند.
  • انعطاف‌پذیری : علاوه بر پکیج‌های زیادی که خود پشتیبانی می‌کند، پکیج‌های pip نیز در محیط‌های ساخته شده توسط کوندا قابل نصب هستند.
  • چندمنظوره: علاوه بر مدیریت محیط‌های مجازی و نسخه‌های پایتون برای زبان‌های دیگر مانند R هم استفاده می‌شود.

نصب

برای نصب Conda از این آموزش استفاده کنید.

ساخت محیط مجازی توسط Conda

برای ساخت محیط مجازی ای با نام myenv و نصب پایتون ۳.۴ و پکیج‌های package1 و package2 با ورژن دلخواه به صورت زیر عمل می‌کنیم:

ورود و خروج به محیط مجازی

برای ورود و فعال سازی محیط مجازی ای با نام myenv به صورت زیر عمل می‌کنیم:

در صورتی که به درستی وارد محیط مجازی شوید، prompt خط فرمان تغییر می‌کند. برای مثال با فعال کردن محیط myenv توسط دستورات بالا به صورت زیر تبدیل می‌شود:

اکنون می‌توانیم در پروژه خود به کتابخانه‌ها، pip، دایرکتوری site-packages و مفسری اختصاصی دسترسی داشته باشیم. همچنین با فعال کردن یک محیط مجازی، فایل‌های اجرایی مربوط به این محیط درون متغیر PATH قرار می‌گیرند تا دستورات مورد استفاده به سادگی در دسترس باشند.

برای خروج و غیر فعال کردن محیط از دستور زیر استفاده می‌کنیم:

برای لیست کردن محیط‌های مجازی از دستور  conda env list و برای لیست کردن پکیج‌ها درون یک محیط از دستورات conda list ویا pip list با توجه به اینکه با کدام روش پکیج‌ها را نصب کرده‌ایم استفاده می‌کنیم.

حذف محیط مجازی

برای حذف محیط مجازی ای که دیگر به آن احتیاج نداریم به صورت زیر عمل می‌کنیم:

برای مطالعه بیشتر در مورد کوندا و کنترل محیط‌های مجازی توسط آن به منابع مربوطه در انتهای پست مراجعه کنید.

از آنجایی که Conda پکیجی چندمنظوره بوده و امکانات و نرم‌افزار‌های زیادی را همراه خود دارد، حجیم بوده و راه‌اندازی آن ممکن است به زمان بیشتری نیاز داشته باشد. روش دیگر ساخت محیط‌های مجازی استفاده از پکیج virtualenv و یا افزونه آن virtualenvwrapper است که در ادامه توضیح داده خواهند شد.

virtualenv


از معروف‌ترین و پراستفاده ترین روش‌های ساخت محیط‌های مجازی برای پایتون استفاده از پکیج virtualenv  است که در ادامه بررسی میکنیم.

نصب

این پکیج به راحتی با استفاده از پیپ (pip) به صورت زیر قابل نصب است:

 

چنانچه بر روی سیستم عاملی هر دو نسخه پایتون 2x یا 3x نصب است؛ این موضوع که virtualenv را توسط pip کدام نسخه نصب نمایید، اهمیت چندانی ندارد. چرا که امکان استفاده از آن برای دیگر نسخه‌ها نیز وجود دارد.

ساخت محیط مجازی توسط virtualenv 

اکنون برای ایجاد یک محیط مجازی از دستور  virtualenv ENV  استفاده می‌شود که منظور از  ENV  در آن، نشانی دایرکتوری دلخواهی است که قصد داریم محیط مجازی در آن ایجاد گردد:

دستور بالا موجب ایجاد یک محیط مجازی در مسیر  /Documents/ENV  سیستم عامل، بر پایه مفسر پایتونی که از pip آن برای نصب virtualenv استفاده کردیم می‌شود و چنانچه بخواهیم محیط مجازی خود را بر پایه‌ نسخه‌ موجود دیگری از پایتون ایجاد نماییم، لازم است با استفاده از فلگ   --python  نشانی مفسر آن مشخص گردد [صفحه راهنما + این پاسخ ]:

در نمونه کد‌ بالا، نسخه‌های۲.۷ و ۳.۴ پایتون از پیش بر روی سیستم عامل نصب بوده و نسخه ۳.۳ و ۲.۵ توسط کاربر در مسیرهای مشخص شده نصب شده است.

ورود و خروج به محیط مجازی

برای ورود و فعال سازی محیط مجازی ای با نام myenv به صورت زیر عمل می‌کنیم:

توچه کنید که با ورود موفق به محیط مجازی prompt خط فرمان چگونه تغییر می‌کند.

اکنون می‌توانیم در پروژه خود به کتابخانه‌ها، pip، دایرکتوری site-packages و مفسری اختصاصی دسترسی داشته باشیم. همچنین با فعال کردن یک محیط مجازی، فایل‌های اجرایی مربوط به این محیط درون متغیر PATH قرار می‌گیرند تا همانند تا دستورات مورد استفاده به سادگی در دسترس باشند.

در لینوکس می‌توانید با اجرای دستورات  which python3 و  which pip3 بررسی کنید که مسیر فایل اجرایی مفسر پایتون و pip از مسیر معمول آن (usr/bin/python3/)‌ متفاوت است.

پس، برای هر پروژه‌ای کافیست داخل پروژه یکبار با فراخوانی virtualenv کارهای لازمه را انجام دهید و پس از آن هرباری که داخل دایرکتوری پروژه مورد نظر می‌شوید آن محیط را فعال کنید.

برای خروج و غیر فعال کردن محیط از دستور زیر استفاده می‌کنیم:

اگر از لینوکس استفاده می‌کنید، با اضافه کردن alias های زیر می‌توان کار ورود و خروج از محیط‌های مجازی را ساده‌تر کرد:

 

virtualenvwrapper


virtualenvwrapper همونطور که از اسمش پیداست یک افزونه و wrapper برای virtualenv است که علاوه بر راحت کردن کار با آن، ایرادات زیر رو هم رفع می‌کند. توجه کنید که virtualenv پیش‌نیاز این پکیج نبوده و لازم به نصب آن نیست:

  • جلوگیری از ساخت دایرکتوری مربوط به مدیریت پایتون و محیط مجازی کنار فایل‌های پروژه (در صورت استفاده از git، باید این فولدر را در gitignore اضافه کنید)
  • لزوم به اعمال فعال سازی و غیر فعال سازی
  • و موارد دیگر

این پکیج برای لینوکس توسعه داده شده است و برای ویندوز یک توزیع از این پکیج با نام virtualenvwrapper-win قابل استفاده است.

نصب

این پکیج به راحتی با استفاده از پیپ (pip) به صورت زیر قابل نصب است:

پکیج virtualenvwrapper برخلاف virtualenv و مانند conda، تمام محیط‌های مجازی را داخل دایرکتوری ای که ما مشخص می‌کنیم ذخیره می‌کند که اینکار باعث جداسازی کد‌ها و پکیج‌های پایتونی ای که نصب می‌کنیم بدون ایجاد ایراداتی که اشاره شد می‌شود.

پیش از ساخت محیط‌های مجازی، اگر از لینوکس استفاده می‌کنید دو دستور پایین را داخل فایل bashrc. (یا zshrc. یا کانفیگ فایل هر شل مورد استفاده) قرار می‌دهیم:

و اگر از ویندوز استفاده می‌کنید متغیری با نام  WORKON_HOME  در Environment Variable ویندوز اضافه کرده و مقدار آن را برابر  USERPROFILE%\Envs%  می‌گذاریم. [آموزش]
با اینکار فولدر virtualenvs. را در لینوکس و فولدر Envs را در ویندوز و در مسیر‌های مشخص شده برای ذخیره سازی محیط‌های مجازی مشخص می‌کنیم.

ساخت محیط مجازی توسط virtualenvwrapper

برای ساخت محیط مجازی ای با نام myenv و ورود به آن از دستور زیر استفاده می‌کنیم:

ورود و خروج به محیط مجازی

برای ورود و فعال سازی محیط مجازی ای با نام myenv به صورت زیر عمل می‌کنیم:

و برای خروج و غیر فعال کردن محیط از دستور زیر استفاده می‌کنیم:

برای لیست کردن محیط‌های مجازی از دستور  lsvirtualenv و یا دستور  workon بدون ورودی استفاده می‌کنیم.

حذف محیط مجازی

برای حذف محیط مجازی ای که دیگر به آن احتیاج نداریم به صورت زیر عمل می‌کنیم:

یک دستور جالب این پکیج  mktmpenv است که یک محیط مجازی با اسم تصادفی ساخته و آن‌را فعال می‌کند و با غیر فعال کردن آن محیط مجازی را پاک می‌کند که برای تست یک کد یا پکیج به سرعت ایده‌آل است.

pyvenv


در نسخه‌های ۳x پایتون و از ۳.۳ به بعد ماژولی با نام venv برای ایجاد محیط‌های مجازی به کتابخانه استاندارد پایتون افزوده شده است که می‌توان از آن به جای نصب virtualenv استفاده نمود و نیازی به نصب ندارد؛ برای این منظور از دستور  pyvenv  و با الگویی مشابه  pyvenv ENV  استفاده می‌گردد.

ساخت محیط مجازی توسط virtualenvwrapper

برای ساخت محیط مجازی ای با نام myenv و ورود به آن از دستور زیر استفاده می‌کنیم:

ورود و خروج به محیط مجازی

برای ورود و فعال سازی محیط مجازی ای با نام myenv به صورت زیر عمل می‌کنیم:

و برای خروج و غیر فعال کردن محیط از دستور زیر استفاده می‌کنیم:

 

منابع

کوندا (Conda)

مقاله «چرا به محیط‌های پایتون نیاز دارید و چگونه آن‌ها را با کوندا مدیریت کنیم» در مدیوم

مقاله «ساخت محیط‌های مجازی برای پایتون توسط کوندا» از سری مقاله‌های دستورالعمل‌های ۲ دقیقه‌ای برای دانشمندان

virtualenv

فصل «ایجاد محیط مجازی» از کتاب آنلاین پایتون کدرز

مقاله «پایتونیک – معرفی Virtual Environment‌ها قسمت اول» در ویرگول

virtualenvwrapper

مقاله «پایتونیک – معرفی Virtual Environment‌ها قسمت دوم» در ویرگول

مستندات virtualenvwrapper

pyvenv

فصل «ایجاد محیط مجازی» از کتاب آنلاین پایتون کدرز

 

مطالعه بیشتر

این سوال و جواب در stackoverflow

مقاله «رمزبرداری از محیط‌های مجازی»

کار با تصاویر توسط ImageMagick

نویسندگان ‌: محیا مهدیان و محمد حسن ستاریان

imagemagick

ImageMagick یک مجموعه فوق‌العاده از کتابخانه (Libraries) و برنامه (Binaries) رایگان و متن‌باز و چندسکویی برای کار با تصاویر پیکسلی (Raster Graphics) و برداری (Vector Graphics) با امکانات فراوان برای نمایش، تبدیل، تغییر و ویرایش است و می‌تواند با بیش از ۲۰۰ فرمت مختلف تصویر کارکند. از این برنامه می‌توان از طریق رابط خط فرمان (CLI) و یا برنامه‌ های نوشته شده توسط کتابخانه‌های آن در زبان‌های دیگر استفاده کرد. برای آشنایی با ImageMagick تنها به این پست اکتفا نکرده و حتما مستندات آن را بخوانید.

برای مثال تمامی تغییرات زیر به راحتی با استفاده از خط فرمان قابل اعمال به تصاویر هستند:

ImageMagick examples

در ادامه چندتا از دستورات پر استفاده را مرور می‌کنیم. اما قبل از آن روش نصب:

نصب

ImageMagick چندسکویی بوده و برای سیستم‌عامل‌های مختلف در دسترس است. برای استفاده از آن می‌توان از کتابخانه‌های آن برای زبان‌های مختلف من جمله C و ++C، پایتون، PHP و غیره استفاده کرد و یا برنامه‌های آماده (Binaries) آن را نصب و استفاده کرد.

ویندوز

برای نصب ImageMgick در ویندوز می‌توان فایل نصب (exe) آن را دریافت کرد و یا با استفاده از پکیج منیجر Chocolatey (از اینجا دریافت کنید) با وارد کردن دستور زیر در CMD آن را نصب کرد:

لینوکس

برای نصب ImageMagick روی لینوکس، از دستورات زیر استفاده می‌کنیم:

اطلاعات بیشتر

روش استفاده

استفاده از ImageMagick توسط رابط خط فرمان بسیار ساده است (لیست مثال‌های استفاده). قالب اجرای دستورات با استفاده از دستور magick --help  و magick -usage  به صورت زیر است (برای مشاهده کامل خروجی روی کد دوبار کلیک کنید):

قالب تمامی دستورات شامل، خواندن تصویر، اعمال تغیرات روی آن و مشخص کردن خروجی است.

در ویندوز تمامی عملیات‌ها با دستور magick  شروع و گاهی لازم است پس از دستور  magick  علمیات مربوطه نیز نوشته شود (لیست دستورات)، اما در لینوکس دستورات با اسم عملیات شروع می‌شوند.

پس توجه داشته باشیم دستورات به فرم magick convert  در لینوکس به صورت convert  استفاده خواهند شد.

همچنین ImageMagick از globbing برای آدرس‌دهی پشتیبانی می‌کند. بنابراین بجای تغییر چندین تصویر بجای دستور حلقه زیر:

از دستور زیر استفاده می‌کنیم:

که مزیت آن علاوه بر سادگی، قابلیت همزمان سازی ImageMagick است که سرعت کار را افزایش می‌دهد.

دستورات

نمایش (Display)

برای نمایش تصویر می‌توان در ویندوز از دستور imdisplay  و در لینوکس از magick display  استفاده کرد.

تبدیل (Convert)

برای تبدیل فرمت تصویر کافیست مانند نمونه دستور زیر فرمت خروجی را مشخص کنید:

همچنین با استفاده از دستور convert  نیز می‌توان فرمت تصویر را تغییر داد و به علاوه این دستور می‌هواند تغییرات دیگری نیز در حین تغییر فرمت بدهد. برای مثال دستور زیر لبه‌های تصویر (که نتیجه اعمال فیلتر canny با سایز کرنل مشخص شده است) را در فایل خروجی ذخیره می‌کند:

canny filter

کاهش کیفیت (Reduce Quality)

از راه‌های فشرده‌سازی تصویر کاهش رزولوشن آن است با دستور زیر می‌توان درصد کیفیت تصویر خروجی را مشخص کرد. اینکار نیز با دستور convert  قابل انجام است:

تغییر سایز (Resize)

برای تغییر سایز تصویر می‌توان از دستور resize استفاده کرد. روش‌های دیگر مشخص کردن سایز خروجی را ببینید.

با استفاده از دستور mogrify نتیجه در خود تصویر ورودی ذخیره می‌شود بنابراین دیگر نیازی به مشخص کردن فایل خروجی نیست.

تصویر مختلط (Collage)

به کمک magick به سرعت و تنها با یک دستور می‌توانیم یک تصویر مختلط از چندین تصویر درست کنیم:

با اجرای خط اول تصویر خروجی کیفیت خوبی نخواهد داشت، دلیل آن مقادیر پیش‌فرض برای geometry  است که برابر ۱۲۰ پیکسل تنظیم شده. در خط دوم با وارد کردن مقدار مورد نظر برای geometry  گفته‌ایم سایز تصاویر تغییر نکنند و سایز حاشیه تصاویر را برابر ۱۰ پیکسل تنظیم کرده‌ایم.

بریدن تصویر (Cropping)

برای بریدن تصویر از طرفین می‌توان از دستور shave  استفاده کنیم:

دستور اول ۱۰ پیکسل از محور x و ۱۰ پیکسل از y از دو سمت تصویر را برش می‌دهد؛ دستور دوم تنها ۱۰ پیکسل از دوسمت محور x تصویر و دستور سوم ۲۰ پیکسل از دو سمت محور y تصویر  را بر می‌دهند.

shave command

برای بریدن ناحیه دلخواه از تصویر باید از دستور crop  استفاده کنیم. آدرس تصویر نوشته شده ( :rose ) آدرس عکس‌های نمونه قابل استفاده شناخته شده توسط magick است که برای تست می‌توان استفاده کرد.

دستور اول عکسی با سایز ۴۰ پیکسل در ۳۰ پیکسل تولید خواهد کرد که از مختصات ۱۰ در ۱۰ تا تصویر برش زده خواهد شد -درواقع برشی به طول ۴۰ پیکسل و عرض ۳۰ پیکسل از مختصات ۱۰ در ۱۰ از تصویر گرفته می‌شود؛ بدیهی است اگر ناحیه برش از تصویر بزرگتر باشد تنها قسمت برش خورده، تصویر خروجی خواهد بود- دستور دوم تصویری خروجی با حداکثر اندازه ۰ پیکسل در ۳۰ پیکسل خواهد داشت که نتیجه برش از مختصات ۴۰ در ۳۰ است، برای دستور سوم نیز تصویری خروجی برابر نتیجه برشی با اندازه ۴۰ پیکسل در ۳۰ از مختصات ۱۰- در ۱۰-  و دستور چهارم، تصویر خروجی ای از نتیجه برش تصویر به مساحت ۹۰ پیکسل در ۶۰ از مختصات ۱۰- در ۱۰- خواهد داشت؛ چون که این ناحیه شامل کل تصویر است تصویر خروجی با ورودی تفاوتی ندارد. در دستور پنجم که عکس خروجی نتیجه برش تصویر از مختصات ۹۰ در ۶۰ با سایز ۴۰ پیکسل در ۳۰ پیکسل خواهد بود، ناحیه برش هیچ قسمتی از عکس را شامل نمی‌شود، بنابراین عکسی خالی خواهد ساخت.

crop

چرخاندن (Rotation)

برای چرخواندن تصویر به صورت زیر عمل می‌کنیم. مقدار مثبت rotate  به معنی چرخش ساعتگرد و مقدار منفی آن به معنی چرخش پادساعتگرد است.:

دستور اول تصویر را ۳۰ درجه ساعتگرد می‌چرخاند. دستور دوم تصویر را ۳۰ درجه ساعتگرد چرخانده و پس‌زمینه ناشی از حذف تصویر را با رنگ تعیین شده پر می‌کند. دستور سوم تصویر را چرخانده و پس‌زمینه آن را حذف می‌کند.

توجه کنید که برای داشتن تصویر بدون پس‌زمینه، به فرمتی آن را ذخیره کنید که از کد رنگ آلفا پشتیبانی کند. برای مثال فرمت png  تصویر بدون پس‌زمینه را به درستی ذخیره می‌کند اما فرمت jpg  تصویر بدون پس‌زمینه را با پس‌زمینه سفید ذخیره می‌کند.

rotate

موارد فوق تنها قسمت کوچکی از توانایی‌های ImageMagick است که شامل متحرک‌سازی، کار به متن‌ها، کار با تصاویر دیجیتال و خام و غیره می‌شود. بنابراین مطالعه مستندات و نمونه موارد استفاده در درک توانایی‌های آن موثرتر خواهد بود.

اتصال مستقیم سرویس کولب (Google Colab) به درایو (Google Drive) از طریق فایل سیستم FUSE

نویسندگان ‌: محیا مهدیان و محمد حسن ستاریان

google colab

اگر با گوگل کولب (Google Colab) کار کرده باشید می‌دانید که فایل سیستم آن از فایل سیستم گوگل درایو (Google Drive) جدا بوده و برای استفاده از فایل‌های خود باید پس از اتصال کولب به درایو فایل‌های مورد نیاز را دانلود کرده و پس از اعمال تغییرات برای جلوگیری از پاک شدن فایل‌ها -فایل‌های موجود در کولب پس از ۱۲ ساعت پاک می‌شوند- آن‌ها را در درایو دانلود کنید.

روش دیگر اینکار اتصال گوگل درایو به صورت یک فایل سیستم FUSE به گوگل کولب است، که در واقع گوگل درایو را در کولب mount می‌کنیم. از مزیت‌های آن این است که فایل‌ها در طرفین همگام و یکسان (sync) بوده و برای استفاده از فایل‌ها نیازی به دانلود و آپلود آن‌ها نیست.

روش اتصال

نصب پیش‌نیازها

ابتدا با استفاده از دستورات زیر،‌ پکیج‌های مورد نیاز را دانلود و نصب می‌کنیم:

تائید هویت

سپس، با استفاده از اجرای دستور زیر و باز کردن لینک داده شده، در اکانت خود وارد شده و کد داده شده را در قسمت مربوطه وارد می‌کنیم تا اجازه اتصال گوگل کولب به گوگل درایو را بدهیم:

همچنین، با دستورات زیر همانند مراحل بالا اجازه دسترسی فایل سیستم FUSE را به گوگل درایو می‌دهیم:

اتصال

حال فولدری در فایل سیستم گوگل کولب به نام drive  ساخته و گوگل درایو را در آن mount می‌کنیم:

پس از اجرا لیست فایل‌های دایرکتوری  drive  چاپ می‌شود که درواقع تمامی فایل‌های گوگل درایو شما هستند.

 

منبع

این نوت‌بوک در گوگل کولب

مقدمه ای بر deep learning

مقدمه ای بر deep learning :

Image classification :

یکی از مبانی پایه در computer vision بحث classification اشیا و تصاویر است که تشخیص می دهد تصویری که به کامپیوتر داده شده چیست. (برای مثال  مشخص می کند تصویر گربه است یا نه)

چالش ها:

در واقع یک طیف پیوسته ای برای هر شی وجود دارد. برای مثال در گربه بین هر دو پیکسلی که ما می بینیم n پیکسل دیگر وجود دارد. همچنین رنگ ها هم طیف پیوسته ای دارند که برای کد کردن مجبوریم آن ها را در یک کانال( RGB (red, green, blue کد کنیم و عدد آن بسته به کامپیوتر و پیاده سازی ای که انجام می دهیم از 0 تا 255 متغیر است. بنابراین در این مرحله تعدادی از اطلاعات برای تبدیل از دنیای واقعی به محیط کامپیوتر که به آن semantic gap می گویند، از دست می رود.

 

چالش های دیگری هم وجود دارد. برای مثال الگوریتم (KNN (k-nearest neighbor  در دیتاست هدی performance خیلی خوبی داشت ولی در دنیای واقعی این گونه نیست و یک سری مشکلات ممکن است رخ دهد، مانند viewpoint validation ها به این معنی که اجسام را می توان از زاویه های مختلف دید و به همین دلیل الگوریتم KNN پاسخ گو  نیست.

Illumination :

کامپیوتر باید همانند چشم انسان در شرایط نوری مختلف قادر باشد یک جسم را درک کند. برای مثال در این شکل رنگ های دو گربه در محیط پیکسلی اصلا شبیه به هم نیست.

Deformation :

انسان قادر است اجسام را در هر حالت که باشند تشخیص دهد اما هدف این است که در computer vision هم این تشخیص به درستی صورت گیرد.

Occlusion :

در صورتی که قسمتی از اجسام پوشیده باشد باز هم انسان قادر به تشخیص آن است بنابراین الگوریتمی که پیاده سازی می شود نیز باید به همین صورت باشد

Background clutter :

اگر جسم در background محو شده باشد باز هم الگوریتم پیاده سازی شده باید بتواند آن را تشخیص دهد.

Intraclass variation :

از هر جسمی انواع مختلفی وجود دارد. برای مثال نژاد های مختلف گربه یا سگ وجود دارد که کامپیوتر باید بتواند تا حدی generalize کند که بتواند آن ها را تشخیص دهد.

Image classifier :

حالا باید مشخص کنیم چه الگوریتمی بهتر است تا این چالش ها برطرف شوند:

def predict(image):

     return class_label

ابتدا تابع predict تعریف می شود که یک عکس می گیرد و class_label ها را برمی گرداند.

بر خلاف sort کردن اعداد یا ماکزیمم گیری هیچ راه روشن و سریعی برای این گونه کلاس ها وجود ندارد و مجبوریم با راه حل های data-driven پیش برویم.

 

Data-driven approach :

ابتدا باید یک سری data و یک تابع train وجود داشته باشد که label ها به آن پاس داده می شوند. سپس بسته به نوع الگوریتم، طی یک فرآیند یادگیری یک مدل ساخته می شود که باید آن را ذخیره کنیم. بنابراین دفعه های بعد که عکس جدیدی به آن داده می شود می توان از یک تابع جدید به نام predict استفاده کرد که model و test_image به آن پاس داده می شود و دیگر نیازی به label نیست.

کد:

def train(train_images, train_labels):

    return model

def predict(model, test_images):

    return test_labels

K_Nearest Neighbor :

در دنیای واقعی این الگوریتم جواب نمی دهد، برای مثال اگر صورت فرد سانسور شده باشد یا در شرایط نوری متفاوت قرار بگیرد نمی توان از این الگوریتم استفاده کرد.

بنابراین KNN هیچگاه برای تصاویر کاربرد ندارد مگر اینکه مانند دیتاست هدی آنقدر کنترل شده باشد که بتوان از آن استفاده کرد.

Neural network و deep learning

History :

از سال 2012 تا کنون deep learning روال رو به رشد چشمگیری داشته است.

تعداد مقالاتی که در رابطه با deep learning جمع آوری شده رشد بسیار زیادی داشته و این بدان معنی است که افراد زیادی وارد این فیلد شده اند.

 

 

 

 

دکتر Andrew ng ، استاد دانشگاه استنفورد، در 5 نوامبر 2017 در کنفرانس خود اعلام کرد تعداد مقالات در بحث deep learning بیش از حد زیاد شده اما با فقدان نیروی متخصص مواجه هستیم و طبق پیش بینی او یک انفجار در شغل های مربوط به deep learning و  neural networkایجاد می شود بنابراین وجود نیروی متخصص بیش از پیش ضروری است.

همچنین Andrej Karpathy ، مدیر هوش مصنوعی شرکت تسلا، در وبلاگ medium خود گفته است deep learning  و neural network نرم افزار ها را دچار تغییر و تحول زیادی می کند. (software2.0 )

 

Neural network کجا استفاده می شود؟

این شبکه ها در دیدن، شنیدن، خواندن متن و استنتاج آن (مانند dictionary translation ها) کاربرد دارند. همچنین برای کنترل کردن (برای مثال انجام بازی کامپیوتری) هم استفاده می شوند.

Neural network ها شبیه logo block یا building block هایی هستند که neural network practitioner (سازنده ی neural network ) می تواند از آن ها استفاده کند.

می توانیم هر شبکه ای که شناخته شده است را یک building block در نظر بگیریم و مشابه کار Andrej Karpathy این شبکه ها را به هم وصل کنیم. برای مثال یک شبکه داریم که image را به خوبی تشخیص می دهد و همچنین یک شبکه داریم که متن را خوب می فهمد. می توان این دو شبکه را پشت سر هم وصل کرد (اتصال یک شبکه CNN و یک سری شبکه RNN (این نوع شبکه برای dictionary ها استفاده می شود.))

نتیجه این است که عکس را که می دهد خروجی جمله است. در واقع یک سری عکس با caption به آن داده شده که شبکه باید generalize  کند که اگر عکس جدید به آن داده شد بتواند جمله معادل را بسازد.

ساده ترین neural network که در نظر گرفته شده neural network یک لایه است. (softmax )

برای مثال یک عکس 2 * 2 را در نظر بگیرید، اگر آن را starch کنیم 4 پیکسل به وجود می آید. فرض کنید سه کلاس خروجی داریم که به طور مثال مشخص می کند تصویر داده شده گربه، سگ و یا گوسفند است یعنی یک ماتریس 4 * 3 داریم. اگر این ماتریس 4 * 3 در یک ماتریس 1 * 4 ضرب شود 3 عدد برمی گرداندکه می تواند مشخص کند در آخر کدام کلاس انتخاب شده است. یک راه ساده تر این است که سطر اول را وزن های مربوط به کلاس cat ، سطر دوم را وزن های مربوط به کلاس dog و سطر سوم را وزن های مربوط به کلاس sheep در نظر بگیریم که به اضافه ی bios می شودد. Bios را می توان به حوزه ی 0 و 1 انتقال داد که این کار با softmax انجام می شود.

و در آخر بعد از عملیات training هر عددی که بزرگ تر شود کلاس مربوط به آن انتخاب می شود.

ارقام دست نویس هدی: (اعدادی که در کنکور سراسری بالای دفترچه به صورت دست نویس نوشته می شود.)

در واقع این ارقام ابتدا normalize شده، سپس background آن ها عوض و بعد از آن با روش های مناسب باینری شده است.

شبکه Dense :

شبکه ای است که در لایه ی اول خود 25 نورون دارد (چون عکس 5 * 5 است) و در لایه ی آخر چون 10 کلاس داریم 10 نورون

قرار می گیرد که از 0 تا 9 مشخص می شوند.

تعداد نورون های لایه ی وسط را باید خودمان مشخص کنیم که با چند نورون به performance بهتری می رسد.

در این نوع شبکه همه ی نورون ها به یکدیگر وصل می شوند که به آن fully connected یا همان dense می گویند.

روی هر کدام از این نورون ها یک تابع activation اعمال می شود که relu برای این کار مناسب است.

کد:

Model=Sequential()

Model.add(Dense(64, activation=’relu’, input_dim=25))

Model.add(Dense(10, activation=’softmax’))

نمودار  relu

فرمول softmax :

تابع هزینه و روش بهینه سازی:

کد:

Model.compile(loss=’categorical_crossentropy’ , optimizer=’rmsprop’ , metrics= [‘accuracy’])

همانطور که پیش تر گفته شد با model.compile میزان loss مشخص می شود. معیار loss مقدار بد بودن شبکه را مشخصمی کند.

rmsprop  روش بهینه سازی است که نشان می دهد به ازای هر data چقدر با چیزی که می خواهیم شبکه predict کند فاصله داریم.

روش های دیگری نیز برای بهینه کردن وجود دارد مانند sgd ، momentum ، nag ، adagrad و … . در نهایت همه ی این روش ها شبکه را بهینه می کنند اما زمان بهینه کردن هم اهمیت زیادی دارد.