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

Click the image to see it in the original size
Originally from: http://herbsutter.com/2012/01/10/map-of-c/
پروژهی اویلر، مجموعهای مسالههای جالبی که اگر اهل برنامهنویسی باشید احتمالا میتواند تا مدتها شما را سرگرم کند. یک نگاهی بیندازید جالبه
http://projecteuler.net

از یک مدت پیش شروع کردم به خارج کردن کدهام از Matlab. برای خیلی از کارهای اسکریپتی، پایتون گزینهی خیلی خوبی بود. اما خوب وقتی بحث کارهای محاسباتی و حجم بالای داده میرسه، C++/C گزینهی بسیار جذابتری میشود. یکی از انگیزههای اصلی من در استفاده از Matlab پیادهسازی و استفادهی خوب و موثر از کتابخانههای توابع BLAS/LAPACK بوده. چون بدون آنها نوشتن کدها سریع تقریبا غیر ممکن است.

اما مشکل اصلی من چی بود؟ کتابخانههای BLAS/LAPACK فقط رابط برنامهنوسی با زبان C دارند و برای همین خیلی خوشدست نیستند (سرعت در مقابل راحتی). چند باری سعی کرده بودن از رابطهایی که برای کار با ++C طراحی شدهاند استفاده کنم، اما همچنان یا کار کردن باهاشون راحت نبود و یا سرعت محاسبات را به شدت کاهش میدادند. اخیرا کتابخانهی Armadillo را پیدا کردهام و با چند بار استفاده به این نتیجه رسیدهام که گزینهی خیلی خوبیه! هم راحت است و هم سریع.
کسی نظری نداره؟ کسی از کتابخانهی مشابهی استفاده کرده که راضی باشه؟ یا کسی مشکلی در استفاده از Armadillo دیده؟
در حال تغییر دادن بعضی قسمتهای کد بودم که دیدم, نسخه GCC اوبونتوی ۴٫۴ است و این نسخه lambda را پشتیبانی نمیکند
برای همین فعلا دارم GCC 4.6 را روی کامپیوترم نصب میکنم. خلاصه اگر میبینید که آمدهام خاک این وبلاگ را میتکانم فکر نکنید تحولی در من رخ داده و من دست از تنبلی کشیدهام. داستان همان داستان سابق است, خر در گل گیر کرده و بیرون بیا هم نیست ...
برای جلوگیری از اختراع مجدد چرخ، سعی کردهم از قسمتهایی از یک برنامهی کدباز که توسط یک همکار آکادمیک فراهم شده بود، را استفاده کنم، از یک طرف کارم سریعتر انجام میشود و از طرف دیگر، گرفتار ظریفکاریهای پیادهسازی ایده از روی مقاله نمیشوم، چون اصولا ایدهی مطرح شده در مقالات کلی جزئیات داره که هیچکس حوصلهی مستندسازی آنها را ندارد و موقع پیادهسازی جد و آباد آدم رو جلوی چشماش میآورد.
حالا نمیخواهم از بلایی که سرم آمد تا ورودی/خروجیهای این برنامه را به برنامهی خودم وصل کنم، را براتون بگم. کد را که را انداختم، دیدم که این داد بیداد این کد که جونش در میآد تا اجرا بشود (دست گل جناب معزز Matlab) و یعنی رسما ۲ ماه زمان CPU نیاز داشتم تا فقط یک بار اجرایش کنم!!!! و نه تنها deadline یک کنفرانس نازنین در هاوایی را از دست دادم، بلکه درست قبل از ایران رفتنم با استاد عزیز (شنگول) یک دعوای خونین هم کردم
.
خلاصه، ناامید و دست-از-پا-درازتر نشتم و الگوریتم مورد بحث را با ++C پیادهسازی کردم (۶۰۰ برابر افزایش سرعت) و حالا یک برنامهی خوشگل و سریع دارم که داره مثل بچهی آدمیزاد کار میکند. نتیجهی اخلاقی هم اینکه زور بازو نان خوردن بهتر ز مچل شدن با کد matlab داغون مردم است.
این چند روزه مشغول کار روی پروژهای هستم که احتمالا آخرین کار من در اینجا خواهد بود. برای پیادهسازی قسمتی از کار رفتم سراغ openCV. فکر کنم ۳-۴ سال از آخرین باری که به صورت جدی با openCV کار کرده بودم گذشته. متوجه شدم در نسخههای اخیر openCV یک رابط ++C هم به این کتابخانه اضافه شدهاست که واقعا دست توسعه دهندگانش درد نکند. ولی خوب هر چه در اینترنت گشتم کمتر در مورد این کتابخانه پیدا کردم. خلاصه فعلا به صورت کاملا مزبوحانه و صورت کوشش و خطا در حال کشف این رابط جدید هست. خلاصه باید بیایید و ببینید چه آش شل-و-قلمکاری شده این کد من.
تا جایی که من فهمیدم، این رابط جدید (شاید هم دیگر قدیمی)، کد را بسیار خوانا و زیباتر میکند. ولی با این حال، کسی راهنمایی بز فهم C++ API برای opneCV سراغ نداره؟
کمیتهی استانداردسازی ++C، ابتدا در آگوست ۲۰۱۰ و سپس در نوامبر۲۰۱۰، پیشنویس استاندارد جدید را با نام C++0X معرفی کرد. البته از خیلی قبل (TR1, 2005) مردم تقریبا میدانستند که چه چیزهایی قرار است در استاندارد جدید ارائه شود و کامپایلرهای مختلف هم کمکم شروع به پیاده سازی C++0x کردهبودند. در لینوکس من معمولا از GCC و در ویندوز هم از VC به عنوان کامپایلر استفاده میکنم. هر ۲ کامپایلر هر چند هنوز تا پیادهسازی کامل استاندار فاصله دارند، ولی با این وجود قسمتهای پیادهسازی شده به قدری جذاب هستند که من به هر کسی که به صورت روزمره از ++C استفاده میکند، توصیه میکنم که یک هفتهای کار و زندگیاش را تعطیل کند و برود ببیند C++0x چطور میتواند کدهایش را بهینه کند و کارش را سریعتر کند.
ظاهرا جناب پت برای وبلاگنویسی خیلی پیر شده و باید برود یک فکری به حال خودش بکند. امروز ۲-۳ ساعت وقت نازنینم را گذاشتم تا یک افزونهای، چیزی نصب کنم که بشود به کمکش کد زبانهایی مثل C و Java وسط پست قرار داد. ولی نشد که نشد. ۳- ۴ تا از افزونههای معروف را امتحان کردم. ولی ظاهرا پلاگین فارسی وردپرس با تمام این افزونهها مشکل دارد و مدام ما را ضایع میکند.
منتظر حمایت سبز شما از iampat در IEEEXtreme 4 هستیم.
التماس دعا
پس نوشت ۱ : قضیه معرکهگیری سر پیریه! کلا توی اواخر دههی سوم زندگی حضور مسابقات قهرمانی یک جور شوخی محسوب میشود ولی بعد از ۳۰ دیگر حتی شوخی هم نیست. حالا ورزش باشد یا برنامهنویسی، فرقی نمیکند!
پس نوشت ۲: اگر یادتون باشد گفته بودم که مشغول کاری هستم که صداش ۲۹ آبان امسال در میآید. متاسفانه بدلیل اندکی آسیبدیدگی آن قضیه فعلا منتفی شد ولی امیدوارم قبل از ۳۰ سالگی اون قضیه هم به سرانجام برسد. التماس دعا