 هدف این پروژه در ابتدا دسته بندی انواع مختلف اعداد دست نویس فارسی بر اساس شکل ظاهری و سپس طبقهبندی ارقام دستنویس ورودی به مشابه ترین گروه به منظور تشخیص رقم مربوطه است. برای دسته بندی ها از مجموعه ارقام دست نویس فارسی تهیه شده تا کنون بهره برده می شود و برای تشخیص شباهت عدد ورودی به هر کدام از دسته ها میتوان از هریک از روشهای طبقهبندی استفاده کرد. در این پروژه چند روش برای طبقهبندی ارقام که به نظر مناسبتر هستند بررسی و مقایسه شوند. # مقدمه اگر یک تصویر از عدد فارسی " ۷ " را - فارغ از خوش خط یا بد خط بودن نویسنده - درمقابل ما بگیرند و از ما بخواهد که تشخیص دهیم که این عدد کدام یک از اعداد را نشان می دهد ، پاسخ به این برای ما - انسان ها - بسیار آسان خواهد بود. اما اگر از ما بخواهند دو عدد ۳ رقمی را در هم ضربکنیم برای محاسبه آن احتمالا به زمان قابل توجهی و یک قلم و کاعذ نیاز خواهیم داشت. حال فرض کنیم یک ماشین در مقابل همین ۲ پرسش قرار گیرد. محاسبه ضرب دو عدد برای یک ماشین یک سوال بسیار آسان است در حالی که برای یک انسان بسیار زمان بر است. و در عین حال فهمیدن و تشخیص حرف " گ " برای یک ماشین (موجودیتی که تنها صفر و یک میفهمد) و تنها میتواند یک درک داده ای و سطح پایین از یک تصویر بر اساس رنگ ها و پیکسل هایش داشته باشد یک کار بسیار دشوار است. تفاوت اصلی در نوع حل مساله در انسان ها و ماشین ها است. ماشین ها توانایی بسیار زیادی در محاسبه دارند اما انسان ها توانایی بسیار بالایی در یادگیری. نکته دیگری که از این مقایسه قابل برداشت است این است که یک انسان در نهایت میتواند حاصل ضرب دو عدد را محاسبه کند اما آیا یک مایشن هم تنها با تکیه بر قابلیت های محاسبه ای خود میتواند یک نوشته را بخواند؟ واقعیت این است نوشتن یک الگوریتم برای انجام عمل خواندن متن و تشخیص صحیح تک تک کاراکتر های آن، حداقل تا به امروز برای ما به عنوان برنامه ریز های ماشین ها امکان پذیر نبوده. علاوه بر این موضوع باید توجه داشت که توانایی یاد گرفتن عامل اصلی برتری انسان بر ماشین میباشد و همین موضوع ، یعنی قابلیت یادگیری انسان موجب شده که بتواند یک ضرب بسیار سخت را در نهایت انجام دهد اما یک کامپیوتر در یک زمان معقول نتواند به تنهایی یک حرف را تشخیص دهد. نتیجه کلی مقایسه بالا این کلیّت را در بر دارد که برای حل برخی از مسایل پیچیده باید به دنبال دسته ای کلی از الگوریتم ها باشیم که به کامپیوتر توانایی یادگیری آن مساله را ببخشد ، نه توانایی صرفا حل آنرا ، دقیقا مشابه مغز انسان. این دسته از الگوریتم ها به الگوریتم های یادگیری ماشین (Machine Learning) معروف هستند. یادگیری عمیق (Deep Learning) شاخه ای از این الگوریتم ها هستند که برای حل اینگونه مسایل استفاده میشوند.در یادگیری عمیق امید به جایگزینی استخراج ویژگیهای تصویر به دست بشر با روشهای کاملا خودکار بدون نظارت انسان وجود دارد. انگیزهٔ نخستین در بوجود آمدن این ساختار یادگیری از راه بررسی ساختار عصبی در مغز انسان الهام گرفته شده است که در آن یاختههای عصبی با فرستادن پیام به یکدیگر درک را امکانپذیر میکنند.[1] بسته به فرضهای گوناگون در مورد نحوهٔ اتصال این یاختههای عصبی، مدلها و ساختارهای مختلفی در این حوزه پیشنهاد و بررسی شدهاند، هرچند که این مدلها به صورت طبیعی در مغز انسان وجود ندارد و مغز انسان پیچیدگیهای بیشتری را دارا است. این مدلها نظیر شبکه عصبی عمیق(Deep Neural Network) و شبکه عصبی پیچیده (Convolutional Neural Network) پیشرفتهای خوبی را در حوزههای پردازش زبانهای طبیعی و پردازش تصویر ایجاد کردهاند.در حقیقت عبارت یادگیری عمیق، بررسی روشهای تازه برای شبکه عصبی مصنوعی (Artificial Neural Network) است.[2] ایده ی پشت حل این مسئله این است که تعداد زیادی از اعداد دست نوشته ( مثال های یادگیری) و سیستم ای که از این مثال ها یاد بگیرد را داسته باشیم . به عبارت دیگر شبکه عصبی مصنوعی از این مثال ها استفاده میکند تا اعداد دست نوشته را تشخیص دهد . هرچه تعداد مثال های دست نوشته بیشتر شود تشخیص کامپیوتر بهتر و دقیق تر می شود . # کارهای مرتبط برای شروع ، نورون (neuron ) مصنوعی به نام پرسپترون (perceptron) را توضیخ می دهم. یک پرسپترون تعدادی ورودی باینری مثل x1 ، x2 ، ... دریافت میکند و یک خروجی باینری را تولید میکند. محققین برای محاسبه ی خروجی یک متغیر به اسم وزن (weight) تعریف کرده اند . W1 ، w2، ... به ترتیب میزان اهمیت هر ورودی را مشخص میکنند . خروجی هر نورون با فرمول سیگما به دست می آید . به این صورت که اگر از مقدار آستانه (threshold) بیشتر باشد عدد ۱ و اگر کمتر باشد عدد ۰ را بر میگرداند .  به نظر محتمل میآید که یک شبکه پیچیده از پرسپترون ها خروجی تقریباً دقیقی را تولید کنند . وزن هر ورودی در تعیین خروجی نقش بسیار مهمی دارد. به این صورت که در دفعه ی اول به صورت رندوم انتخاب وزن برای هر ورودی انجام می شود. در دفعات آینده با توجه به درست یا غلط بودن خروجی ، وزن ها با یک فرمول ریاضی تغییر پیدا میکنند . این تغییر انقدر انجام میشود تا وزن ها طوری باشند که خروجی صحت داشته باشد.  در این شبکه ، ستون اول پرسپترون ها ( که به آن لایه ی اول پرسپترون ها میگوییم) با در نظر گرفتن وزن هر ورودی تصمیم ساده ای را اتخاذ میکنند . پرسپترون ها در لایه ی دوم با توجه به وزن خروجی بدست آمده از لایه ی اول خروجی را تعیین میکنند . لایه ی دوم در حالت پیچیده تری نسبت به لایه ی اول تصمیم میگیرد و خروجی ای نزدیک به واقعیت تولید میکند . و در لایه ی سوم تصمیم گیری پیچیده تر و خروجی بیشتر به واقعیت نزدیک میشود. با این روش پرسپترون هایی با تعداد لایه ی زیاد می توانند تصمیمات پیچیده تری را بگیرند. حال میخواهیم توضیحاتی را که در مورد پرسپترون ها دادیم ساده کنیم. اولین تغییر این است که به جای سیگما مینویسیم w.x . تغییر دوم این است که عدد آستانه (threshold) را به طرف دیگر تساوی انتقال میدهیم و با چیزی که به عنوان perceptron bias ، شناخته میشود جایگزین می کنیم . (Bias = -threshold ) . نا مساوی را به صورت زیر بازنویسی میکنیم :  در این بخش سیگموید (sigmoid) را معرفی میکنیم که بسیار شبیه به پرسپترون است. سیگموید هم درست مثل پرسپترون تعدادی وروذی دارد که بر عکس پرسپترون فقط ۰ و ۱ را قبول نمیکند و هر عددی بین ۰ و ۱ را قبول میکند. همینطور مشابه پرسپترون ، نورونِ سیگموید هم برای هر ورودی وزن تعیین میکند و bias دارد . خروجی این نورون فقط ۰ یا ۱ نیست و تمامی اعداد بین ۰ و ۱ میتواند باشد . تابع سیگموید به صورت زیر تعریف میشود :   همواری تابع سیگموید است که بسیار حیاتی است نه فرم دقیق آن . منظور از همواری سیگموید این است که با هر تغییر کوچک wj و bias تغییر کمی در خروجی نورون اتفاق می افتد . چگونه از نورون سیگموید خروجی استخراج کنیم؟ به طور مشخص یک تفاوت بزرگ بین نورون های پرسپترون و سیگموید این است که خروجی نورون های سیگموید فقط ۰ و ۱ نیست. هر خروجی ای بین ۰ و ۱ می توانند داشته باشند . این ویژگی سیگموید هم میتواند مفید باشد و هم آزار دهنده. برای مثال اگر بخواهیم تشخیص دهیم که آیا تصویر ورودی ۹ را نشان میدهد یا خیر اگر خروجی به صورت ۰ یا ۱ بود ، تشخیص ساده تر میشد . اما برای تشخیص این عدد با نورونِ سیگموید باید شرط بگذاریم که اگر خروجی از ۰.۵ بیشتر بود عدد ۹ است و اگر کمتر بود عدد ۹ نیست . اگر برای تشخیص یک عدد در لایه ی آخر ۱۰ نورونِ سیگموید داشته باشیم ( هر نورون برای هر یک از ارقام ۰ تا ۹ که برای هر ورودی وزن و هر نورون bias مخصوص به خود دارند ) جواب به این صورت انتخاب میشود که خروجی نورونی که از همه بزرگتر باشد . که این کار با استفاده از نورون های پرسپترون امکان پذیر نیست . ( از آنجایی که تمانی خروجی نورون های پرسپترون ۰ یا ۱ است) . [3] [4] # آزمایش ها برای پیاده سازی این پروژه از کتابخانهی tensorflow استفاده شده است. یکی از دلایل استفاده از این کتابخانه سهولت مدیریت وزنها و مقادیر نُرون ها در لایههای مختلف در شبکههای عصبی عمیق و یادگیری عمیق است.[5] ##داده ها در این مرحله از پیاده سازی از مجموعه ی داده ی MNIST استفاده شده است که مجموعه ای از ارقام دستنویس انگلیسی است[6]. علت استفاده از MNIST سهولت در استفاده از آن است. در مرحله ی بعد پیاده سازی از مجموع دادگان هدی استفاده می شود. ##پیاده سازی شبکه عصبی پیاده سازی شده به شرح زیر است : لایهی ورودی دارای ۷۲۸ نرون است که به اندازهی پیکسل های عکس است. سه عدد لایهی مخفی پیاده سازی شده است که هر کدام ۲۵۶ نرون دارد. و در لایهی آخر ۱۰ کلاس خروجی تعریف شده است که هر کدام نشانگر یکی از اعداد ۰ تا ۹ است.  برای هر لایه ، وزن ها و bias ها به صورت تصادفی انتخاب میشوند و به مرور زمان در طی یادگیری وزنها و bias ها طوری تنظیم میشوند که خروجی نزدیک به واقعیت شود و میزان خطا کمینه میشود. ##توضیحات دقیق تر چگونگی پیاده سازی هر نورون ضرب نقطه ای بین ورودی و وزن آن نرون را انجام میدهد و سپس با bias جمع میکند. خروجی بدست آمده به تابعی به نام ReLU داده میشود [7]. تابع ReLU به این صورت است که اگر ورودی آن از صفر کوچک تر باشد خروجی تابع صفر است و اگر ورودی آن از صفر بزرگ تر باشد خروجی برابر ورودی است. برای اینکه چگونگی تغییر وزن ها مشخص شود باید پارامتری تعریف کنیم به نام Learning rate . برای اینکه دلیل اهمیت این پارامتر بیشتر مشخص شود نگاهی به عملکرد مغز انسان می اندازیم. همانطور که احتمالا بارها تجربهاش را داشتهایم ، هنگامی که برای اولین بار با یک مسئلهی جدید رو به رو می شویم حل آن مسئله به شدت دشوار به نظر می آید. در صورتی که اگر از قبل تمرینهای سادهتر اما مشابه دیده بودیم حل آن مسئله آنقدر ها هم دشوار به نظر نمی رسید. در مورد نرون ها هم همینگونه است باید به صورت تدریجی وزن ها تغییر کند تا به خروجی قابل اعتمادی دست یابیم. نتیجه کلی این است که: > در صورت کوچک بودن learning rate یادگیری قابل اعتماد تر است اما زمان بیشتری طول میکشد تا به کمینه تابع خطا برسیم. با بزرگ بودن learning rate تغییرات در وزن ها بسیار زیاد میشود و این باعث میشود به تابع خطای کمینه نرسیم و جواب ها غیرقابل اعتماد میشود. در این پروژه در ابتدا learning rate را ۰.۰۰۱ گذاشتیم و دیدیم که درصد درستی جواب ها ۹۲ بود. این عدد را به ۰.۰۰۴ افزایش دادیم و درصد درستی جواب به ۹۷ رسید. با افزایش این عدد به ۰.۰۰۵ درصد درستی جواب ها به ۹۴ درصد کاهش پیدا کرد. در پیاده سازی این پروژه از تابع خطای cross-entropy استفاده شده است. این تابع صحت خروجی شبکه عصبی را میسنجد و فاصلهی آن با جواب درست را نشان میدهد. با استفاده از عکس ها و برچسب مربوط به هر عکس وزن ها و bias ها طوری تعیین شود که تابع خطای cross-entropy به حداقل برسد. در پیاده سازی این پروژه از بهینهسازی به نام Adam استفاده شده است که در ابتدا از learning_rate تعریف شده استفاده میکند سپس در طی یادگیری این مقدار را تغییر میدهد. علاوه بر این نکتهی مهم این است که این تابع برای هر وزن از شبکه learning rate جدایی را اختصاص میدهد .به گفتهی نویسندگان مزایای اصلی این الگوریتم به شرح زیر است[8] : ۱- کم بودن حافظهی مورد نیاز ۲- مناسب برای مسائلی که دادهی بزرگ دارند ۳- سادگی در پیاده سازی در آخر برای تشخیص عدد از softmax استفاده می کنیم. تابع softmax خروجی های آخرین لایه را میگیرد و آنها را به اعدادی بین صفر و یک (مقدار احنمال یا امتیاز هر کلاس) تبدیل میکند و همچنین جمع تمام این اعداد ۱ می شود(عکس شماره ۱) . که ما در این جا با توجه به داشتن ۱۰ کلاسِ خروجی ۱۰ عدد بین صفر و یک داریم و از بین این اعداد بزرگترین آنها معرف آن کلاس است(عکس شماره ۲).   نتیجه ی پیاده سازی :  همانطور که در عکس مشاهده میکنید در 30 مرحله (epoch) یادگیری صورت گرفته است . در تصویر بالا مشاهده می کنید که 97 درصد از عکس ها درست تشخیص داده شده است. کد مربوط به پیاده سازی این پروژه را می توانید در [اینجا](https://github.com/mayahmir/AI-OCR-96) بیابید. #بهبود نتایج مهمترین هدف در این بخش پیادهسازی سیستم با استفاده از شبکههای عصبی عمیق Convolutional، به همراه استفاده از مجموعه دادهگان هدی است. # کارهای آیندهترین تغییرات ایجاد شده در این بخش استفاده از شبکههای کانولووشن و دادگاه فارسی هدی است. برای توضیح این مباحث، ابتدا مقدمهای بر شبکههای عصبی کانوولوشن را بیان خواهیم کرد و تفاوتهای آن با شبکههای قسمت قبل را بیان خواهیم کرد. سپس با معرفی دادگاه فارسی هدی به بررسی و مقایسه نتایج خواهیم پرداخت. ## شبکههای عصبی کانوولوشن معمولاً در همه شبکههای عصبی قدیمی فازی مهم و حیاتی در پیادهسازی به نام استخراج ویژگیها وجود دارد. در این بخش، برای کمک به فهم بهتر شبکه ، داده ورودی توسط یک خبره به دادههای معنادار تری تبدیل میشود. به عنوان مثال، برای تشخیص یک کاراکتر در عکس، یک خبره تصمیم میگیرد که میانگین کل پیکسلها، شیب عمودی و افقی تصویر و یک نسخه تار شده از تصویر ویژگیهای مناسبی برای یادگیری هستند. برنامهنویس شبکه موظف است که این ویژگیها را استخراج کند و به جای اینکه تصویر اصلی را به عنوان ورودی شبکه در نظر بگیرد، برآیند این ویژگیها را، که با نام بردار ویژگی شناخته میشود، به ورودی شبکه متصل کند (گاهی این ویژگیها در کنار ورودی اصلی قرار میگیرند و با هم ورودی شبکه تصویر میشوند). مشکل اصلی این روش این است که یک راهکار درست و مشخص ندارد و ممکن است برای هر عمل خاص متفاوت باشد. به عنوان مثال، ممکن است ویژگیهای مناسب برای تشخصی کاراکتر در تصویر با ویژگیهای مناسب برای تشخیص حیوان در تصویر متفاوت باشد. شبکههای کانوولوشن دقیقاً برای حل این مشکل ابداع شده اند و ویژگی متمایز آن این است که به صورت خودکار و با استفاده از عمل کانوولوشن میتواند بهترین دسته از ویژگیها برای انجام هر عمل خاص یا تشخیص هر نوع موجودیت در تصاویر متفاوت باشد. در بخشهای بعد خواهیم دید که این اتفاق چگونه در شبکههای کانوولوشن رخ میدهد. عمل معروف کانوولوشن که کاربردهای زیادی در زمینههای مختلف علوم کامپیوتر و برق دارد یک راه خودکار مناسب برای استخراج ویژگی از دادههای جبری در قالب بردار است. در این عملیات، با فرض ۲ بعدی بودن ورودی، یک بردار ۲ بعدی کوچکتر (با نام هسته kernel) روی بردار اصلی لغزانده میشود و حاصلجمع ضرب یکبهیک المانهای هسته و المانهای بردار اصلی، در مکانهای متناظر در مرکز المان متناظر به مرکز هسته جایگزین میشود. تصویر زیر این عمل را بر روی یک ورودی ۲ بعدی نشان میدهد.  در ادبیات پردازش تصویر، تمام فیلترهای معروف عکس مانند تار کردن، برراق کردن و لبهیابی، با استفاده از یک هسته خاص قابل پیادهسازی هستند. به عنوان مثال، میتوان حتی بدون محاسبه به این نتیجه ضمنی رسید که هسته زیر باعث تار شدن تصاویر خواهد شد: $$ 1/9 * \begin{bmatrix} 1 & 1 & 1 \\ 1 & 1 & 1 \\ 1 & 1 & 1 \\ \end{bmatrix} $$ این هسته مقادیر یک پیکسل خاص و هشت همسایه اصلی و فرعی آن را با یکدیگر جمع کرده و در هسته جایگذاری میکند. این عمل باعث ترکیب شدن رنگها شده و مانند عمل تار شدن عکس است. با فرض این مقدمات در مورد عمل کانوولشن، حال میتوانیم نمایی کلی از شبکههای کانوولوشن را بیان کنیم: شبکههای کانوولوشن ابتدا ورودی را به لایههای کانوولوشن میدهند؛ این لایههای با اعمال چندین و چند هسته متفاوت ویژگیهای معتددی از تصویر را بدست میآورند. به هریک از این بردارهای ویژگی که توسط کانوولوشن بدست میآیند یک کانال میگویند. سپس این کانالهای متعدد ویژگی، که هریک از آنها همان تصویر اصلی پس از اعمال یک یا چند هسته است، به یک بردار یک بعدی تغییر بعد داده میشود و ورودی یک شبکه عمیق پرسپترون، مانند فاز یک در نظر گرفته میشود. خلاصهای از این عملیات را میتوان در شکل زیر مشاهده کرد.  جزییات بیشتر این شبکه، مانند لایههای pooling در بخشهای آتی توضیح داده شدهاند. مهمترین نکته در مورد لایههای کانوولوشن که در بحث های پیشین تعمداً اشارهای به آن نکردیم سوال زیر است: هستههای هریک کانالهای لایههای کانوولوشن در بحثهای پیشین را چگونه انتخاب کنیم؟ اگر این هستهها توسط برنامهنویس مشخص شوند استفاده از لایههای کانوولوشن هیچ تاثیری در روند کلی ندارد و بحث ابتدایی این بخش، وابسته نبودن به دامنه و نوع عمل مورد نظر، مجدداً زیر سوال میرود. خوشبختانه شبکه کانوولوشن توصیف شده بالا مانند شبکههای عمیق پرسپترون یک خروجی مشخص دارد، میتوان با استفاده از این خروجی مقدار Loss Function مشخصشدهای را بدست آورد و بر اساس آن مشتقات جزیی خروجی نسبت به همه پارامترهای ورودی، منجمله المانهای هستههای کانوولوشن را بدست آورد. بدین طریق میتوان نتیجهگیری کرد که: در شبکههای کانوولوشن، هستهها به صورت خودکار، توسط رویه Gradient Descent یادگیری میشوند و بهترین هستهها برای استخراج بهترین ویژگیها انتخاب میشوند. ## دادهگان فارسی هدی در بخش قبل برای آزمایش مدلهای ایجاد شده از دادگان انگلیسی MNIST استفاده شد. در این بخش برای آزمایش دقیق عملگر مدل، رویهای برای استخراج تصاویر از پایگاه داده هدی ایجاد کردهایم و با استفاده از آن تصاویر حروف فارسی را به عنوان ورودی مدل در نظر میگیریم. این پایگاه داده شامل ۶۰۰۰۰ تصویر دودویی برای یادگیری و ۲۰۰۰۰ تصویر کاراکتر فارسی برای ارزیابی مدل است. متاسفانه، بر خلاف دادگان انگلیسی MNIST دادگان هدی اندازه مشخص ندارند و ابعاد تصاویر از حدود ۱۵ تا ۷۰ پیکسل متغیر است. برای رفع این مشکل از رویه زیر استفاده کردهایم: + اندازه هر تصویر استخراج شده و در صورت بزرگتر بودن از یک اندازه معین این تصویر نادیده گرفته میشود. + طول و عرض تصویر استخراج شده به اضافه عدد صفر کرده به اندازه طول و عرض مطلوب میرسد. با استفاده از این رویه، حدود ۵۸۰۰۰ تصویر برای آموزش و ۱۸۰۰۰ تصویر برای ارزیابی مدل بدست آوردیم. همه این تصاویر دودویی و اندازه همه آنها ۴۰ در ۴۰ پیکسل است. نمونههایی از این تصاویر را در شکل زیر به صورت پردازش شده و به صورت برداری مشاهده میکنید:  ## جزییات شبکه ایجاد شده شبکه اولیه ایجاد شده شامل لایههای زیر است. + لایه کانوولوشن، که نحوه کارکرد آن در بخش قبل بررسی شد و یک بردار دو بعدی را به عنوان ورودی میگیرد و تعداد مشخصی کانال خروجی دارد. همانطور که بیان شد، هر کانال یک تصویر به اندازه تصویر ورودی است که یک هسته معین به آن اعمال شده است. + لایه مخفی: مشابه لایههای پرسپترون استفاده شده در فاز اول این پروژه. این لایهها برای کاهش ابعاد خروجی لایههای کانوولوشن و رساندن آن به ابعاد بردار (۱۰) خروجی استفاده میشوند. + لایههای Pooling: در شبکههای کانوولوشن، با توجه به نحوه عملکرد این فرآیند، میتوان از یک بهینه سازی در زمان و فضای حافظه استفاده کرد. با ادعای اینکه با انجام یک کانوولوشن با اندازه هسته A x A بر روی یک ماتریس دلخواه، چکیدهای از اطلاعات پنجره A در مرکز این پنجره ذخیره میشود، میتوان تعدادی از المانهای ماتریس اصلی را، با نگهداری بیشینه مقدار موجود در پنجره، حدف نمود (معمولا اندازه هستههای Pooling کوچک تر از کانوولوشن در نظر گرفته میشود). اعمال این لایه دلخواه است و آزمایشهای متعدد نشان داده است که اعمال این لایه بدون این که به کیفیت خروجی شبکه تاثیر بگذارد، باعث بهبود سرعت یادگیری و پردازش شبکه میشود[10].  + لایه Dropout: برای بهبود عملکرد شبکه از المانی تصادفی به نام Dropout نیز استفاده شده است. این لایه که از نظر ورودی و خروجی مانند یک لایه بدون تابع فعالسازی است، تنها کاری که میکند این است که به صورت تصادفی تعدادی از نرونهای ورودی را غیر فعال میکند تا از فرآیند Overfitting جلوگیری کند. در شبکههای عصبی زمانی که شبکه به جای یادگیری رابطههای ورودی و خروجی مطلوب، آنها را تنها بر اثر دیدن مثالهای زیاد حفظ کند، Overfitting گفته میشود [9]. جدول زیر خلاصهای از لایههای اصلی شبکه به همران پارامترهای مهم آن را نمایش میدهد. ``` | Layer | Parameters | |:-------------:| ----------------------------------:| | Input | 40 x 40 | | Convolution2D | 1->32 channel, [5,5] kernel | | Pooling | [2,2] kernel, [40,40] -> [20,20] | | Convolution2D | 32->64 channel, [5,5] kernel | | Pooling | [2,2] kernel, [20,20] -> [10,10] | | Reshape | [64,10,10] => [64*10*10] | | Hidden Layer | 6400 => 1024 | | Dropout | prob=0.4 | | Hidden layer | 1024 => 10 | ``` لازم به ذکر است که لایه Reshape تنها ابعاد داده را تغییر میدهد. ## آزمایش۱: دادگان انگلیسی و شبکه کانوولوشن با توجه به اینکه در بخش اول و آزمایشهای اولیه از مجموعه دادگان انگلیسی استفاده کردیم، ابتدا برای مقایسه بهتر شبکه جدید را، با پارامتر های ذکر شده فوق را، با این دادگاه آموزش میدهیم. نتایج بدست آمده به شرح زیر است. | تعداد تکرار - Step | دقت نهایی | |:-------------:| ----------------------------------:| | 1000 | 70% | | 2000 | 87% | | 5000 | 96% | همانطور که مشاهده میشود، نتایج شبکه با پارامترهای یادگیری مناسب بسیار نزدیک به عملکرد شبکه پیشین است. شاید این شائبه برای خواننده پیش بیاید که چرا با وجود استفاده از یک شبکه نوین و پیچیده تر، نتایج به طرز قابل توجهی بهبود پیدا نکرد؟ پاسخ به این سوال را میتوان بدین صورت داد که عمل تشخیص کاراکتر انگلیسی، به عنوان یک فرآیند تقریباً اشباع شده (یعنی علم به مرحلهای رسیده است که بهترین نتایج ممکن بدست بیاید) در نظر گرفته میشود، لذا استفاده از شبکههای پیچیده تر در ظاهر تاثیر چندانی بر درصد نهایی نخواهد داشت. حتیً میتوان منابع زیادی را یافت که در آن ادعا شده است که روشهای قدیمی تر هوش مصنوعی مانند SVM نیز میتوانند برای این فرآیند به دقت بالای ۹۵٪ برسند. بخش دیگری از پاسخ نیز این است که در قالب چالشهای یادگیری ماشین، دقت بالا ۹۵٪ یک دقت قابل قبول است (صادق باشیم، انسان هم احتمالاً بیش از ۵٪ مواقع اشتباه میکند) و استفاده از یک شبکه قویتر قرار نبوده که دقت ما را بالاتر ببرد. بر خلاف تصور، ویژگی اصلی و مزیت شبکههای کانوولوشن قابلیت تعمیم آنها میباشد. این ویژگی به این دلیل است که این شبکهها، بر خلاف شبکههای عمیق معمولی که داده ورودی را به صورت خام پردازش و یادگیری میکنند، به ویژگیها، روابط و Pattern های تصویر دقت میکند و بر اساس آنها یک تصمیم صحیح را به کمک یک شبکه عمیق میگیرد. بر این اساس میتوانیم ادعا کنیم که به احتمال زیاد، شبکههای عمیق معمولی برای **دادههایی که شامل نویز زیاد هستند** مناسب نیستند، اما شبکههای کانوولوشن میتوانند تا حد زیادی دقت و کارایی خود را در انواع دادههای نویزدار یا با رنگ متفاوت حفظ کنند. ## آزمایش۲: دادگان هدی و شبکه کانوولوشن در نهایت و با احتساب تمام مطالب فوق، به عنوان کار پایانی در این تحقیق، دادگان هدی را با استفاده از شبکه ذکر شده یادگیری میکنیم. نتایج بدست آمده با پارامترهای یادگیری متفاوت به شرح زیر است. | تعداد تکرار - Step | دقت نهایی | |:-------------:| ----------------------------------:| | 200 | 33% | | 400 | 56% | | 600 | 62% | | 800 | 71% | | 1000 | 74% | | 5000 | 88% | | 10000 | 96% | همانطور که مشاهده میشود دقت نهایی سیستم با یادگیری کافی برای دادگان فارسی نیز مانند انگلیسی مطلوب است. برای مشاهده بهتر روند صعودی دقت شناسایی، در هردو آزمایش پارامترهای یادگیری کم و غیر کافی نیز ذکر شدهاند. منابع کد بهروزرسانیشده این پروژه در [مخزن گیت](https://github.com/mayahmir/AI-OCR-96) قرار داده شده اند. # کارهای آینده - تغییر بیشتر پارامترهای شبکه برای دستیابی به نتایج بهتر. - آزمایش شبکه جدید با دادههای شامل نویز برای نمایش بهتر تفاوت آن با شبکهها عمیق معمولی. # منابع 1. Song,Hyun Ah, and Soo-Young Lee. "Hierarchical Representation Using NMF." Neural Information Processing. Springer Berlin Heidelberg, 2013. 2. Ronan Collobert (May 6, 2011). ["Deep Learning for Efficient Discriminative Parsing"](http://videolectures.net/aistats2011_collobert_deep/). _videolectures.net_. Ca. 7:45. 3. Ian Goodfellow, Yoshua Bengio, and Aaron Courville [Deep Learning](http://www.deeplearningbook.org/) 4. http://neuralnetworksanddeeplearning.com/chap1.html 5. http://www.tflearn.ir/1395/11/08/tensor/# 6. http://yann.lecun.com/exdb/mnist/ 7. https://en.wikipedia.org/wiki/Rectifier_(neural_networks) 8. Kingma, Diederik, and Jimmy Ba. "Adam: A method for stochastic optimization." _arXiv preprint arXiv:1412.6980_(2014).6.9. [Overfitting](https://machinelearningmastery.com/overfitting-and-underfitting-with-machine-learning-algorithms/) 10. [Max-Pooling Dropout for Regularization of Convolutional Neural Networks](https://arxiv.org/pdf/1512.01400.pdf) ** ## پیوندهای مفید + [صفحه رسمی مجموعه دادگان هدی](http://farsiocr.ir/%D9%85%D8%AC%D9%85%D9%88%D8%B9%D9%87-%D8%AF%D8%A7%D8%AF%D9%87/%D9%85%D8%AC%D9%85%D9%88%D8%B9%D9%87-%D8%A7%D8%B1%D9%82%D8%A7%D9%85-%D8%AF%D8%B3%D8%AA%D9%86%D9%88%DB%8C%D8%B3-%D9%87%D8%AF%DB%8C/) + [مقاله در مورد مجموعه دادگان فارسی هدی](http://farsiocr.ir/Archive/dataset_PRL.pdf) + [Kaggle Competition](https://www.kaggle.com/c/digit-recognizer) + [Semeion Handwritten Digit Data Set](http://archive.ics.uci.edu/ml/datasets/Semeion+Handwritten+Digit) + [MNIST Handwritten Digits](http://yann.lecun.com/exdb/mnist/)