یادگیری ماشین در صنعت؛ یا چگونه‌ یک مساله‌ی هوش مصنوعی را در دستگاه نوا بنوازیم!

مقدمه:

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

پیش درآمد:

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

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

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

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

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

تمام این موارد مشخص می‌کند که آیا یک شرکت، توانایی اضافه کردن محصولات دیتایی به خود را دارد یا خیر.

البته، این نکته لازم به ذکر است که تقریبا برای هر دو مورد آنالیز و دیتا انجینیرینگ، یک جایی از کار احتمالا به عهده‌ی شما خواهد بود، و شما نیاز خواهید داشت که مهارت‌های خود را در این موارد رشد دهید. باید با دیتابیس‌های مختلف، از هر دو نوع relational و non-relational آشنا باشید، تقریبا در همه‌ی موارد لازم است به زبان SQL مسلط باشید و روش‌های نمایش خروجی‌ها را بشناسید. تسلط به روش‌های streaming و batch processing خیلی می‌تواند به رشد شما کمک کند، و ابزارهای کار با بیگ دیتا، هم‌چون spark, hive, HDFS و … ، می‌توانند کمک شایانی به به ثمر رسیدن کارها برسانند.

درآمد:

محصول، محصول و محصول

حال، با در نظر گرفتن این که سیستم توانایی داشتن چنین محصولاتی را دارد، کار اصلی آغاز می‌شود.

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

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

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

معمولا، تیم‌ها قبل از شروع کار، چیزی به اسم تعریف پایان (definition of done) را بین خود قرارداد می‌کنند، که مشخص می‌کند چه زمانی یک پروژه پایان یافته تلقی می‌شود. این می‌تواند نشان‌دهنده‌ی فرایندهای مهندسی یک تیم باشد، مثلا داشتن پایپ‌لاین خوب به همراه تست، یا مستند شدن پروژه. در مورد مسائل دیتایی، معمولا یک خطای پذیرفته شده و هم‌چنین یک حد بالا برای زمان اجرا نیز در این قرارداد وجود دارد، که مشخص می‌کند انتظار از پروژه با توجه به نیاز چقدر است. کدام پارامتر قرار است بررسی شود، در مسائل طبقه‌بندی accuracy یا precision یا recall ؟ خطای پیش‌بینی برای یک مساله‌ی رگرسیون تا چه حدی می‌تواند باشد و … .

شما احتمالا مقاله‌های پلاک دیوار (۱و ۲) رو قبلا دیده‌اید. درآمد این پروژه‌ها چه بود؟ یک تحقیقی روی دیوار توسط ناظرین انجام شد، و به نتیجه رسیدیم که حدود ۵۰ درصد آگهی‌های دیوار، به خاطر پوشاندن پلاک از طرق مختلف، مثل پوشاندن با انگشت، استفاده از واترمارک‌های بی‌کیفیت و یا گرفتن عکس به صورتی که کل نمای ماشین در آن مشخص باشد، کیفیت غیرقابل قبولی داشتند، که در نهایت منجر به زشتی صفحه‌ی اصلی دیوار، و نگرفتن اطلاعات کامل از روی عکس برای خریداران می‌شد. برای مثال، اگر کنار سپر ماشین دچار خوردگی بود، دیده نمی‌شد. در کنار این مساله، در صورتی که کاربر مجبور به گرفتن عکس با نمای کامل می‌شد، مسائل جدی حریم خصوصی پیش می‌آمد و ممکن بود در دراز مدت اثر سو روی اعتبار دیوار داشته باشد.

حال نیاز بود که تصمیم بگیریم که این مدل، روی client پیاده‌سازی شود یا back-end. جواب به این سوال ساده نیست، و هر کدام از راه‌حل‌ها، معایب و مزایای خود را داشت، و باید با بررسی trade-off ها، یک راه انتخاب می‌شد. پیاده‌سازی در client، منجر به این می‌شد که حجم برنامه به شدت زیاد شود، و تغییرات روی آن به دلیل نیاز به update، خیلی کند صورت بگیرد. از طرفی، پیاده‌سازی یک میکروسرویس در back-end، نیاز به حجم بالایی از منابع داشت و ممکن بود کاربر به صورت sync نتیجه را نبیند و بدون آگاهی از این‌ تغییر، هنوز کیفیت عکس‌های خود را تغییر ندهد. در نهایت، back-end انتخاب شد.

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

  1. آیا نیاز هست که وجود چند ماشین را هم بررسی کنیم؟
  2. چه تعداد درخواست بر ثانیه داریم؟ چه response time ای برای این مساله مناسب است؟
  3. آیا دسترسی به gpu در محیط productoin داریم؟
  4. ...

حزین

ساخت و تمیزکاری دیتا

خب. حالا تیم به این نتیجه رسیده که یک پروژه‌ی یادگیری ماشین را شروع کند. اصولا اولین قدم، آماده‌سازی یک دیتاست تمیز است. منظور من data preparation هست، نه data preprocessing که خود جزو مراحل یک کار ML است. معمولا اگر حل یک مساله‌ی واقعی در دستور کار باشد، با یک حجم خوبی از داده‌ی بسیار کثیف، با اعتبار پایین، دارای انواع خطاهای شناختی و بایاس‌های جدی، و منابع بدون ساختار روبه‌رو خواهید بود، که احتمالا ستون‌ و یا ستون‌های label آن‌ها، یا وجود ندارند، یا نیازمند بررسی خیلی جدی‌اند. این مساله‌، حجم خوبی از زمان کار شما را به خود اختصاص خواهد داد و بعضا می‌تواند بسیار خسته‌کننده و تکراری باشد.

برای مثال، فرض کنید که سیستم شما دارای تعدادی متن بوده و شما می‌خواهید به کمک یک شبکه‌ی LSTM ساده، یک مدل ‌seq2seq را آموزش دهید. این یک تمرین بسیار روتین در درس‌های یادگیری عمیق است. ولی، شما برای انجام این کار رو دادگان خودتان، اولا نیاز دارید که به اندازه‌ی کافی داده جمع‌‌آوری کنید. سپس ابزاری برای annotation در اختیار داشته باشید، و با توجه به سختی کار، نیروی معمولی یا متخصص برای انجام این عمل اختصاص دهید. در دنیای واقعی، احتیاج خواهید داشت که این annotation ها را بارها بررسی کنید تا به کیفیت مورد نیاز شما برسند، و ارتباطات لازم را با این تیم به انجام برسانید. ممکن است در حین انجام این وظیفه متوجه شوید که دادگان شما از لحاظ آماری کافی نیستند، (بالانس بودن دیتا، تعداد کافی، داشتن موارد خاص به اندازه‌ی نیاز و …) و مراحل باید تکرار شوند. در نظر بگیرید احتمالا انواع کیبرد‌های فارسی و عربی و انگلیسی در این نوشته‌ها موجودند، غلط‌های املایی و نگارشی جدی وجود دارند و … . این گوشه‌ای از کارهایی‌است که قبل از شروع کارها باید انجام دهید.

در بعضی مسائل نیز، ممکن است دیتای مورد نیاز، به کل نیاز به ساخته شدن داشته باشد. برای مثال، برای سیستم‌های توصیه‌گر، شما نیاز دارید که از پایه، شبیه بودن دو آیتم را تعریف کنید، و با توجه به تعریف‌، مسیر کار خود را بسازید. آیا این مساله را به شکل شبیه بودن یا شبیه نبودن تعریف خواهید کرد، یا نمره‌ای به شباهت اختصاص خواهید داد و از مدل انتظار دارید که یک مساله‌ی classification را حل کند یا یک مساله‌ی regression؟ ابعاد محصولی مساله در این‌جا خیلی مهم خواهند بود. برای مثال، اگر یک فروش‌گاه اینترنتی هستید، در لیست پیشنهادی برای یک رنگ ساختمانی، آیا قرار است رنگ‌های مشابه و با کیفیت‌های متنوع قرار گیرند، یا اجناس مرتبط مثل قلمو و تینر؟

چیزی که باید در نظر داشت، خیلی وقت‌ها چنین مسائلی ذاتا از جنس big data خواهند بود، و استفاده از ابزارهایی برای این‌کار، به یک امر حیاتی تبدیل خواهند شد. تاکیدم بر روی استفاده‌است، زیرا که ممکن است وظیفه‌ی نگه‌داری و توسعه‌ی این زیرساخت‌ها بر دوش تیم دیگری باشد، ولی شما به عنوان مشتری این سرویس‌ها، باید قادر باشید که تا حد امکان، از آن‌ها برای رسیدن به منظور خود استفاده کنید.

کرشمه

بازی با مدل‌ها

حال، با در نظر گرفتن آماده شدن دادگان، آموزش مدل‌های اولیه شروع می‌شود. تقریبا تقریبا هیچ‌وقت قرار نیست ما مدل‌های جدیدی را معرفی کنیم یا مدل‌های قبلی را از صفر توسعه دهیم. به لطف جامعه‌ی بزرگ دانشگاهی و مهندسی سراسر جهان، بسیاری از مسائل روتین ما به صورت کلی، حالا با دقت‌های بالا و پایین حل شده‌اند، و حتی تعداد خوبی مدل pretrained موجوداند. قطعا مثال‌های نقض زیادی برای این حرف هست، ولی حرف من به صورت آماری برای کلیات مسائل صادق است. این کمک گرفتن از منابع می‌تواند در لایه‌ی کتاب‌خانه، مثل catboost یا pytorch باشد، می‌تواند استفاده از کلیات یک قطعه کد از جایی مثل github باشد، و یا استفاده از مدل‌های پیش‌آموزش‌دیده و fine tune کردن آن‌ها.

حال، انواع متریک‌ها، برای بررسی عمل‌کرد مدل‌های متخلف مورد استفاده قرار می‌گیرند، و با توجه به definition of done ای که برای این مسئله مشخص شده، نتایج اولیه مشخص می‌گردند. چون این قسمت به صورت کلی جزو خود مراحل کار یادگیری ماشین هست، خیلی در آن توقف نمی‌کنم.

نهفت

اثبات درستی

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

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

عشاق

رفت و برگشت با بک‌اند

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

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

عمده‌ی ما، به دلیل جریان کلی آموزش و کارهای خودمان، عادت داریم که اکثریت کدهایمان در یک فایل مثل jupyter notebook و یا چند فایل پایتون بنویسیم، و معمولا best practice های توسعه‌ی نرم افزار را رعایت نمی‌کنیم. این اصول، از تبعیت از قوانین SOLID شروع شده، و مسائلی چون قابل بازسازی بودن، داشتن pipeline کامل، توجه به مسائل سیستم‌عاملی و … را شامل می‌شوند.

از طرفی، از آن‌جا که ما معمولا از کتاب‌خانه‌های open source برای توسعه‌ی مدل‌ها استفاده می‌کنیم، بعضی مسائل ممکن است به شکل کلی در آن‌ها رعایت نشده باشند. به عنوان مثال واقعی، ما در یکی از محصولات دیوار، متوجه شدیم که کتاب‌خانه‌ی tensorflow، مشکل memory leak دارد، و چنین مساله‌ای می‌تواند یک web service را دچار مشکلات جدی کند و یا مثلا کتاب‌خانه‌ی xgboost طراحی‌ tread-safe ندارد و پیاده‌سازی آن در سرویس‌های back-end، باید از طریق دیگری انجام شود. ممکن است حجم مدل بیش از حد زیاد شده و امکان اضافه کردن آن به اپ‌های موبایل نباشد و … .

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

فرود

نتیجه‌گیری

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