چگونه يك شبكه عصبي هوشمند بسازيم؟ - مثالي از برنامهنويسي شيءگرا در شبكههاي عصبي و هوش مصنوعي
امين صفايي
قدرت و سرعت كامپيوترهاي امروزي به راستي شگفت انگيز است؛ زيرا كامپيوترهاي قدرتمند ميتوانند ميليونها عمليات را در كمتر از يك ثانيه انجام دهند. شايد آرزوي بسياري از ما انسانها اين باشد كه اي كاش ميشد ما نيز مانند اين دستگاهها كارهاي خود را با آن سرعت انجام ميداديم، ولي اين نكته را نبايد ناديده بگيريم كه كارهايي هستند كه ما ميتوانيم آنها را به آساني و در كمترين زمان ممكن انجام دهيم، ولي قويترين كامپيوترهاي امروزي نيز نميتوانند آنها را انجام دهند و آن قدرت تفكري است كه مغز ما انسانها دارد. حال تصور كنيد كه دستگاهي وجود داشته باشد كه علاوه بر قدرت محاسبه و انجام كارهاي فراوان در مدت زمان كوتاه، قدرت تفكر نيز داشته باشد يا به قول معروف هوشمند باشد!اين تصور در حقيقت هدف فناوري هوش مصنوعي يا Artificial Intelligence) AI) است. يكي از راهحلهاي تحقق اين هدف، شبكههاي عصبي است. شبكههاي عصبي در واقع از شبكههاي عصبي و سيستم عصبي انسان الگوبرداري ميكنند. برخي از محققان براين باورند كه هوش مصنوعي و شبكههاي عصبي دو راهحل متفاوت و در دو جهت مختلف هستند، ولي اين باور را نميتوان كاملاً صحيح دانست؛ چرا كه در حقيقت علم شبكههاي عصبي و هوشمصنوعي وابسته به هم هستند. بدينمعنا كه قبل از اينكه Symbolها بتوانند توسط هوش مصنوعي شناسايي شوند، بايد مراحلي طي شود. مثلاً تصور كنيد كه Symbolهايي مانند خانه، انسان يا ميز وجود دارند. قبل از اين كه AI بتواند هر كدام از اين Symbolها را شناسايي كند، بايد از تواناييها و صفات هر كدام از اينها اطلاع كامل حاصل كند. مثلاً تصور كنيد كه يك روبات كه هوش مصنوعي دارد، يك انسان را ميبيند، ولي از كجا ميفهمد كه اين جسم يك انسان است؟ مثلاً بر اساس مشخصاتي مثل داشتن دو پا، دست، صورت، دهان و قدرت تكلم. اما شما وقتي يك انسان ديگر را ميبينيد، نيازي نداريد كه اول تعداد پاهاي او را بشماريد و بعد بگوييد كه اين جسم، انسان است. مغز انسانها ميتواند با ديدن يك جسم فقط براي يك بار ياد بگيرد و اگر مجدداً آن جسم را مشاهده كرد، ميتواند سريع تشخيص دهد و قسمتهاي مختلف مغز ميتوانند به صورت همزمان فعاليت كنند و از اطلاعات درون مغز استفاده نمايند. شبكههاي عصبي در بسياري از پروژههاي هوش مصنوعي به كار گرفته ميشود. مثلاً براي برنامههاي تشخيص و الگوبرداري، شناسايي تصوير و كاراكتر، روباتها و برنامههاي فيلترينگ اطلاعات. اين شبكهها امروزه حتي در اتومبيلهاي بيسرنشين نيز كاربرد دارد. به طوريكه با ديدن و بررسي رانندگي انسانها، ميتوانند رانندگي كنند. در اين مقاله اصول شبكههاي عصبي در برنامهنويسي شيءگرا مورد بررسي قرار ميگيرد. با استفاده از زبان #C و انجام دادن عمليات X-OR ساده ميتوانيد اولين برنامه ساده هوش مصنوعي خود را بنويسيد. لازم به ذكر است كه مثالي كه در اين مقاله از آن استفاده شده، از مقاله Matthew Cochran (سي شارپ كورنر) اقتباس شده است.
![]() |
|
شكل 1 |
براي اينكه بتوانيم اين كار را دقيقاً در برنامه خود شبيهسازي كنيم، لازم است يك كلاس مانند شكل 1 قسمت اول طراحي كنيم كه ضمن داشتن مشخصههاي خاص، يك خروجي داشته باشد. البته همانطور كه در قسمت دوم نيز مشاهده ميكنيد (شكل 1)، هر نورون ميتواند داري چندين ورودي نيز باشد.
همانطور كه در شكل 1 مشاهده ميكنيد، نورونها به صورت گروهي لايهبندي ميشوند.
![]() |
|
شكل 2 |
حال كه تقريباً با كار يك لايه عصبي آشنا شديد، ميتوانيم شبكههاي پيچيدهتر را مورد بررسي قرار دهيم. براي اين كار حداقل به سه گروه از نورونهايي كه در شكل 2 ميبينيد، نياز داريم.
همانطور كه در شكل 3 مشاهده ميكنيد، اين شبكه داراي سه لايه است. لايه 1 يا لايه بالايي اين شبكه كه در حقيقت لايه ورودي است، پارامترهاي پالس را تنظيم ميكند و اين مقادير را همراه سيگنال يا پالس به لايههاي بعدي پاس ميدهد، ولي نورونهاي لايه 3 يا لايه خروجي كه در پايينترين سطح شبكه قرار دارد، هيچ سيگنالي را به لايه ديگري نميفرستند و در واقع فقط خروجي دارند.
![]() |
|
شكل 3 |
حال قسمت اصلي كار شبكه فرا ميرسد؛ يعني آموختن به شبكه عصبي. ب
راي اينكه به شبكه عصبي موجود توانايي آموختن بدهيم، بعد از اينكه سيگنال از لايه اول شبكه به لايه پاييني شبكه ميرود، بايد اطلاعات هر نورون را كه روي سيگنال ما اثر ميگذارد، بروزآوري و اصلاح كنيم. اين رويه را به اصطلاح BP يا Back Propagation ميگويند.
در حقيقت با اين كار يعني مقايسه خروجياي كه خودمان محاسبه كردهايم با خروجي شبكه، ميتوانيم مقدار اشتباهاتي كه شبكه ما انجام ميدهد را به دست آوريم.
مثلاً تصور كنيد كه در يك سلول نورون در لايه آخر شبكه يا لايه خروجي اشتباهي داريم، هر نورون در واقع ركورد تمامي نورونهايي كه سيگنال از آن عبور ميكند را نگهداري مينمايد و ميداند كه كدام يك از نورونهاي قبلي يا به اصطلاح نورونهاي والد باعث اين اشتباه ميشوند.
همچنين ميدانيم كه هر كدام از اين نورونهاي شبكه يك مقدار اشتباه را محاسبه كردهاند و از اين طريق شبكه ما ميتواند ياد بگيرد و اگر مقدار ديگري نيز به آن داده شد، ميتواند توانايي محاسبه داشته باشد.
|
|
|
شكل 4 |
|
|
|
شكل 5 |
|
|
|
شكل6 |
در كدهاي اين كلاس ميبينيد كه دو مقدار Private به نامهاي Mywight و MyDelta نوع double و جود دارد. كار اصلي اين كلاس، دادن و گرفتن مقادير نورون است و در واقع تغييرات در ورودي نورونها و وزن آنها را نگهداري ميكند. حال ميتوانيم يك اينترفيس براي خود نورون درست كنيم. از آن جايي كه هر نورون هم مشخصات سيگنال و هم Receptor را دارد، بايد از دو اينترفيسي كه قبلاً در شكل هاي 5 و 4 توضيح داده شد، استفاده كند. همچنين هر نورون چيزي مانند يك ورودي ديگر نيز دارد كه به آن Bias ميگوييم.
اضافه براين، بايد دو متد براي انجام كار در شبكه درست كنيم: يكي براي انجام Pulse و ديگري براي يادگيري نورون. كدهاي شكل 7 تمامي اين اينترفيس را مشخص كرده است.
|
|
|
شكل7 |
اكنون كه با اينترفيسهاي اين شبكه ساده آشنا شديد، نوبت به ساختن اجزاي اصلي برنامه ميرسد. اولين كاري كه بايد در اين قسمت انجام دهيم، ساختن كلاس اصلي نورون است كه بايد آن را بر اساس اينترفيسهايي كه ساختهايم، درست كنيم. شكل 8 ساختار اصلي اين كلاس را نشان ميدهد.
|
|
|
شكل8 |
![]() |
|
شكل 9 |
اگر كمي به كدهاي شكل 9 و متد Pulse دقت كنيد، متوجه ميشويد كه اين متد جمع هر ورودي يا هر خروجي كه به نورون داده ميشود را دريافت ميكند و در Weight مربوطه كه در دايركتوري است ضرب ميكند و آخرين خروجي آخرين را به متد Sigmoid انتقال ميدهد و در نتيجه خروجي آخر ما عددي بين 0 و 1 خواهد بود.
حال دو كلاس مهم از اين شبكه باقيمانده است: اولين كلاس، كلاس اصلي شبكه يا NeuralNet است و ديگريNeuralLayer، كلاس لايههاي شبكه ما است. اين دو كلاس در شكل 10 به صورت مشخص نشان داده شده است، اما نكته بسيار مهم اين است كه كلاس NuralLayer در حقيقت مسئول نگهداري نورونهاي انتقالدهنده يا فراخوانكننده متد Pulse است.
|
کلاس اصلي شبکه |
کلاس لايههاي شبکه |
|
|
|
|
شكل 10 | |
در اين كلاس از فهرست نورونها استفاده شده است و اين كلاس در اصل نورونها را در خود جا ميدهد. در اين كلاس دو متد كه هيچ مقدار برگشتي ندارند، به نامهاي Pulse و ApplyLearning وجود دارد. اين متدها در حقيقت كار فرستادن پالس و يادگيري لايهها را به عهده دارند. كدهاي شكل 11 اين دو متد را نشان ميدهد.
|
|
|
شكل 11 |
|
|
|
شكل 12 |
متد BackProgation يكي ديگر از متدهاي اين كلاس است. اين متد ابتدا خطاهاي خروجي نورونها را با محاسبه اختلاف عددي بين مقدار مورد انتظار ما و خروجي نورونها محاسبه ميكند و وقتي كه خروجي همه نورونها بروز گرديد، اين متد خطاهاي نورونهاي پنهان را نيز محاسبه ميكند.
![]() |
|
شكل 13 |
وقتي اين متد توسط برنامه انجام شد، برنامه با استفاده از متد، ()Train و با استفاده از خروجيهاي قبلي ميتواند توانايي يادگيري داشته باشد.
اگر بخواهيم شبكه خود را آموزش دهيم كه عمليات X-OR را انجام دهد، بايد ابتدا يك شبكه بسازيم كه دو نورون ورودي، دو نورون پنهان و يك نورون خروجي داشته باشد. مثلاً ميتوانيم شبكه خود را طوري آموزش دهيم كه بتواند عمليات مشخصشده در جدول 1 را انجام دهد:
|
خروجي |
ورودي دوم |
ورودي اول |
|
1 |
0 |
1 |
|
0 |
1 |
1 |
|
0 |
0 |
0 |
|
1 |
1 |
0 |
|
جدول 1 | ||
كل 13 روند اجرايي برنامه را نشان ميدهد. ميتوانيد سورس كدهاي اين برنامه را از قسمت دريافت فايل سايت ماهنامه شبكه دريافت كنيد و قدم به قدم و با استفاده از راهنماييهايي كه در آن نوشته شده است، تغييراتي در كدها انجام دهيد و اولين برنامه هوش مصنوعي خود را بنوسيد
منابع:
http://en.wikipedia.org/wiki/Neural_network
www.c-sharpcorner.com
lss/NNIntro/InvSlides.htmlدwww.cs.stir.ac.uk/
www.nd.com/neurosolutions/products/ns/whatisNN.html














Life has taught me this: to have peace and comfort, I should walk along-side God today and then have faith in him for tomorrow