من یک مدل را آموزش دادم. قدم بعدی چیه ؟

این پست آموزه های Vladimir Iglovikov یکی از استادبزرگ‌های Kaggle است که آرزو می‌کرد هنگامی که در چالش‌های هوش مصنوعی شرکت می‌کرد کسی این پیشنهادات را به او می‌داد.

پست اصلی را می‌توانید اینجا بخوانید. Teranus blog

مقدمه :

من در مسابقات Machine Learning پلتفرم‌های مختلفی شرکت کردم تا مهارت خودم را در ML تقویت کنم. من رتبه ی 19 جهانی و عنوان استادبزرگ Kaggle را کسب کردم.

هر چالش ML با یک دانش جدید،کد و مدل به پایان می رسید. من آموختن را دوست داشتم اما از ارزش این روند یادگیری چشم‌پوشی می‌کردم. کد های من در repository (مخزن) خصوصی github باقی می‌ماند و در آخر همه‌ی آن‌ها پاک می‌شد.

این وضعیت در همه‌ی پلتفرم‌ها یکسان است. دانش‌آموز مدل را آموزش می‌دهد،مقاله می‌نویسد و بعد از اینکه قبول می‌شود،تمام این کار‌ها را رها می‌کند،این آموزه‌ها پاک می‌شود و دانش آموز سراغ چالش بعدی می‌رود.

این بلاگ در مورد قدم‌های کوچکی صحبت می‌کند که بعد از پایان هر چالش می‌توانید انجام دهید.

این قدم‌ها باعث می‌شود:

  • اطلاعات فنی شما افزایش یابد
  • برند شخصی خودتان را بسازید
  • موقعیت های شغلی شما بهتر شود
  • دنیا به جای بهتری تبدیل شود :))

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

Teranus Repository



1.کد را در repository عمومی github پخش کنید. 5+ دقیقه

معمولا کد در repository خصوصی github است. چه چیزی را از دست می‌دهید اگر کدتان را عمومی کنید؟

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

متداول‌ترین مانعی که دیدم این است که مردم فکر می‌کنند باید کد‌های عمومی بدون نقص باشند و گرنه مورد قضاوت قرار می‌گیرند.

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

مرحله‌های بعدی بر اساس مثال زیر جلو می‌رود.

Teranus Retinaface



2.خوانایی کدتان را افزایش دهید. 20+ دقیقه

با اضافه کردن syntax formatters و checkers می‌توانید خوانایی کدتان را افزایش دهید. اصلا سخت و زمان‌بر نیست. checkers و formatters کد بد را به خوب تغییر نمی‌دهند اما خوانایی آن را افزایش میدهند. به درست‌کردن syntax‌های کد مثل بهداشت فردی فکر کنید مثل مسواک زدن.

مرحله‌ی اول: Configuration files (فایل‌های پیکربندی)

این فایل‌ها را به ریشه‌ی (root) repository خود اضافه کنید.

مرحله‌ی دوم: ملزومات

کتاب‌خانه‌های مورد نیاز را نصب کنید.

pip install black flake8 mypy


مرحله‌ی سوم : Black

راه‌های بسیار زیادی برای Format کردن کد وجود دارد.formatter‌هایی مثل black یا yapf، کد را بر اساس قواعد از پیش تعیین شده تغییر می‌دهند. خواندن کدی که از تعدادی الگو پیروی می‌کند راحت‌تر است وقتی ساعت‌ها روی کد کار می‌کنید و نیاز دارید که زمینه را بین سبک‌های مختلف کدنویسی تغییر دهید، «انرژی اراده» را تخلیه می‌کند؛ نیازی به انجام آن بدون دلیل موجه نیست.

اجرا کنید

black .

تمامی فایل‌های پایتون شما را با قواعد black تغییر می‌دهد.

مرحله‌ی چهارم: Flake8

اجرا کنید

flake8

کد را اصلاح نمی‌کند اما کد را برای مشکلات syntax چک می‌کند و آن‌ها را روی صفحه نشان می‌دهد.

درستشان کنید.

مرحله ی 5 :mypy

پایتون سیستم تایپ ایستا ندارد اما توصیه می‌شود که الگویی به آرگومان‌های تابع و انواع return اضافه کنید. به عنوان مثال :

class MyModel(nn.Module):
....
def forward(x: torch.Tensor) -> torch.Tensor:
....
return self.final(x)


  1. کد خواناتر می‌شود.
  2. می‌توانید از mypy package برای بررسی سازگاری آرگومان‌ها و انواع تابع استفاده کنید.

بعد از به روز کردن کد، mypy را بر کل repository اجرا کنید.

mypy .

باید الگوی تایپی به کد اضافه کنید :

اگر mypy مشکلی پیدا کرد؛ درستشان کنید.

مرحله‌ی ششم :

اجرا کردن دستی mypy،black،flake8 آزاردهنده است. ابزاری به اسم pre-commit hook این مشکل را حل می‌کند. برای فعال کردن آن ، این فایل را در repository کپی کنید. pre-commit-config.yaml

نیاز دارید که pre-commit package را روی ماشین خود نصب کنید.

pip install pre-commit

و با این خط کد مقدار اولیه را بدهید.

pre-commit install

الان همه چیز آمادست

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

تفاوت اصلی بین اجرای دستی black, flake8, mypy این است که به شما التماس نمی‌کند که مشکلات را برطرف کنید، بلکه شما را مجبور به انجام این کار می کند. از این رو، "انرژی اراده" هدر نمی رود.

مرحله‌ی هفتم: اقدام‌های github

شما چک‌ها را به pre-commit hook اضافه کرده اید و آن‌ها را به صورت محلی اجرا می‌کنید. اما شما نیاز به یک خط دفاع دوم دارید. برای اجرای این بررسی‌ها در هر درخواست pull به Github نیاز دارید.

راه انجام این کار، اضافه کردن فایل .github/workflows/ci.yaml به repository است.

این کد هاست :

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install black flake8 mypy
- name: Run black
run:
black --check .
- name: Run flake8
run: flake8
- name: Run Mypy
run: mypy retinaface

این به github می‌گوید که چه چیزی را چک کند.

من همین‌طور پیشنهاد می‌کنم بیخیال push کردن مستقیم کدتان به master branch بشوید.

یک شاخه درست کنید ، کدتان را اصلاح کنید، commit کنید،push کنید، درخواست pull ایجاد کنید و بعد با master branch ادغام کنید.

این کار‌ها در بازار کار کاملا استاندارد است اما در فضای آموزشی و میان کسانی که در چالش‌ها شرکت می‌کنند غیر‌معمول است.

اگر با این ابزار‌ها آشنا نیستید، ممکن است بیش از 20 دقیقه طول بکشد که ابزار‌ها را اضافه کنید و خطا‌ها و هشدار‌ها را درست کنید.

یادتان باشد در پروژه بعدی این چک‌ها را در commit اول که هیچ کدی نوشته نشده است اضافه کنید. از آن لحظه، هر commit کوچک بررسی می شود، و شما باید هر بار حداکثر چند خط کد را اصلاح کنید: سربار کوچک، عادت عالی.

همچنین خواندن کتاب عادات اتمی را توصیه می کنم. در مورد تغییرات کوچک در رفتار شما صحبت می‌کند که بهره‌وری و کیفیت زندگی شما را بهبود می‌بخشد.



3. یک Readme خوب بنویسید.

یک Readme خوب دو هدف را دنبال می‌کند:

برای خودتان: شما فکر می‌کنید که هرگز قرار نیست از این کد استفاده کنید اما هرگز نگویید هرگز ؛ شما این کار را انجام خواهید داد و یادتان هم نمی‌آید که اینجا چه اتفاقاتی افتاده است. readme به شما کمک خواهد کرد.

برای دیگران: readme یک نقطه‌ی فروش است. اگر دیگران نتوانند هدف repository شما را بفهمند و این‌که چه مشکلی را حل می‌کند، از آن استفاده نخواهند کرد و تمام کار‌هایی که شما انجام دادید تاثیر مثبتی بر دیگران نمی‌گذارد.

برای machine learning repositories حداقل ها عبارتند از:

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

اگر شما نیاز به نوشتن 100500 کلمه برای توصیف نحوه اجرای آموزش یا نتیجه‌گیری آن دارید، این یک زنگ خطر است. شما باید کد خود را اصلاح و user friendly کنید. مردم اغلب می پرسند - چگونه می‌توانم برنامه‌نویس بهتری شوم؟ این تمرینی است که کمک می‌کند. شما باید کد خود را بازنویسی کنید. سعی کنید از چشمان شخص دیگری به Readme خود نگاه کنید و به مرور این رفتار باعث ایجاد یک عادت خوب می‌شود که به محصول خودتان از دیدگاه یک کاربر نگاه کنید.



4.استفاده از مدل‌تان را راحت‌تر کنید. 20+ دقیقه

حدس می‌زنم شما بنویسید

model = MyFancyModel()
state_dict = torch.load(<path to weights>)
model.load_state_dict(state_dict)

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

کار می‌کند و مراحل واضح هستند، اما به وزن‌هایی روی دیسک و دانستن اینکه کجا هستند؛ نیاز دارد. راه‌حل زیبا‌تر این است که از تابع torch.utils.model_zoo.load_url در torchvision و مشابه آن در TensorFlow یا Keras استفاده کنید.
می‌توانیم انجام دهیم :

from retinaface.pre_trained_models import get_modelmodel = get_model("resnet50_2020-07-20", max_size=2048)

اگر وزن‌ها روی دیسک نباشند، از اینترنت دانلود شده و روی دیسک ذخیره می شوند. مدل مقداردهی اولیه می‌شود و وزن‌ها بارگذاری می شوند.

این user friendly است و این همان چیزی است که در کتابخانه‌های Torchvision و timm می‌بینید.

مرحله‌ی اول : وزن‌های میزبان مدل از پیش آموزش داده شده

این بزرگترین مانع برای من بود. اگر نمی خواهید با AWS، GCP سر و کار داشته باشید،پس کجا می‌توانم وزن‌ها را برای مدل قرار دهم؟

ظاهراً یک راه‌حل عالی وجود دارد، من می‌گویم یک راه فرار. می‌توانید در GitHub به نسخه‌ها وزن بدهید.

محدودیت برای هر فایل 2GB است که برای اکثر مدل‌های Deep learning کافی است.

مرحله‌ی دوم : تابعی بنویسید که به مدل مقدار اولیه بدهد و وزن‌ها را بارگذاری کند.

در مورد مثال من : Teranus

این قابلیت زمانی که ما نوت‌بوک و برنامه وب Colab را بسازیم، مورد استفاده قرار خواهد گرفت.



5.کتابخانه بسازید. 20+ دقیقه

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

git clone retinaface

مرحله‌ی اول : dependency های لازم را به requirement.txt اضافه کنید

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

pip freeze > requiements.txt

یا به صورت دستی به‌روزرسانی کنید.

مرحله ی دوم : ساختار فایلی repository را تغییر دهید.

یک "main folder" بسازید در مورد من، به نام "retinaface"، مشابه repository ایجاد کنید.

  • تمام کدهای مهم را به آنجا منتقل کنید.
  • تصاویر کمکی، Readme، نوت‌بوک‌ها یا تست‌ها را به آنجا منتقل نکنید.

این یک روش معمول برای ساختار کد در repositories است.

امیدوارم در آینده از ابتدا این الگو را دنبال کنید. اگر چیزی حتی ساختارمندتر می‌خواهید، Package Cookie Cutter را بررسی کنید.

مرحله‌ی سوم: فایل config اضافه کنید.

  • فایل setup.py را با محتوایی مشابه setup.py به root پوشه اضافه کنید.
  • یک نسخه برای package اضافه کنید. در مورد من، من آن را به فایل init پوشه "main" اضافه کردم.

مرحله‌ی چهارم: حساب کاربری در pypi بسازید.

اگر در pypi حساب کاربری ندارید؛ وقت آن است که دست به کار شوید.

مرحله‌ی پنجم: کتاب‌خانه بسازید و در pypi آپلود کنید.

python setup.py sdist
python setup.py sdist upload

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

pip install <your_library_name>

اگر صفحه‌ی package را در pypi بررسی کنید، خواهید دید readme که در repository است برای ارائه پروژه استفاده می‌شود.

ما از عملکرد این مرحله برای Google Colab و برای یک برنامه وب استفاده خواهیم کرد.



6. نوت بوک google colab بسازید. 20+ دقیقه

افزودن یک نوت بوک jupyter به repository برای نشان دادن نحوه مقداردهی اولیه مدل و انجام نتیجه‌گیری، تمرین خوبی است. مثال

می‌توانیم بهتر هم انجام دهیم.

ما یک مدل اولیه "fancy" و جادوی pip install را در دو مرحله قبل فعال کردیم. بیایید از آن استفاده کنیم.

ما می توانیم یک نوت‌بوک Google Colab ایجاد کنیم.

حالا تنها چیزی که کسی برای بازی با مدل شما نیاز دارد یک مرورگر است! افراد بیشتری می توانند آن را بررسی کنند. مثال

فراموش نکنید که لینکی برای یک نوت‌بوک به readme خود اضافه کنید و نسخه را در PyPi به روز کنید.



7.یک برنامه وب ایجاد کنید. 20+ دقیقه

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

این فرض درست است، یک پروژه پیچیده برنامه وب به مهارت‌هایی نیاز دارد که دانشمندان داده ممکن است نداشته باشند.

ساختن یک برنامه وب ساده که مدل را نشان می‌دهد آسان است.

من یک github repository جداگانه برای یک برنامه وب ایجاد کردم. با این حال، می‌توانید این کار را در repository خود با مدلتان انجام دهید.

مرحله‌ی اول: کد برای برنامه اضافه کنید.

کد

"""Streamlit web app"""import numpy as np
import streamlit as st
from PIL import Image
from retinaface.pre_trained_models import get_model
from retinaface.utils import vis_annotations
import torchst.set_option("deprecation.showfileUploaderEncoding", False)
@st.cache
def cached_model():
m = get_model("resnet50_2020-07-20", max_size=1048, device="cpu")
m.eval()
return m
model = cached_model()st.title("Detect faces and key points")uploaded_file = st.file_uploader("Choose an image...", type="jpg")if uploaded_file is not None:
image = np.array(Image.open(uploaded_file))
st.image(image, caption="Before", use_column_width=True)
st.write("")
st.write("Detecting faces...")
with torch.no_grad():
annotations = model.predict_jsons(image) if not annotations[0]["bbox"]:
st.write("No faces detected")
else:
visualized_image = vis_annotations(image, annotations) st.image(visualized_image, caption="After", use_column_width=True)

کمتر از 40 خط

مرحله‌ی دوم: فایل‌های config را اضافه کنید.

نیاز دارید که این فایل‌ها را اضافه کنید:

  • شما می‌توانید از این فایل بدون تغییر استفاده کنید. setup.sh
  • شما باید مسیر فایل را با برنامه تغییر دهید. Procfile

مرحله‌ی سوم: requirements.txt را اضافه کنید.

مرحله‌ی چهارم: در herokuapp ثبت‌نام کنید.

مرحله‌ی پنجم: کد را push کنید.

heroku login
heroku create
git push heroku master

می‌توانید مثال را در https://retinaface.herokuapp.com/ ببینید.



8. یک بلاگ بنویسید. 4+ ساعت

بسیاری از مردم کار خود را دست‌کم می‌گیرند. آنها فرض می‌کنند که اگر بدانند چگونه کاری را انجام دهند، همه آن را می‌دانند. اینطور نیست.

زباله یک نفر گنج دیگری است.

مقاله شما به افراد دیگر کمک می‌کند و فرصت‌های شغلی شما را بهبود می‌بخشد.

من در Lyft، در سطح 5 کار می‌کنم و از تکنیک‌های deep learning برای مشکلات ماشین‌های خودران استفاده می‌کنم. قبل از Lyft، من در آژانس جمع‌آوری بدهی TrueAccord کار می‌کردم.

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

برای من که کار کرد پس برای شما هم کار می‌کند.

برای machine learning، توصیه می کنم متنی را بنویسید که شامل موارد زیر است:

  • مشکل چه بود؟
  • راه حل شما چه بود؟

اگر تا این لحظه بلاگ را مطالعه کردید و مطالب آن برایتان مفید بود پس شما می‌توانید با نوشتن یک مقاله‌ی machine learning در مورد مسئله‌ای که با آن روبه‌رو شدید و چگونگی حل آن؛ از من تشکر کنید.