حدود بهمن یا اسفند سال ۱۳۹۹ بود که من، یک عدد رزبری پای ۴ مدل B (لینک) خریداری کردم که باهاش یه سری ایده رو عملی کنم. از وقتی که این دستگاه رو خریدم، مدت زیادی تقریبا گذشته اما خب چند هفته اخیر، شدیدا با این دستگاه در حال کشتی گرفتن و تست ایدههای مختلف هستم. یکی از ایدههای من پروژهای بود که تا حد زیادی به هوش مصنوعی (و بخصوص tensorflow) نیازمند بود. مشکلی که داشتم این بود که در خود مخازن PyPi ای که روی رزبری پای در دسترسه، هیچ ساخت درستی از tensorflow وجود نداره.
اما خب، نمیشه در دنیای تِک ناامید شد؛ به همین خاطر دنبال راهکار و راه حلی گشتم که بتونم تنسرفلو رو روی رزبری پای داشته باشم. یکم سختتر از حالت عادی (که استفاده از pip بود) شد اما ارزشش رو داشت. چون تونستم بدون مشکل مدلی که مدنظر داشتم رو لود و استفاده کنم. همچنین لازمه ذکر کنم که در این مطلب قراره یاد بگیریم چطور خود تنسرفلو رو نصب کنیم و به TFLite کاری نداریم.
رزبری پای چیه؟
رزبری پای (Raspberry Pi) یک کامپیوتر تکبرد (SBC یا Single Board Computet) محسوب میشه که توسط یک بنیاد غیرانتفاعی به همین اسم در بریتانیا طراحی شده (البته تولیدش مثل عمده محصولات دیگر، در کشور چین انجام میشه). این بردها معمولا یک پردازنده ARM دارند و میشه روی اونها سیستمعامل نصب کرد. خیلیهاشون هم ورودی/خروجی عاممنظوره (General Purpose Input/Output) یا همون GPIO دارند که میتونن رابطی بین این کامپیوتر و قطعات الکترونیکی دیگر باشند.
این کامپیوترهای کوچک – که در ابعاد یک کارت اعتباری ساخته شدند – اسباببازی خوبی برای برنامهنویسان و مهندسین کامپیوتر به شمار میان. بسیاری از متخصصین و علاقمندان از رزبری پای استفاده میکنن تا ایدهها و پروژههاشون رو پیادهسازی کنن. البته لازم به ذکره که خیلیها هم حتی محصولاتشون رو برپایه رزبریپای توسعه دادند (پس اگر دوست داشتید یکی تهیه کنید و باهاش بازی کنید، درنگ نکنید 😁)
تنسرفلو چیه؟
از اونجایی که این مطلب، در مورد نصب Tensorflow روی رزبری پای بود، لازمه که کمی هم در مورد تنسرفلو توضیح داده بشه. تنسرفلو یک کتابخونه نرمافزاری آزاد و متنبازه که توسط تیم Google Brain توسعه داده میشه. این کتابخونه، به ما اجازه میده که پروژهها و پروسههای یادگیری ماشین، هوش مصنوعی، یادگیری عمیق، استنباط آماری و … تا توسعه شبکههای عصبی مصنوعی رو انجام بدیم. به خاطر پشتیبانی گوگل از این کتابخونه، به یکی از محبوبترین و پراستفادهترین کتابخونههای هوش مصنوعی تبدیل شده (مثلا در پروژه خودران، من از این کتابخونه استفاده کرده بودم).
اما یک مشکل بزرگی با نصب تنسرفلو روی رزبری پای مواجه هستیم. مشکل اینجاست که وقتی دستور روتین pip برای نصب تنسرفلو رو بزنیم، اتفاق خیلی خاصی رخ نمیده، جز این که یک ارور مبنی بر پیدا نشدن این کتابخونه در مخازن PyPi متعلق به پلتفرم ما نشون داده میشه. پس باید چی کار کنیم؟ خب در ادامه قراره که همین داستان رو بررسی کنیم و به نتیجه درستی برسیم.
نصب Tensorflow روی Raspberry Pi
قبل از هرچیزی باید بگم که من این پروسه رو روی Raspberry Pi 4 Model B (با رم ۲ گیگابایت) و سیستم عامل Raspberry Pi OS نسخه Bullseye (بله درست حدس زدید، سیستمعامل رزبری پای دبیانه 😁 و صدالبته که میتونید توزیعهای دیگری هم روش نصب کنید) و ویرایش ۶۴ بیتی طی کردم. بسته به مدل رزبری شما و سیستمعاملتون، این پروسه میتونه متفاوت باشه.
نصب نرمافزارهای پایه
ما برای این که بتونیم تنسرفلو رو نصب کنیم، نیاز به نصب تعداد زیادی نرمافزار روی خود سیستمعامل داریم. به نظر بهتره که ابتدا، لیست بستههای مخازن رو بروزرسانی کنیم:
sudo apt update
و صدالبته بهتره که خود سیستمعامل هم بروزرسانیهای آخرش رو دریافت و نصب کنه:
sudo apt full-upgrade
پس از این که این مراحل انجام شد، تعداد زیادی نرمافزار رو به این شکل نصب میکنیم:
عمده این نرمافزارها رو بر اساس پیامهای خطایی که دریافت میکردم پیدا کردم، چرا که وقتی شما روی سیستم دسکتاپ یا لپتاپ خودتون تنسرفلو نصب میکنید، بسیاری از اینها (متناسب با معماری پردازنده) پیشتر نصب شدند اما سیستمعاملهایی که روی رزبری نصب میکنیم چنین حالتی ندارند. بهرحال، همه نرمافزارهای پایهای که نیازه از مخزن دبیان نصب بشه، در این دستور موجوده (طبیعتا اگر نیاز به بسته دیگری باشه بعدا این مطلب ویرایش میشه)
نصب و بروزرسانی بسته های پایتونی
خب ما تعدادی پیشنیاز پایتونی هم داریم (که اینها رو اکثرا حتی در وبسایت تنسرفلو هم میشه پیدا کرد) که با دستورات زیر نصبشون میکنیم:
توجه کنید که اگر این دستور کار نکرد هم جای نگرانی نیست، میتونید این لینک رو باز کنید و فایل رو خودتون دانلود کنید.
سپس کافیه که با اجرای این دستور:
pip3 install <TENSORFLOW WHL FILE>.whl
نصب رو انجام بدید.
ضمنا، از اونجایی که ممکنه بعدتر نسخهها تغییر کنن، بهتره که این صفحه رو هم هر چند وقت یه بار چک کنید تا اگر نیاز بود نسخه تنسرفلو رو تغییر بدید، فایل مربوطه رو دانلود کنید.
جمعبندی
مدتهای زیادی میشه که دوست دارم در مورد پروژههایی که در حوزه «اینترنت چیزها» یا همون IoT انجام میدم هم بنویسم. اما متاسفانه پروژههای سختافزاری، وقت زیادی از آدم میگیرن و وقتی وقت آزاد زیادی نداشته باشید، معمولا به پروژههای سختافزاریتون هم آنچنان نمیتونید رسیدگی کنید. به همین خاطر مدتی میشه که در تلاشم تا پروژههای شخصی و صدالبته کاریم در حوزه بینایی ماشین رو با IoT ترکیب کنم و به این شکل این حوزه رو هم وارد کارهای روتین و اصلیم کنم که وقت هم همیشه براشون باشه 😁
تست چند پروژه بینایی ماشین روی Raspberry Pi شروعی برای این دوران از زندگی منه. راستی، اگر دوست دارید نقشه راه بینایی ماشین رو داشته باشید میتونید بیایید اینجا، اگر دنبال ایده برای پروژهها هستید هم اینجا رو بخونید. حتی میتونید به ما در جامعه بینایی ماشین هم ملحق بشید و اشتراک تجربه و دانش کنید.
چندی پیش، در مورد پیشنیازهای یادگیری بینایی ماشین در همین وبلاگ نوشته بودم (لینک) و بعد از اون هم در مطلبی در ویرگول، در مورد این که چرا موجودیتی به اسم «جامعه بینایی ماشین» رو راه انداختم (لینک) صحبت کردم. پس از انجام چندین پروژه و تولید چندین محتوا پیرامون این موضوع، امروز در این پست قراره که ایده هایی که شما میتونید در پروژه های بینایی ماشین و پردازش تصویر خودتون به کار بگیرید رو بررسی کنیم.
توجه داشته باشید که در این پست، فرض رو بر این گذاشتیم که شما با هوش مصنوعی، پایتون، بینایی ماشین و … آشنایی لازم و کافی رو دارید و حالا قصد دارید یک پروژه جدی باهاش انجام بدید اما نمیدونید باید چی کار کنید. اگر آشنایی ندارید هم مشکلی نیست، میتونید این مطلب رو صرفا برای ایجاد علاقه و یا رفع کنجکاوی بخونید 😁
ایده های مرتبط با تشخیص چهره
تشخیص چهره، همیشه یکی از پرطرفدارترین شاخههای پردازش تصویر و بینایی ماشین بوده است. چرا که با استفاده از تشخیص چهره، میتوانیم عملیات جالبی انجام دهیم و پروسههای زیادی از یک کار بزرگتر را، خودکار کنیم. همچنین میتوانیم امنیت خانه و محل کار و … را نیز با استفاده از تشخیص چهره تامین کنیم.
در لیست زیر، تعدادی از پروژههای مرتبط با تشخیص چهره رو برای شما فهرست کردهام:
حضور و غیاب مبتنی بر چهره
دوربین امنیتی (به این شکل که وقتی شخص ناشناسی وارد حریم دوربین شد از طریق ایمیل یا SMS و … به شما اطلاع بده)
قفل هوشمند ( به شکلی که اگر شما رو دید در رو باز کنه و در غیر این صورت، یک سیستم مانند دزدگیر یا سیستم امنیت خونه رو راهاندازی کنه)
تشخیص حالت و احساسات چهره
تشخیص خوابآلودگی (مثلا در یک کلاس این پروژه میتونه کاربردی باشه).
همه ایدههای بالا، به سادگی قابل انجام هستند. فقط کافیه که کار با کتابخانهها و تئوری پردازش تصویر رو بلد باشید. شاید دو سه روزه بتونید یکی از این پروژهها رو به ثمر برسونید 😁
ایده های مرتبط با تشخیص کرکتر
تشخیص نوری نویسه یا Optical Character Recognition که به اختصار به اون OCR هم گفته میشه، یکی از شاخههای پرطرفدار دیگر در حوزه بینایی ماشین میتونه به حساب بیاد. پروژههایی که در این حوزه انجام میشن به شدت کاربردی هستند و طبیعیه که در حوزههای مختلفی کاربرد خواهند داشت. در اینجا تعدادی از ایدههایی که میتونید روش کار کنید رو اینجا فهرست کردم:
تشخیص و استخراج شماره پلاک (که پیشتر در موردش نوشتم – لینک)
تشخیص و حل مسائل ریاضی/فیزیک (که این هم پیشتر در مورد نوشتم – لینک)
تشخیص دستخط فارسی
تشخیص خط نستعلیق (و در کل خوشنویسی) فارسی
تشخیص نسخه پزشکی (نکته جالب اینه که در نسخ پزشکی، بسیاری از خطخطیهایی که میبینید در واقع روش مصرف و دوزاژ دارو هستند، که طبق کدگذاری خاصی نوشته میشن).
البته باید این نکته رو هم عرض کنم خدمتتون که دنیای OCR خیلی گستردهست. تقریبا هرجایی که شما با نوشتن سر و کار داشته باشید، میتونید از OCR هم اونجا استفاده کنید. خیلی چیزا اینجا به خلاقیت و نیازهای خودتون برمیگرده. اگر ایده دیگری داشتید، میتونید در بخش نظرات همین مطلب با من به اشتراک بذارید.
ایده های مرتبط با پزشکی
هوش مصنوعی در علم پزشکی، جایگاه خاصی در سالهای اخیر داشته. چرا که همه دانشمندان کامپیوتر و همچنین پزشکی، دریافتند که با استفاده از راهحلهای هوشمند، میتونند به حد قابل توجهی، خطاهای پزشکی رو کاهش بدند. همچنین تحقیقات دارو و واکسن هم به شدت سریعتر میتونن انجام بدند. برای مثال، همین دنیاگیری ویروس کرونا که در سال ۲۰۱۹ آغاز شد و کماکان ادامه داره رو بررسی کنیم، بارها از این که از هوش مصنوعی برای پیدا کردن ترکیبات دارویی موثر بر ویروس استفاده شده، صحبت کردند. همچنین در پروسه ساخت واکسن هم بسیاری از مراحل رو به ماشین سپردند و به هوش ماشینی اعتماد کردند. شاید یکی از دلایلی که واکسن این بیماری انقدر سریع ساخته شد، استفاده از همین راهکارهای هوشمند در تولید بوده.
بینایی ماشین هم استثناء نیست و طبیعتا میتونه خیلی به کمک افراد بیاد. در این بخش، تعداد زیادی از ایدههایی که میتونه به پزشکها در شناخت بهتر مشکلات بیمارهاشون کمک کنه رو فهرست کردم و خب بد نیست اگر شما هم سراغش برید و سعی کنید یکیش رو پیاده کنید (این بخش میتونه برای دانشجویان مهندسی پزشکی و پزشکی؛ بسیار مفید باشه)
تشخیص نوع تومور مغزی (تصویر این بخش، پروژهای که خودم انجام دادم)
تشخیص رتینوپاتی دیابتی در اشخاص مبتلا به دیابت
تشخیص MS و مراحل مختلف اون بر اساس MRI
تشخیص سلولهای سرطانی
تشخیص میزان درگیری ریه در بیماریهای تنفسی (مانند COVID-19)
تشخیص ناهنجاریهای پوستی
تشخیص آسیبهای استخوان
تشخیص آسیبدیدگیها و پوسیدگیهای دندان
طبیعتا اینها، همه کارهایی که میتونیم در حوزه پزشکی با کمک بینایی ماشین و پردازش تصویر انجام بدیم نیستن و این دامنه میتونه به شدت گستردهتر باشه. طبیعیه که گستردگی این دامنه به خلاقیت خودتون و نیازهاتون برمیگرده. همچنین طبیعتا اگر شما دانشجوی مهندسی پزشکی یا رشته پزشکی و رشتههای مرتبط باشید، احتمالا ایدههای بهتری خواهید داشت.
سایر حوزهها
چندین و چند حوزه دیگر هست که خب مثل باقی حوزههای پوشش داده شده در این مطلب، نمیشه ایدههای پروژههای بینایی ماشین و پردازش تصویرشون رو فهرست کرد. به همین خاطر، توضیح اجمالی راجع به هر کدوم میدم تا شما ببینید که کدوم حوزه رو بیشتر دوست خواهید داشت و در کدوم حوزه ممکنه بتونید ایدهپردازی بهتری داشته باشید.
تشخیص حرکت یا Action Detection
این حوزه به طور خاص، میتونه برای کارهایی مثل تشخیص و ترجمه همزمان زبان اشاره (لینک)، تشخیص حرکات ورزشی و یا تشخیص «نیت» افراد بشه. برای مثال، میتونیم سیستمی بسازیم که حرکات بعدی فرد در یک نبرد تن به تن (مثل مسابقه بوکس) رو پیشبینی کنه و به مربیها و نوآموزهای اون رشته اطلاع بده.
خودروهای خودران
خودروهای خودران یا Self-Driving که پیشتر هم ازشون در همین وبلاگ صحبت کرده بودم (لینک) میتونن با استفاده از بینایی ماشین و پردازش تصویر، تابلوهای راهنمایی، رفتار سایر رانندگان، موانع در مسیر و … رو تشخیص بدند. این حوزه البته پیچیدگی زیادی داره اما کار کردن روی بخشهای مختلفش میتونه برای یادگیری جوانب مختلف ماجرا جذاب و جالب و مفید باشه.
مصرف انرژی
حوزه انرژی هم حوزه جالبی میتونه برای پروژههای بینایی ماشین باشه. برای مثال OCR ای که بتونه دیتای کنتور گاز/برق رو به متن تبدیل کنه و اون رو با یک مرکز محاسبه قیمت، چک کنه و قیمت رو به ما اعلام کنه. همچنین میشه عکسهای حرارتی از خانهها و … تهیه کرد و با استفاده از بینایی ماشین دقیقا بررسی کرد که کجاها انرژی بیشتری داره از دست میره و … .
این پروژهها به خودی خود شاید جالب به نظر نرسن اما ترکیبشون با IoT و هوشمندسازی در سطوح دیگر، طبیعتا میتونه جذاب و حتی پولساز هم باشه.
کشاورزی
این هم گفتن نداره، شما کافیه که یک سری عکس هوایی از زمینهای کشاورزی داشته باشید. احتمالا خیلی راحت بتونید سیستمی توسعه بدید که آفات رو شناسایی کنه. همینطور میتونید نوع خاک و … هم از روی این عکسها طبقهبندی کنید و پیشنهاد بدید که چه محصولی در این زمین کشت بشه بهتره. در حوزه مصرف انرژی هم میتونید یکی از پروژهها رو بردارید بیارید اینجا و ازش بهرهبرداری کنید. چی از این بهتر؟
ضمن این که امنیت زمین کشاورزی و گلخانه، بررسی نور و رنگ و … هم میتونن اینجا کاربردی باشند.
جمعبندی مطلب
در این مطلب، ایدههایی که میتونید بعنوان یک پروژه تفریحی یا جدی پیادهسازی کنید رو بررسی کردیم. همچنین این ایدهها، به جز این که میتونن رزومه خوبی برای شما بسازند طبیعتا میتونن پایه یک کسب و کار و یا یک استارتاپ باشند که شانس خوبی برای به پول رسیدن داره. به همین خاطر هم ممنون میشم اگر هر کدوم از این ایدهها رو پیادهسازی کردید در بخش کامنت همین مطلب در موردش بنویسید و به من اطلاع بدید تا ببینم چه کردید.
همچنین لازم به ذکره که اگر دوست دارید مطالب فنی/علمی دیگری از من بخونید، میتونید به ویرگول من هم مراجعه کنید. در پایان هم بابت وقتی که گذاشتید، ازتون تشکر میکنم و امیدوارم در آینده باز هم بتونم در این وبلاگ، مطلب بنویسم.
دقیقا دو هفته پیش، در نسخه انگلیسی وبلاگ در مورد YOLOv5 نوشتم (لینک) و توضیح دادم که چرا این مدل هوش مصنوعی برای تشخیص اشیاء رو دوست دارم (و حتی چرا شما باید دوستش داشته باشید) و خب طبیعتا دوست داشتم یک پروژه خیلی خیلی ساده و در عین حال باحال هم با این مدل انجام بدم.
ایدههای زیادی در سر داشتم. برای مثال ایده بازی Red Light – Green Light که در سریال اسکوییدگیم همه دیدیم. اما این ایده علیرغم خوب بودنش، آنچنان کاربردی نبود. پس تصمیم من برآن شد که یک نرمافزار دیگر توسعه بدم. نرمافزاری که هم چالش داشته باشه، هم در نهایت یک کاربرد درست ازش بشه درآورد.
نمیدونم شما یادتونه یا نه، اما نرمافزار سیمبولب، دروانی خیلی خاص و معروف شد. به همین خاطر، تصمیم من هم این شد که سیمبولب رو دوباره بسازم و بعد از این که نتایج مورد نظرم رو گرفتم در موردش وبلاگ بنویسم. پس این شما و این ماجرایی که من داشتم تا این نرمافزار رو بسازم.
گام اول: طرح مساله
در هر پروژهای، اولین گام اینه که مطرح کنیم چه مشکلی رو باید حل کنیم. یا به قول دنیل کوهن Look for the pain. خب دردی که ما اینجا به دنبال حل کردنش بودیم، چی بود؟ این که بسیاری از دانشآموزا و دانشجوها سر ریاضی عمومی یا Calculus مشکل دارند. این مشکل ریشهش کجاست؟ برای من شخصا مهم نیست که این ریشه رو بررسی کنم (البته به معنای این نیست که نظری در موردش ندارم، اما از حوصله این مطلب خارجه).
حالا درد این که بسیاری از دانشجوها و دانشآموزها مشکل دارند، چطور میشه براشون یک مسکن خوب تجویز کرد؟ بعنوان یک مهندس هوش مصنوعی، یا بهتر بگم مهندس بینایی ماشین در ذهنم این ایده چرخید و اون این بود که:
یک نرمافزار هوش مصنوعی وجود داشته باشه که از روی عکس مساله، پاسخ نهایی یا راهحل رو به افراد بده.
و این پروژه، در نظر پروژه بسیار بسیار بزرگی بود اما در نهایت، پروژه سادهای شد. در ادامه، در راهی که طی شد توضیح خواهم داد.
گام دوم: انتخاب ابزار
گام دوم برای من، انتخاب ابزار بود. اول از همه میخواستم برم سراغ OCR های آماده برای تشخیص مسائل پارامتری مثل x و y و … . اما بعد دیدم که اینجا علاوه بر حروف و اعداد، نشانهها هم هستند. ضمن این که به شکلی باید توان و … هم تشخیص داد. پس کمی پروژه رو نگه داشتم تا به ابزارها فکر کنم.
بعد از مدتی تحقیق و تفحص، به دارکنت رسیدم که برای ترین کردن YOLOv3 و YOLOv4 استفاده میشه و خب دارکنت مشکلات زیادی هم با خودش به همراه داره. برای مثال کاملا در سیپلاسپلاس نوشته شده و روی سیستمهای مختلف باید از نو کامپایل بشه. با CPU درست کار نمیکنه. کامپایل کردنش روی مک یا ویندوز دردسره و انتقال دادنش به Google Colab هم میتونه تا حد زیادی مشکلساز بشه.
بعد از اون الگوریتم YOLOv5 رو کشف کردم. تقریبا همه مراحل کاملا پایتونی پیش میرفت و این عالی بود. کم کم دیدم که میشه بعد از ترین کردن قضیه، از pytorch هم استفاده کرد و اشیاء رو تشخیص داد و از اون بهتر این بود که در تشخیص اشیاء، میشد خروجی pandas هم گرفت که مختصات شیء مورد نظر به همراه لیبلش در اون data frame خاص موجود بودند. پس به این شکل تشخیص این که ما با چه چیزی روبرو هستیم هم سادهتر از گذشته میشد.
وقتی این ابزار رو با چند چیز مختلف تست کردم، نوبت این رسید که در این پروژه حتما ازش استفاده کنم. اما این تمام ماجرا نیست. دقیقا وقتی که سمت OCR ماجرا هندل میشد، یک بحث خیلی مهم میموند. بحث این که چطوری باید مساله حل بشه؟ برای حل مساله هم از Wolfram Alpha گفتم کمک میگیرم.
خب حالا نوبتی هم باشه، نوبت اینه که دادههای مورد نیاز رو جمع کنیم. قبلتر در مورد راههایی که شما میتونید برای جمعآوری داده استفاده کنید، صحبت کردم و میتونید از اینجا بخونیدش.
نمونه دادههای استفاده شده در این پروژه
گام سوم: جمعآوری داده
برای جمعآوری دادهها، نیازمند این بودم که روی چند سطح مختلف (وایتبرد، کاغذ A4 و همچنین کاغذ خطدار) و با چند دستخط مختلف، مسائل ریاضی رو بنویسم. بعد از نوشتن مسائل ریاضی، از دوستانم خواهش کردم که روی صفحات مختلف و همچنین وایتبرد، مسائل ریاضی رو بنویسند.
بعد از این که مسائل ریاضی رو روی این سطوح و با دستخطهای مختلف داشتم، نوبت عکاسی ازشون بود. از هر بار نوشتن، چندین عکس از چند زاویه گرفتم. چرا که زوایای مختلف باعث میشن توزیع نور هم در تصاویر یکسان نباشه و این خودش یک مرحله data augmentation رو برای من کاهش میداد.
حالا یه حجم زیادی داده دارم، باید بعدش چی کار کنم؟ پاسخ سادهست. الان زمانیه که ما وارد مرحله پیشپردازش داده میشیم.
گام چهارم: پیشپردازش داده
بعد از این که ما دادههای مورد نیاز خودمون رو جمع کردیم، نیازمند اینیم که داده رو پیشپردازش کنیم. به طور کلی، پیشپردازش داده به پروسهای گفته میشه که در اون قراره داده ها تمیز بشن، تغییر کنند (یا به قولی data augmentation رخ بده)، برچسب زده بشن و دادههای غیرلازم (یا همون نویز) دور ریخته بشه.
اولین مرحله برای من اینجا، تکه تکه کردن عکس بود. شاید فکر کنید که برای تکه تکه کردن عکس، از ابزار خاصی استفاده کردم یا کدی زدم. باید بگم که خیر، ابزارم دقیقا ادوبی فتوشاپ و ابزار Slice بود. بعدش با قابلیت save for web آمدم و عکسهای قطعهقطعه شده رو ذخیره کردم. پس از ذخیره نهایی عکسها، نیاز بود که عکسها برچسب زده بشن.
برچسبها، در مرحله آموزش مدل، به ما کمک میکنند که اشیاء رو در تصاویر پیدا کنیم. این برچسبها در مراحل بعدتر به کمک ما میان تا بتونیم مسائل یافت شده رو به ولفرامآلفا بدیم تا برامون حلش کنه. پس لازم بود که این اتفاقات بیفته.
گام پنجم: آموزش مدل YOLOv5
و اما گام یکی مونده به آخر دقیقا این بود که مدل آموزش داده بشه. آموزش این مدل با pytorch به شدت سرراست و راحته و کلش اجرا کردن یک دستور در ترمیناله. باز با این حال، مشکلات عدیدهای داشتم. برای مثال روی لپتاپ شخصی چون GPU مناسب نداشتم، آموزش به شدت طولانی میشد. آموزش رو به Google Colab منتقل کردم و چون پلن رایگان داشتم، اونجا هم یک سری داستان جدیدتر پیش آمد. اما بهرحال هرطور که شد، مدل آموزش داده شد و نتایج خوبی هم ازش گرفتم.
در مورد آموزش مدل و نحوه کار اون به زودی محتوای آموزشی جدیدی تولید خواهد شد که به تفصیل در اون توضیح میدم چطور میتونید YOLOv5 رو خودتون آموزش بدید و باهاش کار کنید. در حال حاضر، توضیح مراحل آموزش تا حد زیادی از حوصله این پست وبلاگ خارجه.
و گام نهایی: آزمایش مدل و نوشتن رابط ولفرام آلفا
پس از این که مدل آموزش داده شد، نیاز بود چندین خط کد پایتون نوشته شه برای چند منظور. اول این که وزنهایی که لازم بود از مدل آموزشدادهشده، لود کنه. دوم این که یک عکس رو از ورودی بگیره و مراحل inference رو روش انجام بده و در نهایت، اگر کاربرخواست اون رو بفرسته به ولفرام آلفا و مرورگر رو براش باز کنه.
برای این مرحله، برخلاف باقی مراحل وقت زیادی نذاشتم ولی با این حال کدش (بدون وزنها) در گیتهاب شخصی من موجوده و میتونید نگاهی بندازید. البته که به زودی گیتهاب بروزرسانی میشه و شما قادر خواهید بود که وزنها رو هم دانلود کنید. اما فعلا وزنها در دسترس نیستند.
در نهایت هم برای این که عملکرد قضیه رو ببینید، این ویدئو کوتاه رو میتونید تماشا کنید که هم inference رو تست میکنیم هم حل مساله با ولفرام رو:
جمعبندی و مشکلات این نرمافزار
این پروژه به عنوان یک پروژه تفریحی، واقعا تفریح خوب و سالمی بود و کلی یادگیری برای من داشت. یادگیری دقیقتر و عمیقتر YOLOv5، یادگیری دقیقتر و عمیقتر PyTorch و از همه مهمتر درگیر شدن با چند مساله و به قولی، دردهای دنیای واقعی. از نتیجه کاملا راضی بودم و هستم، اما فکر نکنم در آینده این پروژه خیلی برام راضیکننده باشه.
احتمالا بعد از مدتی به این پروژه برگردم و بزرگترین مشکلش – یعنی شباهت زیاد ورودیها به هم – رو طور دیگری هندل کنم. برای این که ببینیم یه چیزی در پوزیشن توان یه چیز دیگه قرار گرفته یه چارهای بیاندیشم و … . خلاصه که راه برای بهبودش زیاده و این بهبودها رو شخصا پیگیر هستم که در این پروژه اعمال کنم. شاید هم لازم باشه داده ورودی رو افزایش داد یا حتی مدل مورد استفاده رو عوض کرد.
در نهایت، از شما بابت وقتی که برای خوندن این مطلب گذاشتید، ممنونم. امیدوارم که این مطلب مفید واقع شده باشه و به دردتون خورده باشه. ضمن این که اگر به این تیپ مسائل و مطالب علاقمند هستید، میتونید من رو در ویرگول هم دنبال کنید و اونجا هم مطالبم رو بخونید. اگرچه در ویرگول عمده مطالبم مرتبط با بیزنس، موفقیت و ایناست.
در نهایت از شما خواهش میکنم که اگر این مطلب براتون مفید بود، یک قهوه به انتخاب خودتون مهمانم کنید تا موقع نوشیدن قهوه به یادتون باشم و از این دست مطالب، بیشتر تولید کنم.
در دو پست قبلی (+، +) در مورد پروژه جبیر با شما صحبت کردم و توضیح دادم که ایدهش از کجا اومد و چی شد و چه کردیم. قسمت دوم یکم پرش قلم من زیاد بود چون موضوعات زیادی رو شامل میشد اما خب نیاز بود که گفته بشه. حالا رسیدیم به قسمت آخر. در این قسمت، میخوام از این بگم که در جشنواره خوارزمی چه گذشت و چرا جشنواره خوارزمی شروعی بود بر پایان این پروژه.
بذارید قبل از هرچیزی، یک مرور کلی داشته باشیم بر دو قسمت قبلی. در قسمت اول، توضیح دادم که من شیفته اپل شده بودم و میخواستم مثل استیو جابز، یک شخصیت مهم در دنیای تکنولوژی باشم و همون قدر شناخته بشم و همونقدر هم ثروتمند (بالاخره آرزو بر نوجوانان عیب نیست، هست؟) و تصمیمم این شد که یک سیستم عامل بسازم و بعد از کلی تحقیق و توسعه؛ نتیجه این شد که یک سیستم عامل مبتنی بر گنو/لینوکس و توزیع اوبونتو بسازم. اسم این پروژه هم گذاشتیم جبیر.
در قسمت دوم، از فراز و نشیبهای فنی این قضیه گفتم. از این گفتم که چی شد که اینطوری شد و چی شد که ساخته شد. بذارید سادهتر و مفصلتر بگم، اول گفتم که فاز تحقیقم چی بود و چه کردم و چه چیزایی خوندم. بعد گفتم که چرا تصمیم گرفتم بیام سراغ سیستمعاملهای متنباز موجود مثل لینوکس یا BSD و در نهایت گفتم چرا لینوکس رو انتخاب کردم. بعدش از عادت Distro Hopping گفتم (این عادت یعنی که شما بیایید و توزیعهای مختلفی تست کنید و همیشه روی یک توزیع ثابت نمونید) بعدش هم گفتم چی شد که مینت و اوبونتو رو به عنوان مبنا در نظر گرفتم و چطور نسخههای اولیه جبیر ساخته شد.
بعد از اون، از انتشار جبیر و اشتباهاتی که در ساخت این پروژه شد نوشتم. بعد از این موضوع، وارد بحث نسخه ۴ که نسخه جنجالی جبیر بود شدیم (نسخهای که به اینترنت متصل نمیشد، به همراه نظر جادی و تبعاتش) و بعد از اون چه شد که به سراغ BSD رفتیم و همین موضوع هم مزید بر علت شد که جبیر روز به روز به پایان خودش، نزدیکتر بشه.
جشنواره خوارزمی
جشنواره خوارزمی، یک جشنوارهست که در سطوح مختلف (چه مقطع تحصیلی و چه تقسیمات جغرافیایی) برگزار میشه و یکی از اهدافش، اینه که به مخترعین و مبدعین و محققین جوان کمک کنه تا نتایج کارهاشون دیده بشه. مقام آوردن در این جشنواره، خودش یک سری امتیاز خاص به همراه داره که این امتیازات عبارتند از دانشگاه بدون کنکور رفتن (طبیعتا در رشتهای که پروژه/اختراع ارائه کنید) و معافیت سربازی و اینها. البته اینها مال اون زمان بود و الان نمیدونم چطور شده ولی فکر نمیکنم تغییری کرده باشه.
احتمالا اگر الان این رو خوندید و دبیرستانی هستید، براتون خیلی دغدغه شده که حتما در این جشنوارهها شرکت کنید، ولی خواهش میکنم که قبلش حتما مطلبی که اول این پست لینک شده رو یه نگاه بندازید. قدیمیه ولی ارزشش رو داره. خلاصه بگذریم؛ چیزی که اینجا مهمه اینه که شما بدونید اگر طرحتون به زعم داوران جشنواره واقعا خوب بیاد، امتیازاتی دریافت میکنید که میتونه شما رو به اهداف زندگیتون نزدیک کنه.
حقیقتا من از وقتی بچهتر بودم، بچههایی که به این جشنواره راه پیدا میکردند رو از تلویزیون و روزنامه و … دنبال میکردم، دلم میخواست روزی مثل اونها باشم. مادامی که در تهران در مقطع راهنمایی تحصیل میکردم خبری از این جشنواره برای دانشآموزان راهنمایی نبود (سالی که ما شرکت کردیم ولی بود) و همین امر، باعث شده بود که من با این تیپ جشنوارهها غریبه باشم. اما در دبیرستان اوضاع فرق کرد. ما این پروژه رو شروع کرده بودیم. بخصوص سال دوم دبیرستان که بودم، رضا باقرزاده عزیز هم به من پیوست و با هم پروژه جبیر رو پیش میبردیم.
یک روز، ما از مدیر مدرسهمون خواستیم که سالن اجتماعات مدرسه رو در اختیارمون بذاره و از بچههایی که اون ساعت خاص، بیکارن دعوت کنه که بیان و پروژه ما رو ببینن. این هم خودش یکی از حرکات «استیو جابز»گونه بود 🙂 خلاصه این اتفاق افتاد و از قضا، مدیر مدرسه هم خودش اومد در اون جلسه دورهمی حضور پیدا کرد. این قضیه برای ما خیلی خوب بود چرا که حسابی در چشم مدیر مدرسه، درخشیده بودیم.
اما این تمام ماجرا نبود …
روز بعد اون کنفرانس، مدیر مدرسه از من و رضا درخواست کرد که جزییات پروژه رو براش بنویسیم. من هم یک صفحه A4 نوشتم تحویلش دادم. یک هفته بعد، ما رو از سر کلاس (که اگر اشتباه نکنم دینی بود) خواستند به دفتر. ما اول کمی ترسیده بودیم (بهرحال سیستم آموزشی ما ایجاب میکنه که از دفتر بترسیم 😂) و وقتی رفتیم، دیدیم یک آقای میانسالی هم اونجا هستند. مدیر مدرسه به ما گفت که ایشون از مسولین آموزش و پرورش استان هرمزگانن و پروژه ما در مرحله استانی خوارزمی پذیرفته شده.
ایشون گفت که روز بعدش، بریم پیشش. پرسیدیم بعد مدرسه؟ گفت نه، از مدیرتون اجازه بگیرید و دو زنگی رو ما در خدمتتون هستیم. ما هم از این بابت خوشحال شدیم. میدونید چرا؟ چون بالاخره دو زنگ پیچوندن هم خودش صفای خودش رو داشت. حالا از این حال و هوا بیاییم بیرون. ما فرداش رفتیم پیش ایشون. ایشون ما رو برد پیش مسولین خوارزمی و کلی تحویلمون گرفتند. این تحویلگیریها البته دلیل داشت! دو سه سالی بود که از استان هرمزگان در رشته کامپیوتر هیچ پروژهای معرفی نشده بود و اینها هم از این موضوع حسابی خوشحال بودند.
خلاصه که این دوستان، به ما گفتند یک A4 کافی نیست و در قالب یک پرپوزال باید در مورد پروژه بنویسیم. من و رضا هم گفتیم پس ما میریم روی این کار میکنیم و میآییم پیش شما. اون خانمی که در آموزش پرورش به ما گفت که بعدا بریم پیشش، گفت که چهارشنبه ها عصر هم حضور داره در همون دفتر و نیازی نیست کلاس رو بخاطر قرار با ایشون بپیچونیم. خلاصه کلام که ما رفتیم و یک فایل ۲۰-۳۰ صفحهای با عنوان «سیستمعامل جبیر» نوشتیم و این رو پرینت کردیم و در طلق و شیرازه قرار دادیم و چهارشنبه بردیم پیش ایشون.
بعد از کمی بررسی، غلطهای این پرپوزال رو به ما گفت و ما اون رو اصلاح کردیم. بعدش به ما گفتند که تا تیرماه حدودا صبر کنیم (و این ماجرا حدودای فروردین اتفاق افتاد اگر درست یادم باشه). ما هم به درس و مشقمون رسیدیم و امتحان دادیم. اما خب اینجا یک سری اتفاق خاص هم افتاد.اتفاقاتی که به نوبه خودشون جذاب و جالب بودند.
جشنواره خوارزمی استانی
جشنواره استانی، برخلاف کشوری، اینطوری نیست که شما بری از پروژه دفاع کنی. بر اساس همون توضیحاتی که از پروژهها ارائه شده، داوری میکنند و اونایی که حس میشه شانس خوبی برای مقام کشوری آوردن دارند انتخاب میشن. بعد از این، این مورد به صاحبان ایده و پروژه، ابلاغ میشه.
در همین حین، ما که سخت مشغول کار روی جبیر بودیم و حتی یادمه که دونفری با رضا میرفتیم پیش خدمات کامپیوتریها که مجابشون کنیم که یکی دو تا سیستم بدن دست ما که روش جبیر نصب کنیم (شاید باورتون نشه ولی یکی از پلنهای من، برای هر توزیعی که درش نقشی داشتم تولید کامپیوترهای رومیزی با همون سیستمعامل هم بوده) و معمولا اونها هم یه چراغ سبز الکی نشون میدادن، یک باره به تلفن رضا زنگ زدند. رضا گفت «آقای …؟» و بعد گوشی رو روی اسپیکر گذاشت و به ما اعلام شد که در استانی، رتبه اول شدیم (لینک خبر).
در مورد تاریخ خبر باید به شما بگم که این اخبار، بعد از برگزاری جشنواره کار شدند. یعنی ما تیر ماه خبر داشتیم از این که در استانی پذیرفته شدیم ولی ظاهرا قوانینی که روی جشنواره حاکمه، ایجاب میکرد که تا زمان شروع جشنواره سال بعد خبری ازش کار نشه. خلاصه بگذریم. ما دو تا هم خوشحال و سرخوش گفتیم که فرداش میریم آموزش پرورش.
در آموزش و پرورش، بیش از گذشته تحویلمون گرفتند! این بار به ما گفتند که نیازه تا فیلمی بگیریم که هردو توش باشیم (البته ما دو فیلم مجزا گرفتیم. چرا که رضا بیشتر روی جنبه UI و ظاهری قضیه کار میکرد و من روی بیس سیستم) و بعد یک پرپوزال دیگر بنویسیم که یک سری ملاحظات خاص رو درش رعایت کرده باشیم. این ملاحظات شامل نحوه فهرستبندی، استفاده از فونت و … بودند. خلاصه ما دوتا CD و یک کتابچه تحویل دادیم و بعدش مدت نسبتا طولانی، از هم دور شدیم.
جشنواره خوارزمی کشوری
مرداد ماه بود و من به همراه مادرم چند روزی (فکر کنم دو هفته!) آمدیم تهران. در همین روزها، یادمه که رضا به من زنگ زد. بهش گفتم چه خبر؟ چه کارا میکنی؟ و خیلی عادی حرف زد. برای من این موضوع خیلی جالب بود که چطور تونسته بود اونقدر خونسرد باشه و یهو من رو غافلگیر کنه :)) پای تلفن به من گفت که «فلانی زنگ زد و گفت که اوایل شهریور باید تهران باشیم که از پروژه دفاع کنیم.
خلاصه بعد برگشت من به بندر، قرار شد با رضا بریم و در مورد این پروسه بپرسیم. به ما گفتند که داورا اینطورین و باید چه کنید و … (که با تقریب خوبی البته درست نبود) و به ما پولی دادند که بلیت هواپیما تهیه کنیم و با هواپیما بریم تهران. همچنین بودجهای به ما دادند که لباسهای متحدالشکل تهیه کنیم و ما هم دوتا پیراهن گرفتیم که لعنت خدا هم گرونش بود، ولی سال ۹۱ بابت هر پیراهن ۶۰ هزار تومان پول دادیم 😂.
خلاصه ۵ شهریور ۹۱ شد. ما رفتیم فرودگاه بندرعباس و سوار یک عدد ایرباس A300 هواپیمایی ماهان شدیم و به سمت فرودگاه مهرآباد تهران پرواز کردیم. در تهران هم مسول آموزش و پرورش هرمزگان (همون آقای میانسالی که کارهای ما رو انجام داده بود) آمد و ما رو به خوابگاه دانشجویی دانشگاه تربیت دبیری شهید رجایی برد. حقیقتا تا حد خوبی حالمون گرفته شد، چرا که به ما گفته شده بود برای ما هتل رزرو شده و از این دست چرت و پرتا. ولی خب ایرادی نداشت، فرداش روز بزرگی بود.
فرداش رفتیم. ظهر شد و دعوت شدیم که بریم داخل اتاق. داخل اتاق، سهتا آقا نشسته بودند که علیالظاهر، اساتید کامپیوتر همون دانشگاه بودند (اینجا این رو بگم که بعدا روش بحث صورت بگیره، اگر جشنواره خوارزمی یک جشنواره کشوریه، آیا بهتر نیست که فراخوانی زده شه و از اساتید و صاحبنظران کل کشور خواسته شه که داوطلب بشن؟ چرا فقط یک دانشگاه خاص؟) و یک سری سوال پرسیدند. ما وقتی داشتیم صحبت میکردیم و …؛ من اشاره کردم که جبیر مبتنی بر گنو/لینوکس ساخته شده. یادمه یکی اونجا خندید و گفت «پس مثل همون لینوکس فارسیهست…».
حالا شما خودتون حساب کنید که این که این دوستان زده بودند تو کانال مسخرهبازی، چقدر به ما فشار آورد. خلاصه ما ارائه و دفاعمون رو تحویل دادیم و آمدیم بیرون. ناهاری بر بدن زدیم و کمی تهرانگردی کردیم و بعدش هم رفتیم سمت فرودگاه. دقیقا یادمه بعد از این که مسول آموزش پرورش ما رو ترک کرد، ما کاری نداشتیم که انجام بدیم پس با رضا نشستیم به خوندن آموزش Bash و اسکریپتنویسی 😁
خلاصه به سمت بندرعباس برگشتیم و بعد از اعلام نتایج، فهمیدیم که رتبه قابل قبولی در این جشنواره کسب نکردیم. این خودش یک شکست بسیار بسیار بزرگ برای ما محسوب میشد. گرچه کادر مدرسه تاکید داشتند سال بعدش هم شرکت کنیم ولی حقیقتا ما سال بعد تصمیم داشتیم دیگه شرکت نکنیم و همین هم شد. این دقیقا اینجا به این معنا بود که پروژه هم داره تا حد خوبی به آخرای خودش نزدیک میشه.
رفتن روی BSD، بزرگترین اشتباه
هنوز که هنوزه، من سیستمعامل FreeBSD رو به شدت دوست دارم و محاله وقتی نسخه جدید میده، نصبش نکنم و باهاش کمی بازی نکنم. اما حقیقت امر این بود که BSD ها – به جز مک – واقعا برای استفاده دسکتاپ و روزمره مناسب نیستند. حتی روی سرور و روتر و … (که BSDها حرفهای به شدت زیادی برای گفتن دارند) هم معمولا انتخاب خوب و اول نمیتونن باشند.
یکی از مهمترین دلایل، اینه که BSDها معمولا ساپورت سختافزاریشون اونقدری که باید و شاید، خوب نیست. دلیل دیگری که به ذهنم میرسه اینه که استفاده از BSDها به شدت محدوده و بین هزاران شرکت و استارتاپی که مبتنی بر لینوکس هستند، شاید فقط Netflix, WhatsApp و Sony باشند که از FreeBSD (یا نسخههای دیگر BSDها) استفاده کنند. همین امر، باعث شده که BSDها مستندات کمتر و جوامع کوچکتری داشته باشند.
و البته اشتباه دیگری که داشتم این بود که فکر میکردم اگر برم روی BSD و یه بخش خوبی از رابط کاربری هم خودم بسازم (که تاحدی این کار رو کرده بودم) و مجوز اون هم BSD قرار بدم، شاید بتونم کد رو ببندم. اما هیچ کس نبود بهم این نکته رو گوشزد کنه که بستن کد برای پروژهای که تیم کوچکی داره و ساپورت مالی نمیشه و سرمایهگذار خاصی هم نداره، سم مطلقه.
خلاصه با پیادهسازی نه چندان بد، تفکرات اشتباه و صد البته واکنشهای عجیب و غریب جوامع نرمافزار آزاد و متنباز ایران، این پروژه باز بیشتر و بیشتر روی سراشیب سقوط قرار گرفت. اما حقیقت امر اینه که یکی از بزرگترین تیرهای خلاص این قضیه رو، همین جامعه نرمافزار آزاد به این پروژه وارد کرد.
واکنشهای جامعه نرمافزار آزاد ایران و پیامدهایش
من اصلا دوست ندارم در نقش قربانی فرو برم و شکستها و عدم موفقیتم رو گردن کسی بندازم. حقیقتا از این رفتار به شدت بدم میاد و اگر ببینم کسی چنین رفتاری داره خیلی سریع، از دایره دوستی و حتی آشنایی من ممکنه حذف بشه. پس امیدوارم این بند خاص از مطلب من، این حس رو القاء نکنه که در نقش قربانی فرو رفتم.
بگذریم، جامعه نرمافزار آزاد ایران، که در حال حاضر عمدتا حول اوبونتو و در فروم اوبونتو متمرکز شده تقریبا (و این تمرکز هم خودش سم مهلکیه) رفتارهای عجیب و جالبی دارند. این جامعه عموما اینطوری بود که خیلی سخت افرادی که بیرون گود بودند رو میپذیرفت و خیلی وقتها هم نمیتونستند یک سری موضوعات خاص رو بپذیرند. به همین دلیل، رفتارها بیشتر شبیه گنگسترها و یاکوزاها میشد. حقیقتا در مقابل پروژه جبیر هم تا حد زیادی به این شکل برخورد نشان دادند.
برخوردهایی از این دست که «چرا به فلان پروژه کمک نمیکنی؟» اصلا از نظرم بد نیست. خیلی هم خوبه و خیلی راحت میتونه شما رو مجاب کنه که نیاز نیست چرخ رو از اول اختراع کنید. اما خب، گاهی برخوردها سمت ترولینگ و قلدری سایبری پیش میرفت. مثلا شخصی میومد میگفت «بیا کرنل رو بکن داروین» و بعد چند نفر ادامه میدادند. نکته جالب هم این که از سادگی من هم به عنوان یک نوجوان، تا حد خوبی بهرهکشی شده بود اینجا. من الان دانشی دارم که بهم میگه که تعویض کرنل بسیار سخته، و در بعضی موارد کاملا ناممکن. اما اون موقع من چنین آگاهیای نداشتم.
خلاصه بگم که کم کم به جایی رسید که من دیگه میفهمیدم کجاها ملت دارند دستم میندازن. حقیقتا خوشم اومده بود که خودم همراه شم با این قضیه و تا میتونم چرت و پرت ببافم. اما خب حقیقتا این به ضرر من شد چرا بعدتر، برچسب ترول به من چسبید و از جامعه کاملا پاک شد. جامعهای که تقریبا همیشه نشون داده با افراد جدید – صرفنظر از این که آدمهای خوبین یا بد – چنین برخوردی رو داشته و خب این برخوردها، نتایج خوبی هم نداشته. برای مثال، خود من از سال ۹۳ تا ۹۶ واقعا در این جامعه هیچ حضور فعالی نداشتم و ۹۶ دوباره برگشتم بهش. سال ۹۹ هم موارد مشابهی پیش آمد و دلخوریهایی ساخته شد.
خلاصه بگذریم از این موضوع، میخواستم صرفا این موضوع رو شفاف کنم که جامعه، از دور ممکنه قشنگ به نظر برسه اما خب درونش نیازمند سازگاری بالا و همرنگ جماعت شدنه. حقیقتا من هم شخصی نیستم که بخوام همرنگ جماعت باشم، به همین خاطر ممکنه در جوامع مختلف، متضرر بشم 😁
سخن آخر
اول از همه از شما ممنونم که این مطلب رو خوندید و تا اینجا اومدید. دوم، میخوام ازتون دعوت کنم که علاوه بر این وبلاگ، ویرگول هم میتونید مطالب من رو بخونید ولی در ویرگول معمولا انقدر حرافی نمیکنم 🙂 و در نهایت، میخوام یک جمعبندی کلی روی این سه قسمت بکنم و بگم که به پایان آمد این دفتر، حکایت همچنان باقیست.
حقیقتا بعد از شکست پروژه جبیر، من یک درس بزرگ گرفتم. درسی که بهم گفت «نیاز نیست استیو جابز دوم باشی، تو خود خودت باش» و این درس به نظرم بزرگترین نکته شخصیتی بود که میتونستم از انجام چنین پروژهای دریافت کنم. درس و نکته بعدی هم این بود که حرفهای اطرافیان میتونه به شدت روی روان آدم تاثیر بذاره و نباید گذاشت این حرفها، از ما یک موجود کینهای بسازه که بعدتر نیازمند انتقامگیری و پروندهسازی و فلان باشه. درسهای شخصیتی و روانی این پروژه، واقعا برای من مهم و ارزنده بودند.
از نظر فنی هم، درسهای خوبی گرفتم. برای مثال اندازه افرادی که LPIC 1, 2 میگذرونند از لینوکس یاد گرفتم. تا حد خوبی پایتون یاد گرفتم. حتی همین امر باعث شد که بعدتر، روبی یاد بگیرم و … . همچنین یاد گرفتم که نیاز نیست برای متفاوت بودن حتما به سمت BSD رفت بلکه یک رابط کاربری متفاوت هم میتونه به خودی خود، تا حد خوبی تاثیر مثبت روی ذهن افراد داشته باشه.
از منظر بیزنسی هم بخواهیم نگاه کنیم یک درس خیلی خوب گرفتم. اون این که «وقتی تیم کوچیکه یا پروژه تکنفره جلو میره نیازی نیست که کد، بسته باشه. اتفاقا باز بودن کد به نفع توئه». و همین باعث شد از اون به بعد عمده پروژههای من روی گیتهابم قرار بگیرند.
خلاصه که یک پروژه شکستخورده، میتونه پر از درس برای ما باشه. مهم اینه که ما بخواهیم همیشه در سوگ بمونیم؟ یا این که به قدری سوگواری کنیم و بعد از اون سوگواری به سمت انجام یک پروژه جدیدتر قدم برداریم. نمیدونم فیلم Whiplash رو دیدید یا نه، اما در صحنهای یکی از شخصیتها میگه «چارلی پارکر وقتی با اون صحنه مواجه شد، اول سوگواری کرد. بعد یک روز کامل استراحت کرد و بعدش اونقدر تمرین کرد که ما امروز ازش حرف بزنیم». پس باید گفت که این ماییم که انتخاب میکنیم چارلی پارکر باشیم، یا اون نوازندهای که با یک شکست، کلا ساز و نوازندگی رو میذاره کنار.
در پایان، مجددا از شما بابت وقتی که برای خوندن این مطلب گذاشتید تشکر میکنم. همچنین امیدوارم که این تجربه شکست طولانی، تونسته باشه برای شما جرقه یا کمکی باشه در هندل کردن پروژههاتون یا حداقل بهتون کمک کرده باشه که چطور با پروژههای شکست خورده کنار بیایید. امیدوارم که در آینده نزدیک، بتونم با مطالب بیشتری در خدمت شما باشم.
در مطلب پیشین (لینک) اشاره کردم که ایدهها و جرقههای ابتدایی پروژه جبیر، از کجا به ذهنم رسید و چرا مهم بود که اون ایده رو پیاده کنم و حتما به اون هدف برسم. این موضوع، باعث شد که من بیش از پیش تلاش کنم که به هدفی که برای خودم گذاشتم برسم.
در این یکی مطلب، قصدم اینه که در مورد فرایندی که جبیر برای ساخته شدن طی کرد صحبت کنم و قطع به یقین، خیلی از این مراحل قدیمیتر از اونی هستند که شما بتونید الان پیادهسازیشون کنید. پس اگر نیازمند این هستید که توزیع لینوکسی مبتنی بر دبیان یا اوبونتو بسازید، میتونید راهنمای عملی قرار دادن فیل در یخچال و همچنین چگونگی ساخت توزیع لینوکس رو بخونید. ولی اگر دوست دارید سفر طولانی یک نوجوان در مسیر پیادهسازی رویاش رو بدونید، به خوندن همین مطلب ادامه بدید.
بررسی راههای ساخت یک سیستمعامل
ابتدای راه، باید بررسی میکردم که سایرین چطور سیستمعامل ساختند و چطور شده که سیستمهای عاملشون، رشد و نمو خوبی داشته. همونطور که در قسمت اول هم اشاره کردم، یکی از idol های من در زندگی، استیو جابز بود (و کماکان هم هست) و طبیعتا اولین سیستمعاملی که به نظرم اومد که داستان موفقیتش رو مطالعه کنم، مک بود. اما مک یک مشکل بزرگ داشت. بررسی درست و حسابیش نیازمند این بود که حتما یک سیستم اپل تهیه کنم. حالا چه آیمک، چه مکبوک و … . به همین خاطر، مک رو بیخیال شدم.
داستان موفقیت ویندوز هم تقریبا اظهر من الشمسه. این سیستمعامل عمده محبوبیتش رو به این خاطر داره که روی سیستمهای سازگار با PC های IBM نصب میشد و از قضا، همون دوره IBM تصمیم گرفته بود که لایسنس تولید کامپیوترهای شخصی مشابه کامپیوترهای خودش رو به کمپانیهای دیگری مثل Dell, Compaq, HP و … هم بفروشه. پس تعداد بیشتر، مصادف شده بود با مصرف بیشتر و محبوبیت بیشتر.
نهایتا، با خودم گفتم که «خب، میرم بین محبوبیت توزیعهای لینوکس جستجو میکنم». اونجا بود که فهمیدم چندین توزیع ایرانی مثل پارسیکس (متوقف شده)، کارآمد (متوقف شده) و آریوس (متوقف شده) وجود دارند. در عین حال، فهمیدم اینها ویژگیهای مشترک زیادی دارند. خلاصه که این مورد رو گذاشتم در لیست مطالعه که بعدتر در موردش مطالعه کنم و ببینم که دنیا دست کیه.
خلاصه، مطالعه پیرامون موفقیت سیستمهای عامل تموم شد. دلم میخواست اون موقع وارد جامعهای از برنامهنویسان بشم و ازشون یاد بگیرم و انتقال تجربه انجام بشه. به همین خاطر، در وبسایت برنامهنویس، ثبتنام کردم. اونجا بود که متوجه شدم یکی از اعضا، یک سیستم عامل نوشته به اسم آراکس. برخلاف عمده پروژههای سیستمعامل که دیده بودم، این یکی توزیع لینوکس نبود بلکه سیستمعاملی بود که از بیخ و بن توسعه داده شده بود و با خودم گفتم که پسر! باید با این رفیق شم حتما. اما خب نشد، یعنی نمیدونم چی شد ولی احتمالا شلوغی سر ایشون و عدم تمایلشون باعث این شد که دوستیای شکل نگیره.
خلاصه، کمی هم به زبان انگلیسی گشتم. اون موقع مثل الان زبانم خوب نبود و در فهم بسیاری از مطالب، مشکل داشتم. با این حال با گشتن در اینترنت به ویکی توسعهدهنگان سیستمعامل رسیدم. جایی که هزاران و دهها هزاران نفر دیگر، مشغول توسعه پروژههای خودشون بودند و همین باعث شده بود که من یک بهشت برین پیدا کنم. اما اونقدری نگذشت که امیدم ناامید شد. چرا؟ چند مدخل رو که خوندم فهمیدم از صفر نوشتن یک سیستمعامل که بتونه کلی کار ریز و درشت انجام بده به این سادگیها هم نیست. که البته اگر نظر خودم رو بخواهید، خیلی خوب شد که این اتفاق افتاد. بعدا در موردش حرف خواهم زد.
به همین خاطر، یک تحقیق بزرگی در مورد سیستمعاملهای متنباز موجود کردم که ببینم کدوم بعنوان پایه سیستمعامل میتونه گزینه خوبی باشه. گنو/لینوکس، بیاسدیها، هایکو و حتی کولیبری رو چک کردم و به این نتیجه رسیدم که خب، لینوکس بهترین گزینهست! حتی در این میان داشتم به اندروید هم فکر میکردم ولی باز پس ذهنم گنو/لینوکس رو داشتم. حالا وقت این بود که ببینم از کدوم یکی میشه یک نسخه شخصیسازیشده بهتر ساخت.
پیدا کردن توزیع مناسب به عنوان مبنا
خب وقتی که فهمیدم قراره بیس سیستمعامل من لینوکس باشه، نیاز داشتم که ببینم کدوم توزیع بهتره. به همین خاطر بارها و بارها، توزیع عوض کردم (و حتی همین امر موجب این شد که هاردم به شدت کند و حتی خراب بشه. بعد از مدتی حتی مجبور به تعویض هارددیسک لپتاپی شدم که اون زمان داشتم). نخستین توزیع، اوبونتو بود. بعدش دبیان. بعد اوپن سوزه، فدورا و … . به همین سبک و سیاق هزاران توزیع رو تست کردم که ببینم کدوم بهتره. البته دروغ چرا، هزاران خیلی مبالغهست. درستترش اینه که هر توزیعی که اسم و رسمی داشت رو نصب و آزمایش کردم که ببینم قضیه چی به چیه.
اما مشکلاتی هم در این میان بودند. یکی از بزرگترین مشکلات پیش روی من، اینترنتی بود که اون زمان داشتیم. اینترنت پرسرعتی بود نسبتا اما دو مشکل اساسی داشت. اولین مشکل محدودیت حجمی بود و خب طبیعتا میدونید که بسیاری از این توزیعها حتی موقعی که نصب میشن هم نیازمند اینترنت هستند و همین یعنی باید فاتحه اون حجم رو خوند. مورد دوم هم قطعیهای زیاد اون خط خاص بود. خلاصه که با تمام این ماجراها، من تهش به چند کاندیدای قدر قدرت رسیدم.
اولین کاندیدا، خود دبیان بود. اصل کاری، پدر اوبونتو. دبیان نصب و راهاندازیش هربار من رو پیر میکرد البته. به همین خاطر ترجیح دادم که مدتی کنارش بذارم. در همین میان، باز به اوبونتو برگشتم. بعد از بازگشتم به اوبونتو، با لینوکس مینت آشنا شدم. حقیقتا از مفهومی که مینت داشت هم خوشم اومد! فهمیدم که مطابق قوانین خیلی از کشورها، یک تعداد زیادی از نرمافزارها مثل فلشپلیر، فونتهای مایکروسافت، کدکها، واین و … امکان «بازتوزیع» یا Redistribute شدن ندارند. اما مینت از این قاعده مستثناء بود. چطور؟ مینت در ایرلند جنوبی ساخته شده. کشور ایرلند هم مثل روسیه و کشور ما، از کشورهاییه که کپیرایت درش به اون شکل مطرح نیست و شما احتمالا راحتتر میتونید این تیپ بازتوزیعها رو انجام بدید.
وقتی دیدم اینطوریه، با خودم گفتم چرا پایه این قضیه مینت نباشه؟ به همین خاطر مینت نصب کردم تا ببینم چی به چیه و دروغ چرا؟ عاشقش شدم. روی مینت گنوم ۳ نصب کردم و کلی باهاش کار کردم و دیدم عجب چیز خوبیه. خلاصه اینجا بود که کاندیداهای من به مینت و اوبونتو، تقلیل پیدا کردند.
پیدا کردن راهی برای پکیج کردن مجدد توزیع شخصیسازی شده
اینجا دیگه روی لپتاپ مینت نصب کرده بودم. شخصیسازیهای مختلفی رو روش انجام داده بودم و وقتش رسیده بود که یک پکیج ازش بسازم. در واقع میخواستم یک ISO بسازم که بتونم بعدا روی لپتاپ خودم یا کامپیوترهای دیگر به طور کل، نصبش کنم. به همین خاطر از Relinux استفاده کردم (این پروژه تقریبا دو سالی میشه که از رده خارج شده، ولی اون موقع جوان اول ابزارهای ساخت توزیع بود). حالا وقت این رسیده بود که یک مینت خوش رنگ و لعاب با هزاران هزار بسته رنگارنگ، به ISO تبدیل بشه و همین تبدیل همانا و سیستمعاملساز شدن من همان!
اما اینجا یه مشکلی پیش اومد. انقدر نرمافزارها زیاد بودند که حجم ISO تولیدی توسط Relinux بالای ۴ گیگابایت رفت. اگر این پست رو تشریف ببرید بخونید، توضیح دادم که استاندارد ISO9660 یک محدودیت روی حجم داره و بیش از چهار گیگابایت رو نمیتونه در خودش جای بده. همین امر، باعث شد که پروژه رو بکوبم و از اول بسازم. به همین خاطر، دوباره DVD اوبونتو 11.10 رو برداشتم (و در همون حین نخستین بتاهای ۱۲.۰۴ هم داشتند میومدند) و روی لپتاپ نصبش کردم. پس از نصب، تغییراتی روش دادم مثل جایگزینی یونیتی با گنوم، نصب تعدادی نرمافزار و جایگزینی تعداد دیگر. این بار شد! این بار واقعا شد و خب خوشحال و خرم بودم.
عکس از توزیع کاپریس است – کاپریس در سال ۹۹ ساخته شد.
انتشار نسخه اول به صورت LTS و اولین اشتباهات
خب در فروردین سال ۱۳۹۱، نخستین نسخه جبیر آمد. یادمه که ده روز قبل از انتشارش حتی این پست رو در فروم اوبونتو ایجاد کردم که خب همونطور که میتونید بخونید؛ کم هم حاشیه نداشته. خلاصه اینجا بود که اولین اشتباهات رو متوجه شدم. در این قسمت بیش از این که بخوام پیرامون این که جبیر چه بود مانور بدم، میخوام روی اشتباهات مانور بدم.
اولین اشتباه شاید برمیگشت به جهانبینی من. اینطور بخوام بگم که این جهانبینی این طور بود که اگر در ۱۶ سالگی یک سیستمعامل مثل جبیر ساختم، دیگه ته دنیای تکنولوژی و اینام. به قول یه بندهخدایی، دچار سندرم «جلوزدگی از خود» شده بودم. خب این مورد در سنین نوجوانی طبیعیه و حتی همین الان باور دارم که نسبت به سن و سال اون زمانم، واقعا کارم خفن بوده ولی نه اونقدری که خودم همیشه فکر میکردم. بهرحال در دوران نوجوانی خیلیها دوست دارند کارهای بزرگ کنن و همونطور که در مطلب پیشین عرض کردم، این قضیه باعث شد من بشم اینی که الان هستم.
خلاصه این اشتباه، اشتباه اول بود. اشتباه دوم این بود که فکر میکردم اینجا میتونم سبک و سیاق اپل رو پیش بگیرم. یعنی چی؟ یعنی که یک سیستمعامل مبتنی بر یک سیستمعامل دیگر بسازم و بعدش، کدش رو ببندم و نهایتا سختافزارهای مبتنی بر اون سیستمعامل رو به ملت بفروشم. نه روی زیرساخت فکری داشتم، نه روی این که پروانهها چه اجازههایی میدند. خلاصه که اینجا کلی اشتباه پشت هم دیدیم. اما تلاش کردم این موارد رو در نسخه ۲ اصلاح کنم.
نسخه ۲، رابط کاربری افسانهای
توزیع آریوس، علاوه بر این که ریمستر از اوبونتو بود دو ویژگی داشت که از سایر توزیعهای ریمستر؛ متمایزش میکرد. یکیش نصاب آفلاین درایورها بود، دیگری این که یک رابط کاربری خیلی خوشگلی هم داشت که خب به شکل یک نشست روی گنوم اجرا میشد. در نسخه دوم تصمیم گرفتم چنین تغییری رو ارائه بدم. به همین خاطر، با کمک AWN, Mutter و یک سری تغییر ریز دیگر، یک رابط کاربری نسبتا کاستوم ساختم و اسمش هم گذاشتم Legendary UI یا «رابط کاربری افسانهای». همچنین در کنار اون نسخه، یک ایزو با XFCE هم ارائه کردم که خب در این مقطع، جبیر با دو میز کار داشت عرضه میشد.
حقیقتا نسخه ۲ تا حد خوبی ترکوند. به حدی که با این پروژه به جشنوارههای استانی و کشوری (منجمله خوارزمی) راه پیدا کرده بودم. این رو هم اینجا بگم چرا که واقعا نمیتونم این رفرنس رو اینجا ندم 😁 در فیلم The Social Network – که داستان ساخت و رشد فیسبوک رو به شکل سینمایی روایت میکنه – کرکتر Divya Narendra (یکی از شرکای دوقلوهای وینکلواس در پروژه Harvard Connection) در مورد مارک زاکربرگ میگه که «مارک بزرگترین شخصیت دانشگاه شده بود. اون هم دانشگاهی که نوزدهتا برنده نول و پونزدهتا برنده پولتیزر و حتی یک ستاره سینمایی داره». حقیقتا در میان دانشآموزان اون مدرسه و حتی شهر بندرعباس من چنین حسی داشتم و همینجا بود که دوباره کمی از خودم جلو زدم. اما این تمام ماجرا نبود. جزییات این بخش رو، در قسمتهای بعدی این داستان خواهیم خوند.
نسخه ۳ و ۴، مشکل اینترنت و متاع خنده؟
در نسخه ۳، تغییر خاصی نبود جز این که قبل از این که Ubuntu GNOME Remix منتشر بشه، این توزیع با میزکار گنوم عرضه شد (حقیقتا جا داشت این مورد شدیدا بهش اشاره بشه). اگر دوست دارید در مورد این نسخه بیشتر بدونید میتونید به این مصاحبه من با لینوکس سیزن مراجعه کنید و کمی با ذهنیت من در اون سال آشنا شید. نسخه ۳ خیلی حاشیه نداشت. در عین حال، خیلی هم سر و صدا و برند نساخت. یک توزیعی بود که نصب میشد و خلقالله استفاده میکردند.
نسخه ۴، برای من خیلی مهم بود. در این حد که حتی اسم نسخهش هم خواستم یک چیز باحال انتخاب کنم و از همین رو، اسم رو گذاشتم Pirates of Galaxy یا «غارتگران کهکشان». در این یکی نسخه خیلی سعی داشتم که همهچی رو مینیمال در عین حال شخصی نگه دارم. اما یک مشکل اساسی اینجا پیش آمد. مشکل چی بود؟ مشکل این که اوبونتو باگی داشت که اگر شما اون رو باز دوباره بستهبندی میکردی، نمیتونست کارت شبکه رو درست شناسایی کنه و به اینترنت متصل نمیشد. همین موضوع باعث این کامنت از جادی شد:
خب بخش اول کامنت تذکری بود به دوستی که ظاهرا ادب رو رعایت نکرده بود. بخش دوم هم از نظر من بد نیست، اما نکته مهم برخورد جامعه نرمافزار آزاد با این موضوع بود. چرا؟ چون من یادمه حتی سال ۹۶ که خودمم یادم نبود چه کرده بودم تو این سیستمعامل، در بعضی جلسات لاگ و بعضی رویدادها این موضوع شده بود متاع خنده! طبیعتا هیچکس خوشش نمیاد کاری که در نوجوانی کرده و حتی کار بدی هم نبوده (ساخت توزیع لینوکس واقعا کار بدی نیست، شاید بیهوده باشه ولی بد، نه!) سوژه خنده یک جمع باشه.
خلاصه اینجا دیگه شد آخرین جایی که جبیر بعنوان یک توزیع گنو/لینوکس عرضه شد و دفترش به پایان آمد. اما حکایتش همچنان باقی ماند.
رفتن سراغ BSD
بعد از جبیر ۴، دیگه تصمیم رو جدی گرفتم. با خودم گفتم لینوکس برای من سیستم بشو نیست :)) در این حد که هرجا بحثی از لینوکس میشد، سریعا اشاره میکردم به این که در PlayStation 4 از FreeBSD استفاده شده، واتسپ داره FreeBSD استفاده میکنه و OpenBSD ایمنترین سیستمعامل جهانه و اپل با BSD اپل شد و اینها و در عین حال لگدی هم به لینوکس میزدم و میگفتم این سیستمعامل، یک سیستمعامل مردهست.
در همین حین، ما باز به تهران برگشتیم و خب کمی سخت بود که روی توسعه جبیر کار کنم چرا که اینترنت درست و درمونی نداشتم، لپتاپم برای کامپایل کردن کدهای FreeBSD ضعیف بود و کلی داستان و مشکل از این قبیل پیش آمد. خلاصه پس از این که مدتی گذشت و کمی این مشکلات حل شد، موفق شدم که جبیر رو دوباره از نو با کرنل FreeBSD تولید کنم و بعد مدتی حتی اسم کرنل رو از FreeBSD به JabirOS تغییر دادم (که خب این خودش یک اشتباه خیلی خیلی بزرگ محسوب میشد چون عملا از پورتها نمیشد دیگه استفاده کرد) و کلا در مسیری بودم که با خودم میگفتم «دو سال دیگه به اپل رسیدم».
یکی از دلایلش، این بود که من کم کم داشتم وارد مدیای خارجی میشدم. مثلا این وبسایت، خبر انتشار جبیر جدید رو کار کرد یا این یکی، با من مصاحبهای ترتیب داد. همه این موارد دست به دست هم دادند تا من خیلی بیشتر از پیش، از خودم جلو بیفتم.
اما خب این موضوعات پشت سر هم، پیشدانشگاهی و کنکور و ورود به دانشگاه باعث شدند که کلا بیخیال پروژه جبیر بشم و این مورد باعث شد که ذهنم برای پروژههای دیگری که در این سالها انجام دادم بازتر بشه.
این داستان ادامه دارد
فکر میکردم شاید این داستان چهار یا پنج قسمت بشه، اما تا اینجا که توضیحاتم رو ارائه کردم، فکر کنم کلا یک مطلب دیگر که کلیت این دو قسمت رو جمعبندی کنه و کمی به رفتارهای اطرافیان – بخصوص جامعه نرمافزار آزاد – و داستانهایی مشابه شرکت در جشنواره خوارزمی و … اشاره کنه، کافی باشه.
خلاصه، دوست دارم ازتون تشکر کنم که تا اینجای مطلب رو خوندید و همراه من بودید. من همیشه دوست داشتم این تجربه رو مکتوب کنم و خب اتفاقات اخیر، موجب این شد که این مطالب مکتوب بشند و در وبلاگ هم به رشته تحریر دربیان.
در نهایت، برای تکتک خوانندگان این بلاگ، آرزوی موفقیت و خوشحالی میکنم.
چندین روز پیش، شخصی در لینکدین خبری از ساخته شدن یک فراجستجوگر داده بود که به شخصه برای من موضوع جالبی بوده همیشه. منتها طبق عادات مالوف هموطنانمون، بزرگ حرف زدن و زیادی مبالغهکردن هم میشد در اون حرفها دید. چیزی که ساخته شده بود اینطور توضیح داده شده بود که:
فراجستجوگر ساخته شده توسط تیمی از بهترین متخصصان که در یک دانشگاه خاص درس خواندند (که خب همین جملات، بدون توجه به اسم دانشگاه و موسسه و … معمولا پرچم قرمزی در بحث تولیدات ملی و بومیه) به این شکل کار میکنه که نتایج جستجو رو از وبسایتهای معروف به موتور جست و جو مانند گوگل، داکداکگو، بینگ و … برمیگردونه و رد پای شما رو از جست و جو حذف میکنه.
وقتی این رو خوندم، فهمیدم که با یک فراجستجوگر یا metasearch engine روبرو هستیم و خب گفتم بد نیست که با هم یکی بسازیم. قبل از هرچیزی، اگر نمیدونید فراجستجوگر چیه، میتونید به اینجا مراجعه کنید و تعریفش رو بخونید. برای ادامه دادن به مطالعه این مطلب هم لازمه که کمی لینوکس و مدیریت سیستم بلد باشید.
آشنایی با searx
خب searx یک نرمافزار آزاده که هدفش، بهبود تجربه جست و جوی افراد در اینترنته. این نرمافزار، به دو صورت قابل دسترسیه. اول این که تعدادی نمونه عمومی داره (لینک نمونههای عمومی در اینجا قرار گرفته) و هم به صورت «خودمیزبان» یا همون self-hosted. متد خودمیزبان یعنی شما به عنوان کاربر، میتونید به صورت رایگان یا با پرداخت پول (بسته به مدل کسب و کار و توسعه اون پروژه خاص)، اون نرمافزار رو روی هاست یا سرور مورد نظر خودتون نصب کنید.
در این آموزش، قراره با کمک یک سرور لینوکسی، یک زیردامنه، یک کارساز وب و داکر؛ یک فراجستجوگر ساده رو به کمک هم بیاریم بالا. به این شکل میتونیم هم یک نمونه عمومی عرضه کنیم، هم این که دیتای کمتری در اختیار شرکتهایی مثل گوگل یا مایکروسافت بذاریم.
ساخت فراجستجوگر
برای ساخت فراجستجوگر خودمون، نیاز به موارد زیر داریم:
سرور لینوکسی. من شخصا از اوبونتو ۱۸.۰۴ استفاده کردم. برای پردازش بهتر نتایج و نخوردن به مشکل تحریم و …؛ بهتره که سرور داخل ایران هم نباشه. به همین خاطر، من از سرور هلند استفاده کردم (کشور محل قرارگیری سرور، کاملا به خودتون بستگی داره).
یک دامنه یا زیردامنه. برای این پروژه من از searx[dot]haghiri75[dot]com استفاده کردم.
کمی آشنایی به کارهای سروری. اگر آشنایی خاصی ندارید هم مهم نیست! در حد لزوم در این مطلب یاد میگیرید 😁
آمادهسازی سرور
وقتی سرور رو از ارائهدهنده سرور تحویل گرفتیم (با فرض اوبونتو/دبیان بودنش) نیازه تا اول لیست بستههای اون رو کمی به روز کنیم:
sudo apt update
و اگر لازم شد، کل سیستمعامل هم یک بار بهروز میکنیم:
sudo apt full-upgrade
بعد از این که این اتفاقات رخ داد، یک دور سرور رو ریبوت میکنیم و پس از بوت شدن مجدد و اتصال به سرور، چند بسته نصب میکنیم:
nginx: این بسته، وبسرور یا همون کارساز وب ماست. چیزی که باعث میشه ما بتونیم بدون مشکل، یک وبسایت یا نرمافزار تحت وب رو استفاده کنیم.
python3-certbot-nginx: از این بسته استفاده خواهیم کرد تا یک گواهی SSL برای وبسایت خودمون بگیریم.
docker.io: داکر یک سیستم کانتینرییزشنه. در واقع نرمافزارها رو داخل بستههای کوچولو قرار میده و همه ملزوماتشون اونجاست. فقط تنها موردی که داره، اینه که از هسته سیستم عامل استفاده میکنه برای مدیریت فرایندها (در واقع تفاوتش با ماشین مجازی همینه).
حالا ما سرور رو آماده کردیم. گام بعدی چیه؟
آمادهسازی دامنه
برای آمادهسازی دامنه، کافیه که یک رکورد A با IP سرور مورد نظر ایجاد کنید. البته در بعضی موارد از CNAME هم میشه استفاده کرد اما اینجا چون سرور از وبسایت جدا بود، یک A تعریف شد. بعد از این که رکورد رو تعریف کردیم، باید ۵ تا ۱۰ دقیقه صبر کنیم تا عموم DNS Server های اینترنت، بشناسنمون. بعدش میتونیم به کارمون ادامه بدیم.
حالا ۱۰ دقیقه گذشت و یک قهوه هم خوردیم و آمادهایم که مرحله بعدی رو انجام بدیم.
دریافت گواهی SSL
خب دریافت گواهی SSL هم بسیار سادهست. کافیه این دستور رو در سرور اجرا کنید (و دامنه من رو با دامنه خودتون عوض کنید):
sudo certbot -d searx.haghiri75.com --nginx
در این مرحله شما باید آدرس ایمیلتون رو وارد کنید و به چند سوال هم پاسخ بدید. در کل همهچیز با یک wizard اتفاق میفته و نیازی نیست که زحمت زیادی بکشید. فقط یک نکته مهم رو اینجا باید بهش دقت کنیم. اون نکته اینه که certbot اینجا خودش nginx رو استارت میزنه. در مرحله بعدی، نیاز داریم که به این مهم توجه کنیم.
راهاندازی داکر و نصب فراجستجوگر
خب اول از همه کاربر خودمون (که در اینجا فرض میگیریم نام کاربریش هم Ubuntu ئه) رو به گروه داکر اضافه میکنیم:
sudo usermod -aG docker ubuntu
بعدش کافیه یک بار از نشست SSH خارج شیم و دوباره به سرور SSH بزنیم. دقت داشته باشید که این بخش الزامی نیست؛ ولی اگر شما این کار رو نکنید بعدا در استفاده از داکر، نیازمند دسترسی ریشه خواهید بود. نگران دسترسی ریشه هم نباشید چون با sudo قابل حله.
بعد از این مورد، ایمیج searx رو از رجیستری داکر دریافت میکنیم:
docker pull searx/searx
خب در حال حاضر، اتفاق خاصی میافته؟ خیر. فقط تصویری که searx روی اون نصب شده، روی سرور ما دانلود شده.
بعد از اون، نیازداریم که یک کانتینر براش بسازیم. برای این، مراحل زیر رو طی میکنیم:
mkdir searx
cd searx
docker run --rm -d -v ${PWD}/searx:/etc/searx -p 8080:8080 -e BASE_URL=http://localhost:8080/ searx/searx
خب تبریک به شما، الان شما یک فراجستجوگر دارید.
اما صبر کنید! هنوز نمیتونیم بهش دسترسی پیدا کنیم. پس چه کنیم؟
پراکسی معکوس برای دسترسی به محتوا
خب اینجا نیاز داریم که از پراکسی معکوس استفاده کنیم. انجینکس علاوه بر این که وبسروره، پراکسی معکوس هم هست و خیلی از ما عمدتا از قابلیت پراکسی معکوسش برای اجرای نرمافزارهای تحت وبمون استفاده میکنیم. مثل همین آموزش دپلوی کردن یک پروژه ریلز نوشته بودم (لینک). دونستن این که پراکسی معکوس چیه و چی کار میکنه، از ملزومات پایهای مدیریت سیستم و همچنین دواپس و CI/CD محسوب میشه (جهت اطلاعات بیشتر این پست رو بخونید).
پس اگر میخواهید در آینده مهندس DevOps بشید، شاید بتونید این مطلب رو فرصتی برای تمرین یکی از مواردش قرار بدید. فکر کنم زیاد صحبت کردیم. بریم سر اصل مطلب. برای این که بتونیم از پراکسی معکوس استفاده کنیم، کافیه که اول با ادیتور دلخواهمون، فایل پیکربندی رو باز کنیم:
sudo nano /etc/nginx/sites-enabled/default
و سپس دنبال دامینمون بگردیم (در نانو با ctrl + W میشه). بعد از این که دامینمون رو پیدا کردیم کافیه بخش location / رو پیدا کنیم (معمولا دو سه خط پایینتر از دامین و تنظیماتشه) و سپس به این شکل درش بیاریم:
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
# try_files $uri $uri/ =404;
proxy_pass http://localhost:8080;
}
و بعدش هم کافیه که دستور زیر رو اجرا کنیم تا انجینکس ریستارت بشه:
sudo systemctl restart nginx
استفاده از فراجستجوگر شخصی
سخن آخر
نرمافزار searx مثل هر نرمافزار متنباز و آزاد دیگری، قابلیت شخصیسازی داره و همین موضوع که با زبان پایتون نوشته شده هم نشون میده که شخصیسازیش احتمالا از چیزی که فکر میکنیم، سادهتره. به همین خاطر میتونیم به سادگی این نرمافزار رو تغییر بدیم که مطابق میل خودمون کار کنه و طبیعتا آموزشش هم در اینترنت وجود داره.
موضوع بعدی اینه که فراجستجوگرها، علاوه بر این که میتونن در حفظ حریم شخصی و … موثر باشند، میتونن کاملا بیزنسی هم کار کنند. مثلا هرکلید واژهای که سرچ کنید رو صرفا در موضوع خاصی دنبالش بگردند. مثلا شما اگر سرچ کنید «سیبزمینی» فقط در وبسایتهایی که وبینار میزبانی میکنند دنبالش بگرده. وقتی سرچ میکنید «قشم» فقط در وبسایتهای گردشگری دنبالش بگرده و الی آخر.
در این مطلب قصد داشتم این موضوع رو نشونتون بدم که داشتن یک موتور جست و جوی امن، اونقدرا که فکر میکنید سخت نیست و با کمک نرمافزارهای آزاد، به سادگی میتونید یکی رو خودتون بسازید. در پایان مطلب، جا داره از شما بابت خوندن این مطلب تشکر کنم. همچنین، ممنون میشم مطالب و خطخطیهای من رو در ویرگول هم بخونید و نظر بدید 🙂
در پست پیشین، یعنی قسمت اول داستان برنامهنویس شدنم (لینک) از زمانی که شروع به خوندن کتابهای ویژوال بیسیک کردم تا زمانی که پروژه جبیر رو راه انداختم رو به تفصیل توضیح دادم. فکر میکنم داستان برنامهنویس شدن من، داستان جالبی برای خیلی از دوستانی که وبلاگم رو میخونن بوده و به همین دلیل، تصمیم گرفتم که قسمت دومش هم حتما بنویسم.
همونطوری که در قسمت قبلی قولش رو داده بودم، قراره که در این قسمت از بعد از پروژه جبیر تا زمانی که وارد بازار کار شدم رو توضیح بدم و بگم چی شد که اینطوری شد. در مورد مسیرهای شغلی قبلتر توضیح دادم (مثلا در پست چگونه توزیع لینوکس بسازیم و یا پست چگونه بازیساز شویم) همینطور حتی ابزارها و وسایلی که در مسیر شغلهای مختلف طراحی و تولید کردم (مثل صداگذاری روی بازی کامپیوتری) هم در این وبلاگ پیشتر توضیح دادم. فلذا در این مطلب، اصلا و ابدا به مسیرهای شغلی اشاره نخواهم کرد.
ورود به دانشگاه
در طی این سالها، یعنی از حدود ۹۱ تا ۹۳ راههای زیادی رو رفتم که سرویسها و نرمافزارهای خاصی رو طراحی کنم و خب دروغ چرا، تا حد زیادی هم رویای استیو جابز یا زاکربرگ شدن هم در سر داشتم و خب کارهای مختلفی مثل ایجاد انجمنهای اینترنتی مختلف (ایرانبیاسدی، ایرانهکینتاش و …) گرفته تا برپا کردن شبکههای اجتماعی و نرمافزارهای آنلاین دیگر (اکسوال، نکستکلود و …) رو انجام میدادم. راستش این راهها من رو به قول خارجیها Satisfy نمیکرد و همچنان دنبال این بودم که یک سیستم عامل خوب بسازم!
خلاصه شد سال ۹۲ و ما از شهر بندرعباس به تهران برگشتیم. اون سال، سال پیشدانشگاهی من بود (و بد نیست این داستانکم رو هم پیرامونش بخونید) و اون سال، یک تصمیم بزرگ هم گرفتم. تصمیمم این شد که جبیر به جای این که مبتنی بر اوبونتو (یک توزیع از گنو/لینوکس)، یک نسخه شخصیسازیشده از FreeBSD باشه. از همین رو، شروع کردم به رفتن به IRC های مختلف، سوال پرسیدن و مستندات خوندن. بعد از چندین ماه مطالعه، وضعیت اینترنت خونه و خودم تا حد خوبی پایدار شد و بعد شروع کردم به انجام تغییرات روی کد FreeBSD.
بعد از مدتی، پروژه جبیر تا حد خوبی پیش رفت و گذشت و گذشت و من کنکور دادم (داستانی از کنکور هم اینجا نوشتم) و وقتی نتایج اومد، فهمیدم که در دانشگاه آزاد اسلامی واحد تهران مرکز در رشته مهندسی کامپیوتر و گرایش سختافزار قبول شدم.
شرکت در لاگها و رویدادها و آخر و عاقبت پروژه جبیر
حضور در تهران و دانشجو شدن، به من کمک کرد که وارد جامعه بشم و در رویدادهای نرمافزار آزاد و متنباز و سایر رویدادها (مثل PyCon و …) شرکت کنم. اولین رویدادی که شرکت کردم، رویدادی بود به اسم «جامعه رایانش ابری آزاد». در اون رویداد با KVM و Docker آشنا شدم و تا حد زیادی هم دانشم در زمینه Containerها و مجازیسازی تا حد خوبی بالا رفت.
در حاشیه شرکت در این رویدادها، بسیاری از افرادی که از انجمن اوبونتو و یا تکنوتاکس یا لینوکسریویو میشناختم رو حضوری دیدم و باهاشون آشنا شدم و حتی رفاقتهایی شکل گرفت. پس از مدتی، در بحثی دوستانه، تصمیم بر آن شد که پروژه جبیر کلا منحل بشه و پروژهای به این بزرگی که نیازمند دانش فنی بالا، پول زیاد و همچنین حوصله فراوونه، به زمانی موکول شه که بتونم از پس حداقل یک موردش بربیام. فلذا پروژه جبیر اعلام شد که دیگه قرار نیست ادامه پیدا کنه.
اگر دوست دارید ببینید که پروژه جبیر چه شکلی بوده، میتونید این لینک مربوط به وب آرکایو رو هم ببینید: لینک. در ادامه، بنا به دلایلی (که در ادامه این مطلب بهش میپردازیم) تصمیم شد که پروژه جبیر بیشتر روی فاز سختافزاری باشه و چند مطلب هم در موردش حتی نوشتم(لینک).
یادگیری روبی، ورود به حوزه سختافزار و دیگر هیچ!
مهرماه ۹۳ بود که من خیلی جدی تصمیم گرفتم حداقل یک زبان برای توسعه وب رو جدی یاد بگیرم. قبلترش، کتاب «از این پس پایتون» رو خونده بودم و به همین خاطر هم کمی با پایتون و فلسک آشنا بودم. دوستی یک کتاب جنگو هم برای من ارسال کرد. اما در همون هنگام در بحثی در IRC که دقیق یادم نیست مربوط به occc بود یا لاگ کرج، دوستی به من پیشنهاد کرد که روبی و روبیآنریلز رو یاد بگیرم. در ادامهش، توصیه کرد که حتما با دیتابیسها آشنا شم و کمی هم مهندسی نرمافزار یاد بگیرم.
من هم این توصیه رو عملی کردم و شروع کردم به خوندن روبی. شاید باورتون نشه ولی از اونجایی که دیدم زبون روبی، خیلی در ایران زبون روتینی نیست و خیلیها باهاش غریبهند، تصمیم گرفتم دانش خودم رو در قالب یک کتاب الکترونیکی دربیارم و خب نتیجه پس از مدت نسبتا طولانی شد کتاب آموزش روبی که به رایگان قابل دانلوده.
خب همونطوری که ابتدای متن گفتم، من گرایش سختافزار بودم و حقیقتا این وسط به سرم زده بود دانش سختافزاری خودم رو هم بالا ببرم. به همین خاطر ترم ۳ یا ۴ که بودم، قبل از این که به مدار منطقی برسم، خودخوان شروعش کردم. برام جالب بود و خب در عین حال ریاضیات گسسته هم برای من داشت مرور میشد. این مرور، در کنار دانش مدار منطقی من رو وادار کرد که کمی بیشتر بخوام در این حوزه ورود کنم. به همین خاطر، معماری کامپیوتر و ریزپردازنده رو هم حتی پیش از این که درسم بهشون برسه، مطالعه کردم.
وقتی به نتایج جالبی رسیدم، تصمیم گرفتم دوباره دانشم رو با مردم به اشتراک بذارم. به همین خاطر، این بار هم محتوا رو به زبون انگلیسی تولید کردم (لینک) و به رایگان در نسخه انگلیسی همین وبلاگ منتشرش کردم. خلاصه که اینجا تموم نمیشه. در اون سالها، بازار «اینترنت چیزها» یا IoT هم داغ بود و خب طبیعتا شروع کردم به یادگیری آردوینو، رزبریپای و … و پروژههای جالبی هم با اونها انجام دادم. البته خیلی از این پروژهها رو هنوز که هنوزه عمومی نکردم.
خلاصه این مورد هم گذشت و رسیدیم به شهریور ۹۶. یعنی جایی که من خیلی جدی و رسمی وارد بازار کار شدم.
ورود به بازار کار
در تیرماه ۹۶، در رویدادی شرکت کردیم که مرتبط با فعالان صنعت بازی رایانهای بود. این رویداد، به طور خاص به آهنگسازان و مهندسین صدا اختصاص داشت و خب بخاطر علاقه شخصیم به موسیقی، در این رویداد شرکت کردم. آخر رویداد گپ و گفتی با سخنران رویداد داشتم که باعث شد شخصی بیاد خودش رو معرفی کنه و بگه که تیمشون نیاز به آهنگساز داره. پس از مدتی، مدیر استودیو به من پیام داد و گفت بازیای در ژانر کودکه و خب نمیدونم چی شد که اون موقع، این بحث ادامه پیدا نکرد.
اما شهریور ۹۶ یکی از دوستانی که در همون استودیو مشغول بود، برای یک بازی دیگر من رو دعوت کرد به همکاری. یک مصاحبه ریزی داشتیم و پس از اون مصاحبه، قرار شد من برم و همکاری کنم. پس از این ماجرا، من رسما وارد اکوسیستم و بازار کار شدم تا به امروز.
سخن آخر
خب، در این مطلب هم مثل مطلب قبلی حجم خوبی از خاطرات من رو شاهد بودید. کل حرفی که میخواستم بزنم این بود که دوستان، از تجربه کردن و حتی شاخه شاخه پریدن؛ نترسید. این پرشها به خودی خود باعث میشن که شما در کارتون – حتی کارهای فریلنسری و پروژهای – به شدت موفقتر عمل کنید. یادتون باشه که زندگی، فانتر از اونیه که بخواید با زیادی جدی گرفتن؛ خرابش کنید.
مدتی میشه که در جامعه بینایی ماشین، دارم به صورت خیلی جدی در مورد بیناییماشین و ملزوماتش، تولید محتوا میکنم. از همین رو، تصمیم گرفتم که در قالب این پست وبلاگی، در مورد این که بینایی ماشین چیه و کجا کاربرد داره و چرا باید بلدش باشیم و از کجا باید شروع کنیم؛ بنویسم.
این مطلب، اصلا و ابدا قرار نیست «آموزش» باشه و همونطوری که ابتدای مطلب گفتم، صرفا «نقشه راه» برای شماست.
بینایی ماشین چیه؟
بینایی ماشین در واقع یکی از شاخههای علوم کامپیوتر محسوب میشه که هدفش، اینه که پردازش و درک تصاویر دیجیتال رو سادهتر کنه. بینایی ماشین در ترکیب با هوش مصنوعی، رباتیکز و سایر شاخههای مرتبط با علوم و یا مهندسی کامپیوتر، میتونه به بهبود زندگی افراد کمک شایستهای کنه.
شاخههای زیادی برای بینایی ماشین داریم اعم از تشخیص چهره، تشخیص متن، خواندن نویسههای نوری (OCR)، واقعیت افزوده، واقعیت مجازی و … . هرکدوم از این شاخهها، تخصصهای خاص خودش رو میطلبه که در ادامه مطالب بهش خواهیم پرداخت.
کجا کاربرد داره؟
کاربردهای بینایی ماشین، میتونه در بسیاری از جاها باشه. نمونهش مثلا همین پروژهای که من زده بودم:
همونطور که میبینید، این پروژه برای اندازهگیری اشیاء مختلف با کمک بینایی ماشین ساخته شده بود. همچنین، یک پروژه دیگر این بود که حروف اشاره (که مورد استفاده ناشنوایانه) رو تشخیص میداد. در دنیای امروز تقریبا در هر جایی که کوچکترین استفادهای از تصویر میشه، مثل ویرایش و ساخت تصویر؛ تشخیص اقلام درون تصویر و …؛ بینایی ماشین داره در ابعاد وسیعی استفاده میشه.
چرا باید بلدش باشیم؟
بایدی وجود نداره. یادگیریش به عنوان یک مهارت، کاملا میتونه شما رو به یک پروژه خفن، کار یا پول نزدیک کنه. حتی اگر قصد ندارید در این زمینه کار کنید هم میتونید با یادگیری بینایی ماشین به سادگی برای خودتون یک تفریح سالم بسازید.
از کجا شروع کنیم؟
خب مهمترین بخش این مطلب دقیقا همینجاست که قراره با هم یاد بگیریم که چه پیشنیازهایی برای یادگیری بینایی ماشین وجود داره. هر پیشنیاز رو با هم کمی بررسی خواهیم کرد 🙂
برنامهنویسی پایتون: از اونجایی که پایتون زبان سادهایه و اکثر آدمها دنبال یادگیریشن (و این یعنی منابع آموزشی خیلی خوبی براش هست) بهتره که پایتون رو تا حد خوبی یاد بگیرید. حد خوب، یعنی حدی که شما بتونید یک نرمافزار ساده ولی کاربردی رو باهاش توسعه بدید (مثلا یه ماشین حساب یا چیزی مشابه اون).
مقدمات یادگیری ماشین: بینایی ماشین به شکلی یکی از زیرمجموعههای هوش مصنوعی محسوب میشه. این نشون میده که اگر شما به الگوریتمها و تئوری یادگیری ماشین و … آشناییت کافی داشته باشید، میتونید در این فیلد هم پیشرفت قابل توجهی کنید. گذشته از این، یادگیری ماشین میتونه بهتون در «هوشمندسازی» بیشتر نرمافزارهای بینایی ماشین کمک کنه.
آشنایی مختصر با جاوا یا سی++: از اونجایی که پایتون یک زبان مفسری محسوب میشه، ممکنه خیلیجاها (مثلا در یک برد آردوینو) نتونیم مستقیم ازش استفاده کنیم و همچنین استفاده ازش پیچیدگی خاصی به همراه داشته باشه؛ بهتره یک زبان سطح پایینتر مثل سی++ هم کمی آشنا باشیم. همچنین اگر قصد این رو دارید که اپلیکیشن تلفن همراه بنویسید که از بینایی ماشین استفاده میکنه، بد نیست دستی هم در جاوا داشته باشید.
آشنایی با سختافزارها و سیستمهای نهفته (Embedded Systems): یکی از کاربردهای عظیم بینایی ماشین، فعالیتهای Surveillance میتونه باشه (البته این که این فعالیتها بد یا خوب هستند بحث جداییه). یکی از نمونههاش میتونه «سیستم حضور و غیاب با تشخیص چهره» باشه، یا حتی «دفترچه تلفن هوشمند» و … 🙂 به همین دلیل، بد نیست که کمی با سیستمهای نهفته و سختافزارهایی مثل Jetson Nano و Raspberry Pi آشنایی داشته باشید.
آشنایی با لینوکس: این واقعا نیاز به توضیح خاصی نداره، روایت داریم اگر لینوکس بلد نیستی، برنامهنویس نیستی 🙄
لیست بالا به شما کمک میکنه که محکمتر در زمینه بینایی ماشین، قدم بردارید. هرجاش رو که بلد نباشید میتونید با جستجو پیداش کنید و یاد بگیرید و از یادگیری، لذت ببرید 🙂
سخن آخر
از این که وقت گذاشتید و این مطلب رو خوندید ممنونم. در آینده، در قالب پستهای وبلاگ در مورد پروژههای بینایی ماشین و سایر پروژههای باحال، صحبت خواهم کرد. امیدوارم که این مطلب مفید فایده واقع شده باشه و وقتی که براش گذاشتید ارزشش رو داشته باشه.
خیلی از افرادی که این روزها، میخوان پروژههایی در حوزههای مختلف هوش مصنوعی مثل یادگیری ماشین، یادگیری عمیق، علوم داده و … انجام بدن یک گلوگاه بسیار بزرگ دارند و اون «داده» است. خیلیها واقعا نمیدونن از کجا میتونن دادههای مناسب پروژههاشون به دست بیارن. در این مطلب، قراره که این موضوع رو پوشش بدم.
منابع مناسب داده برای پروژههای شما
در این بخش، با هم چندین منبع مناسب برای پیدا کردن داده رو بررسی خواهیم کرد. فقط قبل از هرچیز این رو بگم که این منابع میتونن تغییر کنن در طول زمان پس هرچه که در این مطلب بیان شده رو در مرداد ۱۴۰۰ معتبر بدونید و اگر مدتی بعد از انتشار این مطلب دارید مطالعهش میکنید، با جستوجو و پرسوجو در مورد این منابع، اطلاعات بهروزتر دریافت کنید.
Kaggle
وبسایت کگل، یک محیط تقریبا مشابه شبکههای اجتماعی برای دانشمندان داده و متخصصین هوش مصنوعی به حساب میاد. در این وبسایت شما میتونید مجموعه داده (Dataset) های خوبی رو پیدا کنید. همچنین، میتونید کارهایی که ملت روی اون دادهها انجام دادن رو در قالب Kaggle Kernel (به نوعی همون جوپیتر نوتبوک خودمون) ببینید و یا کارهای خودتون هم به اشتراک بذارید.
برای دسترسی به کگل، میتونید روی این لینک کلیک کنید.
Academic Torrents
این وبسایت هم وبسایت جالبیه (و به نوعی مرتبط با بخش بعدی). در واقع هر حرکت آکادمیکی که زده شده و اطلاعاتش هم همزمان منتشر کردند رو در خودش داره. چرا؟ چون جست و جو در محتوای آکادمیک نسبتا سخته و این وبسایت اون کار رو براتون راحت کرده. همچنین یک بخش خوبی برای مجموعهداده (لینک) هم در این وبسایت در نظر گرفته شده.
برای دسترسی به این وبسایت، میتونید از طریق این لینک اقدام کنید.
وبسایت دانشگاهها
همونطوری که در بخش قبلی گفتم، بسیاری از دانشگاهها (و در کل، فضاهای آکادمیک) تحقیقات زیادی انجام میدن و دادههای اون تحقیقات رو هم معمولا منتشر میکنن. چرا که یکی از اصول مطالعات آماری، اینه که دادهها به صورت شفاف منتشر بشن (شاید دلیلش اینه که بعدها، یکی بخواد خودش اون آزمایش و مطالعه رو تکرار کنه و …).
به همین خاطر، وبسایت دانشگاهها – چه ایرانی و چه خارجی – میتونه محل خوبی باشه برای مراجعه و پیدا کردن دادههای خوب برای مطالعه.
دیتاستهای متنباز شرکتها
بسیاری از شرکتهای بزرگ مثل گوگل، فیسبوک، آمازون و …، میان و حجم خوبی از دادههایی که قبلتر در تحقیقاتشون استفاده کردند رو به صورت اوپنسورس، منتشر میکنن. پیدا کردن این دیتاستها هم اصلا کار سختی نیست.
برای مثال، در این لینک میتونید دیتاستهای گوگل رو ببینید. یکی از نمونههایی که خود گوگل اینجا مطرح کرده، دیتاست مرتبط با بیماری کووید-۱۹ است. (لینک)
چرا این شرکتها، دیتاستها رو منتشر میکنن؟ باز هم میگم دقیقا به همون دلیلی که دانشگاهها منتشر میکنن. شاید افراد یا سازمانهایی باشن که بخوان تحقیقات و مطالعات رو برای خودشون تکرار کنند و یا نتیجه آزمایشات و … رو صحتسنجی کنند.
خزیدن (Crawling) صفحات وب
خب، بعضی وقتا هم دادهای که ما نیاز داریم، توسط شرکتها یا دانشگاهها منتشر نشده. پس در این حالت چه کار میکنیم؟ اگر داده مورد نظر، در اینترنت موجود باشه، میتونیم یک خزنده (Crawler) بسازیم و با اون کارمون رو پیش ببریم.
در بسیاری از زبانهای برنامهنویسی و چارچوبهاشون، ابزارهای بسیار خوبی برای کراول کردن صفحات وب وجود داره. یکی از بهترین نمونههاش میتونه BeautifulSoup در پایتون باشه. در مطالب بعدی، احتمالا با استفاده از این ابزار، یک خزنده برای وبسایتهای مختلف خواهیم نوشت.
دوربین، میکروفن، حرکت!
اگر دادههای مورد نیاز ما حتی به شکلی که بتونیم کراول کنیم موجود نبود چی؟ سادهست. ابزارهای ورودی خوبی برای کامپیوتر وجود داره که میتونه بهمون کمک کنه تا داده مورد نظر رو جمعآوری کنید.
گذشته از این، دوربین تلفنهای همراه، میتونه منبع خوبی باشه برای جمع آوری تصاویر(پروژههای بینایی ماشین و …)، میکروفنهای استودیویی برای دریافت صدا خوبن. اگر نیاز به دیتایی مثل گرما یا رطوبت نیاز دارید، طراحی مداری که این داده رو از محیط بخونه و روی دیتابیس خاصی ذخیره کنه کار سختی نیست.
جمعبندی
پروژههای هوش مصنوعی به ذات سخت نیستند. چیزی که اونها رو سخت میکنه، همین دیتای ورودی و تمیزکاری و مرتب کردنشه. بعضی وقتا دادههای ما کم هستند و ما مجبور خواهیم شد که Data augmentation انجام بدیم. بعضی وقتا ممکنه نویز به قدری زیاد باشه که اصلا مرحله جمعآوری دیتا رو مجبور بشیم دوباره از نو انجام بدیم و … .
خلاصه هدف از این مطلب این بود که اگر پا در این عرصه گذاشتید، بدونید همیشه جایی هست که بتونید بدون مشکل، دادههایی رو دریافت و در پروژهتون استفاده کنید و از بابت نویز و …، خیالتون تا حد خوبی راحت باشه.
پس از مدت طولانی، با یک پست دیگر برگشتم و این بار قراره با هم احراز هویت JWT رو در ریلز بررسی کنیم. اول از همه، لازمه بدونیم JWT چیه؟ چرا نیازش داریم؟ اصلا چرا احراز هویت و هزاران چرای دیگر که احتمالا الان در سر شما هستند. بعدش یک پروژه خیلی کوچولو ایجاد میکنیم و با هم براش احراز هویت رو پیادهسازی میکنیم 🙂
احراز هویت JWT چیه و چرا بهش نیاز داریم؟
اول از همه این سوال بنیادیتر رو پاسخ بدیم که «چرا احراز هویت نیاز داریم؟» و بعد بریم سراغ احراز هویت JWT که قراره در این مطلب در موردش مفصل حرف بزنیم.
ما به احراز هویت نیاز داریم چون همیشه بخشی از دادههای ما، خصوصی هستند. گذشته از اون، احراز هویت میتونه اجازه CRUD رو به شما بده، نه؟ فکر کنید اپی دارید که هرکسی میتونه روش بخونه و بنویسه. ممکنه خوندن چیزی باشه که برای «همه» مناسب باشه اما «نوشتن» اینطور نیست. بخصوص که نوشتن خودش به قسمتهایی مثل حذف و بروزرسانی هم شکسته شده.
پس ما به احراز هویت نیاز داریم که هر ننهقمری (😂) نتونه از API ما استفاده کنه. بلکه کاربرانی که ثبتنام کردند و دسترسی درستی به سرویس دارند، بتونن استفاده کنن. این قضیه در API های تجاری (یا Business facing) خودشون رو بیشتر و بهتر نشون میدن.
حالا سوال مهمتر …
احراز هویت JWT چیه؟
در اپهای قدیمی (مثل همین وردپرس)، احراز هویت توسط cookie ها انجام میشه. به چه صورتی؟ به این صورت که وقتی نام کاربری و گذرواژه وارد میکنیم، نرمافزار فضایی رو در مرورگر به خودش اختصاص میده و یک سری اطلاعات رو با خودش جابجا میکنه. اما در ReST API ها این قضیه رو نداریم. در واقع نمیتونیم به کوکیها اعتماد کنیم. پس چه میکنیم؟ اینجا لازمه جز یوزرنیم(که معمولا میتونه عمومی باشه) و پسورد (که میتونه راحت لو بره) میاییم و یک «توکن» هم تعریف میکنیم. این توکن، میتونه ثابت یا متغیر باشه. یعنی چی؟ یعنی میتونه به ازای هربار ورود تغییر کنه، میتونه سر زمان مشخصی هم منقضی بشه.
حالا توکن چیه؟ توکن به صورت کلی، در کازینوها معادل پولیه که شما در بازیها قرار میدید، در واقع مجوز حضور شما در اون کازینو، کلاب و … است. حتی به رمزارزهایی که بر مبنای دیگر رمزارزها ساخته میشن هم سکه نمیگن بلکه میگن توکن. شما فرض کنید که مثلا ۱۰۰ دلار میدید و پنج تا سکه با آرم اون کازینوی خاص دریافت میکنید. اگر در بازی برنده بشید یا ببازید، باید توکنهاتون رو تحویل بدید یا بگیرید.
حالا در احراز هویت JWT هم، ما به ازای کاربرمون یک توکن در نظر میگیریم. این توکن، معمولا یک رشته طولانیه که انسان نمیتونه بخوندش. نتیجتا خیلی از اطلاعات ما به صورت ایمنتر میتونن رد و بدل بشن (طبیعیه که مواردی مثل SSL داشتن و الگوریتمهایی که در ساخت توکن داشتیم هم مهمن). ضمن این که نامکاربری، ایمیل، رمزعبور و .. هم به همین سادگیا نمیتونن خونده بشن.
پس ما میآییم و یک دیتابیسی از توکنها در کنار دیتابیسی از یوزرها میسازیم (البته درستترش، جدوله!) و به ازای هر یوزر معمولا دوتا توکن در اون دیتابیس قرار میدیم. یکیش رو بهش میگیم «توکن دسترسی» یا Access Token و یکی رو میگیم «توکن بازنشانی» یا Refresh Token. توکن دسترسی، معمولا یک تاریخ انقضایی داره و بعد از اون با استفاده از توکن بازنشانی، میتونیم یکی جدید بگیریم. اما در آموزش امروز، صرفا میخوایم توکن دسترسی رو به دست بیاریم.
احراز هویت JWT به این شکل کار میکنه
خب، الان که تقریبا همهچی رو میدونیم، بریم برای پیادهسازی.
پیادهسازی یک اپلیکیشن ریلز با JWT
خب در قدم اول، باید یک اپ ایجاد کنیم. این اپ رو به این شکل ایجاد میکنیم:
rails new devise-jwt --api
خب توضیح واضحات:
قسمت rails که واضحا فراخوانی نرمافزار rails در ترمینال ماست.
قسمت new در خواست برای ایجاد یک اپ جدیده.
قسمت devise-jwt اسم پروژه ماست. حالا چرا؟ چون قراره از یک لایبرری با همین اسم استفاده کنیم. بنابراین، پروژه رو اینطوری اسم گذاشتیم.
در قسمت آخر هم، به ریلز گفتیم که ما تو رو بخاطر API هات دوست داریم. ویو نیاز نیست.
بعد از چند ثانیه (و بسته به سرعت اینترنت دقیقه) اپ ما ساخته میشه. بعد لازمه که مرحله مرحله کارهایی رو انجام بدیم.
نصب لایبرریهای مورد نیاز
خب، اول از همه با ویرایشگر متنی مورد علاقمون فایل Gemfile رو باز میکنیم و این خطوط رو بهش اضافه میکنیم :
gem 'devise'
gem 'devise-jwt'
gem 'rack-cors'
بعد از این که این خطوط رو اضافه کردیم، دستور زیر رو اجرا میکنیم:
bundle
این دستور چه کار میکنه؟ میاد و تمام لایبرریهای مورد نظر شما رو به صورت ایزوله در یک دایرکتوری، نصب میکنه. به این شکل شما میتونید به سادگی بدون رسیدن آسیب به باقی لایبرریهای روبی نصب شده روی سرور یا حتی کامپیوتر خودتون، ایدههاتون رو تست کنید.
لازم به ذکره که بعد از اجرای این دستور فایل Gemfile.lock بهروز میشه، این فایل حالا چه کار میکنه؟ این فایل حواسش به همهچی هست. در واقع، ورژن روبی، ورژن ریلز، لایبرریهای مورد نیاز و ورژنینگشون و … رو همه رو این فایل داره کنترل میکنه.
بعد از انجام مراحل فوق، کافیه این دستور هم اجرا کنیم:
rails g devise:install
این دستور چه میکنه؟ این دستور هم برای ما فایلهای devise رو در جای درستش قرار میده.
آشنایی با devise
برای احراز هویت در هر سیستمی ما دو راه داریم:
نوشتن سیستم احراز هویت از بیخ
استفاده از کتابخانههای موجود
در مورد روش «از بیخ»، ما معمولا این کار رو انجام نمیدیم. چرا؟ چون معمولا اونقدر خوب نیستیم که بتونیم امنیت سیستم رو به خوبی تامین کنیم. در مورد دوم، در هر فرمورک و زبانی، کتابخانههایی ساخته شدند که کمک میکنن ما بتونیم با اضافه کردنشون به پروژه خودمون، بخش احراز هویت رو هندل کنیم. برای ریلز devise ساخته شده. این لایبرری، یک لایبرری مبتنی بر cookie برای احراز هویت وباپهاست.
بعد از همهگیر شدن ReST API ها، لایبرری devise-jwt هم نوشته شد. این لایبرری، ابزاریه که به من و شما کمک میکنه بتونیم احراز هویت JWT رو به پروژهمون اضافه کنیم. در واقع هر سه لایبرری که به پروژه اضافه کردیم، کارشون همینه که JWT رو برای ما راحت کنند.
هندل کردن CORS
در این مطلب قصد ندارم در مورد CORS حرف بزنم، چون قبلتر ازش حرف زدم (و میتونید اینجا بخونید). اینجا ما صرفا قصدمون اینه که بیاییم و این مشکل رو حل کنیم. چطوری؟ خب این فایل:
config/initializers/cors.rb
رو با ویرایشگر متنی مورد علاقهمون باز میکنیم، و محتواش رو به این شکل تغییر میدیم:
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins '*'
resource '*',
headers: :any,
methods: [:get, :post, :put, :patch, :delete, :options, :head]
end
end
توجه کنید که این قسمت معمولا به صورت کامنتشده در کد هست، فقط کافیه آنکامنتش کنید و نیاز نیست که کلا این مورد رو کپی پیست کنید.
ساخت مدل و کنترلرهای مورد نیاز برای کاربر
یکی از خوبیهای devise اینه که به شکل scaffold گونهای، میتونه به ما کمک کنه که کاربر و سیستم کنترلش رو بسازیم. برای ساخت مدل کاربر فقط کافیه که این دستور رو اجرا کنیم:
rails g devise User
به این شکل میفهمه که باید یک مدل، مطابق مدل User ولی با مشخصات devise برامون بسازه. بعدش هم کافیه این دستور رو اجرا کنیم:
rails db:migrate
که جدولای مرتبط برامون در دیتابیس ساخته بشن.
حالا که خیالمون از بابت این قضایا راحت شد چی؟ هیچی. دو تا کنترلر هم میسازیم به این شکل:
rails g controller users/sessions
rails g controller users/registrations
بعد از این میشه گفت که کار ما اینجا تمام شده و باید بریم یه چیزایی رو ادیت کنیم 🙂
ویرایش مدل یوزر
بعد از این که کارهای بالا رو انجام دادیم، کافیه که بریم سراغ مدل یوزرمون و به این شکل ادیتش کنیم:
class User < ApplicationRecord
devise :database_authenticatable,
:jwt_authenticatable,
:registerable,
jwt_revocation_strategy: JwtDenylist
end
حالا این کار برای چیه؟ برای اینه که ما یک جدول دیگر به اسم JWT Deny List در نظر میگیریم و توکنهای منقضیشده رو درونش قرار میدیم. به اون شکل وقتی توکنی منقضی بشه، میتونیم به کاربر خطا نشون بدیم یا از توسعهدهندههای فرانت تیم بخوایم که وقتی اون خطا رو دیدن، کاربر رو لاگ اوت کنن. خلاصه که راه برای رسیدن به نتیجه مطلوب زیاده. بگذریم، بعد از این، در پوشه مدلها لازمه که یک فایل به اسم jwt_denylist.rb ایجاد کنیم و این محتوا رو درونش قرار بدیم:
class JwtDenylist < ApplicationRecord
include Devise::JWT::RevocationStrategies::Denylist
self.table_name = 'jwt_denylist'
end
بعد نیاز داریم که برای این قضیه یک مایگرشن اضافه کنیم:
rails g migration CreateJwtDenylist
سپس، فایل مایگرشن که معمولا در آدرس:
db/migrate
قرار داره رو باز میکنیم و محتواش رو به این شکل تغییر میدیم:
class CreateJwtDenylist < ActiveRecord::Migration[6.1]
def change
create_table :jwt_denylist do |t|
t.string :jti, null: false
t.datetime :exp, null: false
end
add_index :jwt_denylist, :jti
end
end
و بعد یک دور مایگرشنها رو اجرا میکنیم:
rails db:migrate
تا اینجا مطلب طولانی شد؟ ایرادی نداره. بریم یک قهوه بزنیم به بدن و برگردیم 🙂
کنترلر Session
امیدوارم که کافئین به قدر کافی مودتون رو بالا آورده باشه 🙂 حالا وقتشه که بریم و کنترلر session رو درست کنیم. نیازی نیست واقعا کار خاصی کنیم. تنها کاری که نیازه بکنیم اینه که کنترلری که ساختیم رو باز کنیم و این موارد رو درش کپی کنیم:
class Users::SessionsController < Devise::SessionsController
respond_to :json
private
def respond_with(resource, _opts = {})
render json: { message: 'You are logged in.' }, status: :ok
end
def respond_to_on_destroy
log_out_success && return if current_user
log_out_failure
end
def log_out_success
render json: { message: "You are logged out." }, status: :ok
end
def log_out_failure
render json: { message: "Hmm nothing happened."}, status: :unauthorized
end
end
نکته مهم، اگر هنگام ساخت کنترلر، جای users از چیز دیگری استفاده کردید باید Users رو در کد بالا به اون تغییر بدید. اگر هم کلا چیزی نذاشتید، کل قسمت Users:: رو ازش حذف کنید.
کنترلر Registration
خب عین همون بخش قبلی، شما کافیه کنترلر registrations رو باز کنید و این کد رو درونش کپی کنید:
class Users::RegistrationsController < Devise::RegistrationsController
respond_to :json
private
def respond_with(resource, _opts = {})
register_success && return if resource.persisted?
register_failed
end
def register_success
render json: { message: 'Signed up sucessfully.' }
end
def register_failed
render json: { message: "Something went wrong." }
end
end
تنظیمات نهایی devise
خب اول در ترمینال (یا cmd) این دستور رو اجرا کنید:
rake secret
و یک کد طولانی و مسخره بهتون میده 😁 اون رو در فایل:
config/initializers/devise.rb
در آخر فایل به این شکل کپی کنید:
config.jwt do |jwt|
jwt.secret = rake_secret_output
end
نکته بسیار مهم اینجا چیه؟ این که حواستون باشه این صرفا یک پروژه تسته و برای محیط پروداکشن اصلا جالب نیست که سیکرتها و توکنها، هاردکد باشن. برای اون زمان میتونید از ENV استفاده کنید.
مسیرها
خب، الان که تقریبا همهچی آرومه و ما چقدر خوشحالیم، کافیه که بیاییم و فایل routes.rb رو هم به این شکل ویرایش کنیم:
Rails.application.routes.draw do
devise_for :users,
controllers: {
sessions: 'users/sessions',
registrations: 'users/registrations'
}
end
خب پس چی میمونه که انجام ندادیم؟ یک سری آزمایش ساده 🙂
ساخت کاربر
خب الان کافیه بعد اجرای سرور ریلز (مطابق آموزشهای قبلی)، این دستور رو اجرا کنیم:
که اینها سرایند (Header) های ما هستند. در این قسمت، هرچی جلوی Authorization قرار داره توکن ماست. و میتونیم ازش استفاده کنیم.
بخش بعدی هم اینه :
{"message":"You are logged in."}
که صرفا به ما میگه ورودمون موفقیتآمیز بوده.
فکر کنم این مطلب، آخرین مطلبی بود که در مورد بیسیکهای روبیآنریلز مینوشتم. احتمالا در آینده نهچندان دور، همه اینها رو با هم به یک سری آموزش ویدئویی تبدیل کنم و از طریق آپارات یا یوتوب منتشرشون کنم.
طبیعتا یک قسمتهایی از آموزش در این مطلب پوشش داده نشده، سعی میکنم در آینده یک یا دو پست تکمیلی هم ارائه کنم که همه این قضایا به خوبی پوشش داده بشه (یا این که کلا در بخش ویدئویی در خدمتتون باشم).
به صورت کلی، دوست دارم بدونم نظر شما در مورد این تیپ آموزشها چیه؟ آیا ادامهشون بدم یا خیر؟ و این که آیا پایهش هستید که بحث فرانتند رو هم شروع کنیم یا روی همین بکند باقی بمونیم و اول یه پروژه کامل رو بکندش رو بزنیم و بعد بریم سراغ فرانت؟ 🙂
در آخر هم بابت وقتی که گذاشتید و مطلب رو خوندید ازتون متشکرم.
وبلاگ شخصی محمدرضا حقیری، برنامهنویس، گیک و یک شخص خوشحال