چطوری کپچای سیستم گلستان رو با کمک یادگیری ماشین بشکنیم؟

همه‌ی ما از کپچا (CAPTCHA) فراری ایم - همون تصاویر مزاحمی رو میگم که نوشته های درهم ریخته است و برای اینکه به فرم یا صفحه ای از سایت دسترسی داشته باشیم باید اونو تایپ کنیم. کپچاها برای تشخیص انسان از بات ها (همون برنامه های اتوماتیک) و معمولا برای جلوگیری از ورود به بخشی خاص، جلوگیری از پر کردن فرم ها یا کاهش برخی حملات طراحی شدند. جالبه بدونید در حال حاضر مدتی است که کپچاهای متنی محبوبیت خودشون رو از دست دادند و جای خودشون رو به کپچاهای تصویری یا موارد مشابه دادند.نمونه ای از کپچای گوگل جایگزین مناسبی برای کپچاهای متنیسیستم گلستان رو تقریبا همه می شناسند. سیستم اتوماسیون معروف دانشگاه های ایران که پیدا کردن هر چیزی داخل اون نیازمند یک دوره دکتری تخصصی "زبانهای رسمی و روش های صوری" است!توی این پست قصد داریم با رویکرد آموزشی و مرحله به مرحله، شکستن کپچای متنی سیستم گلستان رو با بهره گیری از قدرت یادگیری ماشین/عمیق و داده های آماری بررسی کنیم. توصیه میشه اگر دنبال دردسر نیستید این کار رو توی خونه امتحان نکنید? .برای شروع ماجراجویی، اول نگاهی به فرم ورود سیستم گلستان به همراه تصویر کپچای متنی می اندازیم:صفحه ورود سیستم گلستانتوی این صفحه یک تصویر جداگانه وجود داره که از طریق آدرس تصویر میشه بهش دسترسی داشت. بنابراین قدم اول ذخیره تعداد زیادی از این تصاویر هست تا با اون ها در مرحله بعد یک شبکه عصبی مصنوعی کانولوشنال (شبکه ای برای استخراج ویژگی ها از تصاویر و کلاس بندی) رو آموزش بدیم. نهایتا شبکه آموزش داده شده میتونه تصاویر ورودی رو به متن مورد نظر ترجمه کنه. جمع آوری داده آموزشیخُب، معمولا هر الگوریتم یادگیری ماشین برای آموزش نیازمند داده های زیادی هست. شکستن کپچا هم از این قاعده مستثنی نیست. بنابراین برای اینکه بتونیم یک کپچای متنی رو بشکنیم، نیازمند تعداد زیادی تصویر هستیم. برای اینکار یک اسکریپت ساده Shell میتونه چاره کار باشه. https://gist.github.com/hkhojasteh/51adc98053cc1d11a72aaca8e911964d این اسکریپت سعی میکنه تعداد زیادی از فایل های تصویر رو دانلود کنه و با فرمت gif. ذخیره کنه (فرمت فایل های خروجی کدی هست که کپچا رو در سیستم اصلی تولید میکنه). نمونه ای از تصاویر کپچاهای استخراج شده از سیستم گلستانحالا حدالامکان تصاویر ورودی به سیستم رو به ساده ترین شکل ممکن تبدیل می کنیم. بدین منظور سعی میکنیم تا نوشته پایین تصاویر رو حذف کنیم.در این مطلب از کتابخونه OpenCV فریم ورک محبوب بینایی کامپیوتر و پردازش تصویر و زبان ++C برای پیش پردازش تصاویر استفاده خواهیم کرد (اگر علاقمندید این کتابخونه Python API داره و می تونید از اون هم استفاده کنید). https://gist.github.com/hkhojasteh/c1a60d4bc6858db8a7dece2a0208d29d کد بالا بخش پایین تصویر ورودی رو حذف میکنه که به عنوان یک آرگومان دریافت شده. بنابراین تا اینجای کار داده های آموزشی برای سیستم یادگیری مون رو در اختیار داریم.پیش پردازش تصاویرسیستم تشخیص کپچای ما می تونه مطابق شکل از شبکه عصبی مصنوعی برای پردازش تصاویر و برای شناسایی متن تصویر تشکیل شده باشه که یک تصویر از کپچای متنی رو به عنوان ورودی دریافت کرده و جواب صحیح رو تولید میکنه.رویکرد کلی سیستم یادگیری برای شکستن کپچابا داشتن داده های آموزشی کافی، رویکرد کلی بالا پاسخ درستی تولید می کنه؛ یعنی فقط کافیه تعداد خیلی زیادی تصویر رو به یکی از لایه های شبکه عصبی کانولوشنال (Convolutional Neural Network) (احتمالا با یک معماری پیچیده و با تعداد لایه و پارامتر زیاد) که وظیفه پردازش تصویر رو داره بدیم و با یک لایه دیگه از شبکه عصبی که وظیفه پیش بینی در مورد کل تصویر رو داره مسئله رو حل کنیم. اما این رویکرد با کمی تغییرات پاسخ های بهتر با محاسبات کمتر رو تولید میکنه. پس سعی میکنیم به جای پیش بینی کل تصویر فقط یک حرف رو پیش بینی کنیم و تصویر رو به چند تصویر شامل حروف (یا اعداد) تبدیل کنیم. واضح هست که برای تعداد زیادی تصویر راه حل فتوشاپ توصیه نمیشه!خوشبختانه کپچایی که ما قصد شکستن اون رو داریم از پنج حرف تشکیل میشه. بنابراین اگر بتونیم روشی برای جداکردن حروف در تصویر داشته باشیم، شبکه عصبی تنها نیاز داره تا یک حرف رو کلاس بندی (Classify) کنه. یک روش ساده شکستن تصویر افقی به پنج قسمت مساوی هست. اما اگر به نمونه های دریافت شده در تصویر دقت کنید، ممکنه به دلیل جمع شدن حروف در یک طرف، حروف به درستی قطعه بندی (Segmentation) نشن. بنابراین برای اینکه محل دقیق تقسیم بندی در تصویر رو پیدا کنیم، سعی میکنیم تا تجمع پیکسل های غیر سفید در تصویر رو پیدا کنیم (یا به صورت ساده تعداد پیکسل در هر خط عمودی رو بشماریم)، و از اونجاییکه بین حروف فاصله کمی وجود داره، تعداد پیکسل بیشتر با تقریب خوبی جای هر حرف در تصویر رو به ما نشون میده. بعد از اینکار یک الگوریتم خوشه بندی (Clustering) می تونه به طور موثر تصویر رو به پنج بخش مختلف تقسیم کنه.ابتدا باید تصویر ورودی تبدیل به تصویر سیاه و سفید بشه و بخشی از نویز اون نیز حذف بشه تا مطمئن بشیم همه چیز به بهترین نحو ممکن انجام میشه. https://gist.github.com/hkhojasteh/a88e6a14bfd2cd900a4ff85bfb304d1f کدهای بالا با پردازش تصویر، جادوی زیر رو انجام میده:مراحل پردازش تصویر ورودیبرای قطعه بندی تصاویر؛ یعنی برش تصویر به کاراکترهای جداگانه، ساده ترین روش استفاده از نمودار هیستوگرام (Histogram) و یافتن دسته هایی از پیکسل هاست که در جای خاصی تجمع دارند. https://gist.github.com/hkhojasteh/18cfb5efd6d1fa62796ad898e434788f نمودار هیستوگرام تعداد پیکسل ها برای قطعه بندی تصویر به ازای کپچای ورودی بالا سمت راست نمودارهمون طور که در تصویر هم می بینید نقاطی که افت شدید مقدار داره، دقیقا مکان های متناظری هستند که باید تصویر برش داده بشه تا تصاویر کاراکترها استخراج بشند.از اونجاییکه این روش با پیچیدگی هایی همراه هست، ما در اینجا با روش خوشه بندی k-means سعی میکنیم تا بهترین مکان برای جداسازی تصویر بعد از فیلتر رو پیدا کنیم. توی این روش از تصویر نهایی به شکل ماتریسی از صفر و یک ها (فقط نقاط سفید) که در مرحله قبل ایجاد کردیم، استفاده میکنیم. پنج نقطه اولیه تصادفی در ماتریس انتخاب میکنیم. با روش k-means سعی میکنیم نقاط درون تصویر رو به پنج خوشه (Cluster) تقسیم کنیم. نقطه مرکز هر خوشه، مرکز هر کاراکتر خواهد بود. https://gist.github.com/hkhojasteh/32802712b675359c309716c4d1d42ae1 نتیجه کدهای بالا باورنکردنیه:خروجی خوشه بندی پیکسل ها برای یافتن مرکز کاراکترها و قطعه بندی تصاویرپردازش های بیشتری هم میشه روی تصویر انجام داد. مثلا برخی تصاویر که کنتراست (Contrast) کمتری دارند، قابلیت نرمال سازی و افزایش کنتراست رو دارند یا برای جداسازی از روش شمارش تجمعی، کاراکترهایی با طول های متفاوت رو جدا کرد. تا همین میزان پردازش برای ایجاد ورودی های شبکه عصبی؛ یعنی همون کاراکترهای جداگانه با اندازه ثابت، کافی است (اگر دوست دارید شما می تونید تا میزان دلخواه پردازش روی تصویر انجام بدید.).ساخت و آموزش شبکه عصبی مصنوعیاز اونجاییکه ما فقط نیاز به تشخیص یک تصویر از حرف یا عدد داریم، نیازی به معماری پیچیده برای شبکه عصبی نداریم. شناسایی حروف یک مسئله بسیار ساده تر از تشخیص یک تصویر پیچیده (مثل تصاویری از سگ یا گربه که تنوع زیادی داره.) است. در اینجا ما برای حل مسئله شکستن کپچا از یک معماری شبکه عصبی مصنوعی با دو لایه کانولوشنال (Convolutional) همراه با Max Pooling و دو لایه تماما متصل (Fully-Connected) استفاده می کنیم. اگر شما این شبکه عصبی ها رو نمیشناسید نگران نباشید. در اینجا نیازی به پیاده سازی های سطح پایین نداریم. اگر علاقمند به یادگیری بیشتر در این زمینه هستید، ویکیپدیا یا این کتاب رو بررسی کنید.معماری شبکه عصبی مصنوعی کانولوشنال برای شکستن کپچابرای سادگی آموزش در اینجا از TensorFlow؛ کتابخونه یادگیری ماشین گوگل، برای ایجاد شبکه استفاده خواهیم کرد. پیاده سازی این مدل به شکل زیر خواهد بود: https://gist.github.com/hkhojasteh/eb67fbfa751663896b54cb8d2952560e اگر بخش های دیگه کد رو هم به این مجموعه اضافه کنید و خوش شانس باشید خروجی زیر رو می بینید:2018-04-25 11:45:45.927302: step 0, loss = 4.68 (2.0 examples/sec; 64.221 sec/batch) 2018-04-25 11:45:49.133065: step 10, loss = 4.66 (533.8 examples/sec; 0.240 sec/batch) 2018-04-25 11:45:51.397710: step 20, loss = 4.64 (597.4 examples/sec; 0.214 sec/batch) 2018-04-25 11:45:54.446850: step 30, loss = 4.62 (391.0 examples/sec; 0.327 sec/batch) ...داده های آموزشی برای این شبکه نیازمند برچسب هستند، برای اینکار می تونید مدل رو ابتدا با مجموعه تصاویر EMNIST آموزش بدید و بعد با تصاویر اصلی استخراج شده آموزش رو انجام بدید. دقت این مدل رو میشه به ازای داده های ورودی اندازه گرفت، نمودارهای مختلف مثل دقت-سرعت رو در زمان اجرا با استفاده از داشبورد مربوطه رصد و بررسی کرد و کلی کار دیگه که می تونه دقت و سرعت مدل رو افزایش بده. با پیاده سازی مدل یادگیری عمیق، حالا ما می تونیم به صورت خودکار کپچای سیستم گلستان رو بشکنیم! این مطلب به صورت کامل در گیت هاب در دسترس هست. همچنین اگر علاقمند به موضوعات هوش مصنوعی، یادگیری ماشین و بینایی کامپیوتر هستید می تونید من رو در توییتر دنبال کنید. ماشین خودکار هوشمند برای بازی کمپین دیجیکالا، تخفیفان و شاتل از توییتراین ماجراجویی تموم شد. حالا نوبت شماست که دست به کار بشید، سیستم تشخیص کپچای دلخواهتون رو طراحی کنید و تجربیاتتون رو به اشتراک بذارید. به نظر شما راهکار جایگزین برای کپچاهای سنتی چه ویژگی هایی باید داشته باشه تا هوش مصنوعی نتونه اون رو بشکنه؟ https://virgool.io/@hadiakhojasteh/how-to-build-an-intelligent-car-with-image-processing-rkgz4q8v37xg