شبکه عصبی در متلب — از صفر تا صد
شبکههای عصبی (Neural Networks) شبکههایی از سلولهای عصبی (نورون یا پیياخته یا عصب) مغز هستند. مغز انسان میلیاردها نورون و تریلیونها ارتباط بین آنها دارد. این نورونها مدام در حال پردازش و ارسال اطلاعات به نورونهای دیگر هستند. در این آموزش، با پیادهسازی شبکه عصبی در متلب برای تقریب توابع و سیستمها آشنا میشویم. برای آشنایی بیشتر با مفاهیم و تعاریف شبکههای عصبی میتوانید آموزشهای «شبکههای عصبی مصنوعی» و «ساخت شبکه عصبی» را مطالعه کنید.
در سال ۱۹۰۹، «سانتیاگو رامون کاخال» (Santiago Ramon y Cajal) کشف کرد که مغز از تعداد زیادی نورون متصل به هم تشکیل شده که پیامهای بسیار ساده تحریکی (Excitatory) و مهاری (Inhibitory) را برای یکدیگر ارسال میکنند و تهییج (Excitation) آنها با همین پیامهای ساده بهروز میشود. یک نورون سه بخش اصلی دارد: جسم سلولی، آکسون یا آسه (Axon) که پیامها را ارسال میکند و دندریت یا دارینه (Dendrite) که پیامها را دریافت میکند. جسم سلولی ساختار سلول را تشکیل میدهد. آکسون یک رشته منشعب است که پیامهای نورون را به بیرون منتقل میکند. دندریتها انشعابهای بیشتری دارند و سیگنال سلولهای عصبی دیگر را دریافت میکنند.
خلاصهای از پیشرفت علمی در زمینه شبکههای عصبی به شرح زیر است:
- در سال ۱۹۴۳، مککولوخ (McCulloch) و پیتس (Pitts) اولین مدل ریاضی نورونها را پیشنهاد کردند و نشان دادند که چگونه میتوان شبکههای نورنمانند را تحلیل و محاسبه کرد.
- نخستین ایدههای یادگیری با شبکههای عصبی را هِب (Hebb) در کتابی با عنوان «سازماندهی رفتار» در سال ۱۹۴۹ ارائه کرد.
- در سال ۱۹۵۱، ادموندز (Edmonds) و مینسکی (Minsky) ماشین یادگیری خود را با بهرهگیری از ایده هب ساختند.
- نقطه مهم آغاز یادگیری شبکه نرون را میتوان کار روزنبلات (Rosenblatt) در سال ۱۹۶۲ دانست. روزنبلات دستهای از شبکههای یادگیری نورونمانند ساده را ساخت که شبکه عصبی پرسپترون (Perceptron Neural Network) نامیده شد.
- جان هاپفیلد (John Hopfield) در مقاله مهمی که در سال ۱۹۸۲ منتشر کرد، یک معماری برای شبکه عصبی با نام شبکه هاپفیلد ارائه کرد. از این شبکه عصبی میتوان برای حل مسائل بهینهسازی مانند مسئله فروشنده دورهگرد استفاده کرد.
- یک شبکه عصبی مهم که بسیار مورد استفاده قرار میگیرد، با یادگیری پسانتشار خطا (Backpropagation) یا BP است. شبکه عصبی پسانتشار خطا را اولین بار، وربوس (Werbos) در سال ۱۹۷۴ و پس از او روملهارت و همکارانش (Rumelhart et al) در سال ۱۹۸۶ ارائه کردند. کتاب آنها، با عنوان «پردازش توزیع شده موازی» (Parallel Distributed Processing)، چشمانداز گستردهای از رویکردهای شبکه عصبی را بیان کردند.
- شبکههای عصبی با توابع پایه شعاعی (Radial Basis Functions) یا شبکههاب عصبی RBF در سال ۱۹۸۸ معرفی شدند و به دلیل قابلیت تعمیم و ساختار سادهشان که از انجام محاسبات طولانی و غیرضروری جلوگیری میکرد، نسبت به شبکههای پیشخور (Feed-forward Network) یا MFNها توجه زیادی را به خود جلب کردند. تحقیقات مربوط به قضایای تقریب جامع (Universal Approximation) نشان دادند که هر تابع غیرخطی را میتوان روی یک مجموعه فشرده (Compact Set) و با دقت دلخواه با شبکه عصبی RBF تقریب زد. همچنین تحقیقات گستردهای درباره کنترل عصبی RBF سیستمهای غیرخطی انجام شده که در حال حاضر نیز ادامه دارد.
در ادامه، مدل ریاضی یک شبکه ساده RBF و پیادهسازی آن در متلب را بیان میکنیم.
یک شبکه عصبی ساده RBF
شبکههای عصبی RBF سه لایه دارند: لایه ورودی (Input Layer)، لایه پنهان یا مخفی (Hidden Layer) و لایه خروجی (Output Layer). نورونهای لایه مخفی با یک تابع پایه شعاعی (RBF) فعال (تحریک) میشوند. لایه مخفی از آرایهای از واحدهای محاسباتی تشکیل شده که گرههای مخفی (Hidden Nodes) نامیده میشوند. هر گره مخفی شامل یک بردار مرکزی است که یک بردار پارامتری با طولی مشابه با بردار ورودی است. فاصله اقلیدسی بین بردار مرکز و بردار ورودی شبکه به صورت تعریف میشود.
شکل ۲ مدل شبکه عصبی سادهای را نشان میدهد. در این شکل، ورودیها یا همان نورونهای ورودی تا هستند. وزنها نیز تا هستند که در هریک از ورودیها ضرب میشوند.
عنصر دیگر این شبکه عصبی تابع جمع است که حاصلضرب ورودیها در وزنها را جمع میکند. بخش دیگر این شبکه، تابع فعالسازی است. و در نهایت، خروجی بخش آخر این شبکه را تشکیل میدهد.
الگوریتم این شبکه عصبی را میتوان به صورت زیر توصیف کرد:
که در آن، و است. مقدار نیز بایاس است.
تابع فعالساز معمولاً به یکی از این سه صورت است:
۱. مقدار آستانه (Threshold Value):
تابع آستانه در شکل زیر داده شده است.
۲. تابع خطی:
برای مثال، با انتخاب ، و تابع خطی به صورت شکل ۴ خواهد بود.
۳. تابع غیرخطی:
توابع سیگموئید (Sigmoid) و گوسی (Gaussian) در شبکههای عصبی بسیار مورد استفاده قرار میگیرند. سیگموئید به صورت زیر تعریف میشود:
به عنوان مثال، با انتخاب شکل این تابع به صورت زیر خواهد بود.
طراحی و شبیهسازی شبکه عصبی در متلب
شبکه عصبی تابع پایه شعاعی (RBF) یک شبکه عصبی چندلایه است. شبکه عصبی RBF از سه لایه با واحدهای (نورونهای) پردازنده تشکیل میشود (در سادهترین حالت).
شبکه عصبی RBF
ساختار یک شبکه عصبی RBF سه لایه در شکل ۶ نشان داده شده است.
در شبکه عصبی RBF بردار ورودی است. فرض میکنیم نورون در لایه مخفی وجود داشته باشد، و بردار تابع پایه شعاعی در لایه مخفی و تابع گوسی نورون در لایه مخفی باشد، و داشته باشیم:
که در آن، مختصات نقطه مرکزی تابع گوسی نورون برای اُمین ورودی است. همچنین، در بردار مقدار طول تابع گوسی را برای نورون نشان میدهد.
مقدار وزن RBF برابر است با:
خروجی شبکه عصبی RBF به صورت زیر است:
شبیهسازی شبکه عصبی RBF در متلب
یک شبکه عصبی RBF را با ساختار در نظر بگیرید که ورودی آن، است و داریم:
فرض میکنیم ورودی باشد. خروجی RBF در شکل ۷ و خروجیهای لایه مخفی در شکل ۸ نشان داده شدهاند.
ابتدا شکل زیر را در سیمولینک پیادهسازی میکنیم.
تابع spacemodel.m به صورت زیر است:
1function [sys,x0,str,ts] = spacemodel(t,x,u,flag)
2switch flag,
3case 0,
4[sys,x0,str,ts]=mdlInitializeSizes;
5case 3,
6sys=mdlOutputs(t,x,u);
7case {2,4,9}
8sys=[];
9otherwise
10error(['Unhandled flag = ',num2str(flag)]);
11end
12function [sys,x0,str,ts]=mdlInitializeSizes
13sizes = simsizes;
14sizes.NumContStates = 0;
15sizes.NumDiscStates = 0;
16sizes.NumOutputs = 7;
17sizes.NumInputs = 1;
18sizes.DirFeedthrough = 1;
19sizes.NumSampleTimes = 0;
20sys = simsizes(sizes);
21x0 = [];
22str = [];
23ts = [];
24function sys=mdlOutputs(t,x,u)
25x=u(1); %Input Layer
26%i=1
27%j=1,2,3,4,5
28%k=1
29c=[-0.5 -0.25 0 0.25 0.5]; %cij
30b=[0.2 0.2 0.2 0.2 0.2]'; %bj
31W=ones(5,1); %Wj
32h=zeros(5,1); %hj
33for j=1:1:5
34h(j)=exp(-norm(x-c(:,j))^2/(2*b(j)*b(j))); %Hidden Layer
35end
36y=W'*h; %Output Layer
37sys(1)=y;
38sys(2)=x;
39sys(3)=h(1);
40sys(4)=h(2);
41sys(5)=h(3);
42sys(6)=h(4);
43sys(7)=h(5);
برای رسم نتایج برنامه را به صورت زیر مینویسیم.
1close all;
2% y=y(:,1);
3% x=y(:,2);
4% h1=y(:,3);
5% h2=y(:,4);
6% h3=y(:,5);
7% h4=y(:,6);
8% h5=y(:,7);
9figure(1);
10plot(out.t,out.y(:,1),'k','linewidth',2);
11xlabel('time(s)');ylabel('y');
12figure(2);
13plot(out.y(:,2),out.y(:,3),'k','linewidth',2);
14xlabel('x');ylabel('hj');
15hold on;
16plot(out.y(:,2),out.y(:,4),'k','linewidth',2);
17hold on;
18plot(out.y(:,2),out.y(:,5),'k','linewidth',2);
19hold on;
20plot(out.y(:,2),out.y(:,6),'k','linewidth',2);
21hold on;
22plot(out.y(:,2),out.y(:,7),'k','linewidth',2);
اکنون یک شبکه عصبی RBF را با ساختار در نظر بگیرید که ورودی آن است و داریم:
دو ورودی را در نظر میگیریم.
خروجی RBF در شکل ۹ نشان داده شده است و شکلهای ۱0 و ۱۱ خروجیهای لایه مخفی را نشان میدهند.
برای پیادهسازی این شبکه عصبی با دو ورودی، سیستم را به صورت زیر در سیمولینک تشکیل میدهیم.
تابع spacemodel.m به صورت زیر است:
1function [sys,x0,str,ts] = spacemodel(t,x,u,flag)
2switch flag,
3case 0,
4[sys,x0,str,ts]=mdlInitializeSizes;
5case 3,
6sys=mdlOutputs(t,x,u);
7case {2,4,9}
8sys=[];
9otherwise
10error(['Unhandled flag = ',num2str(flag)]);
11end
12function [sys,x0,str,ts]=mdlInitializeSizes
13sizes = simsizes;
14sizes.NumContStates = 0;
15sizes.NumDiscStates = 0;
16sizes.NumOutputs = 8;
17sizes.NumInputs = 2;
18sizes.DirFeedthrough = 1;
19sizes.NumSampleTimes = 0;
20sys = simsizes(sizes);
21x0 = [];
22str = [];
23ts = [];
24function sys=mdlOutputs(t,x,u)
25x1=u(1); %Input Layer
26x2=u(2);
27x=[x1 x2]';
28%i=2
29%j=1,2,3,4,5
30%k=1
31c=[-0.5 -0.25 0 0.25 0.5;
32-0.5 -0.25 0 0.25 0.5]; %cij
33b=[0.2 0.2 0.2 0.2 0.2]'; %bj
34W=ones(5,1); %Wj
35h=zeros(5,1); %hj
36for j=1:1:5
37h(j)=exp(-norm(x-c(:,j))^2/(2*b(j)*b(j))); %Hidden Layer
38end
39yout=W'*h; %Output Layer
40sys(1)=yout;
41sys(2)=x1;
42sys(3)=x2;
43sys(4)=h(1);
44sys(5)=h(2);
45sys(6)=h(3);
46sys(7)=h(4);
47sys(8)=h(5);
برای رسم نتایج، برنامه را به صورت زیر مینویسیم و اجرا میکنیم.
1close all;
2% y=y(:,1);
3% x1=y(:,2);
4% x2=y(:,3);
5% h1=y(:,4);
6% h2=y(:,5);
7% h3=y(:,6);
8% h4=y(:,7);
9% h5=y(:,8);
10figure(1);
11plot(out.t,out.y(:,1),'k','linewidth',2);
12xlabel('time(s)');ylabel('y');
13figure(2);
14plot(out.y(:,2),out.y(:,4),'k','linewidth',2);
15xlabel('x1');ylabel('hj');
16hold on;
17plot(out.y(:,2),out.y(:,5),'k','linewidth',2);
18hold on;
19plot(out.y(:,2),out.y(:,6),'k','linewidth',2);
20hold on;
21plot(out.y(:,2),out.y(:,7),'k','linewidth',2);
22hold on;
23plot(out.y(:,2),out.y(:,8),'k','linewidth',2);
24figure(3);
25plot(out.y(:,3),out.y(:,4),'k','linewidth',2);
26xlabel('x2');ylabel('hj');
27hold on;
28plot(out.y(:,3),out.y(:,5),'k','linewidth',2);
29hold on;
30plot(out.y(:,3),out.y(:,6),'k','linewidth',2);
31hold on;
32plot(out.y(:,3),out.y(:,7),'k','linewidth',2);
33hold on;
34plot(out.y(:,3),out.y(:,8),'k','linewidth',2);
آموزش شبکه عصبی با الگوریتم پس انتشار
شکل ۱۲ ساختار یک شبکه سه لایه را برای الگوریتم پس انتشار (BP) نشان میدهد. این الگوریتم، یکی از روشهای آموزش شبکه عصبی است. اولین لایه (سمت چپ) لایه ورودی است که از دادههای ورودی تغذیه میشود. لایه بعدی، لایه مخفی است که در آن، واحدهای پردازنده به واحدهای لایه قبل و بعد متصل هستند.
همانطور که در شکل ۵ میبینیم، لایهها کاملاً با هم ارتباط دارند؛ بدین معنی که هر واحد پردازش با همه واحدهای لایه قبلی ارتباط دارد. همچنین، واحدهای هر لایه مجزا با یکدیگر ارتباطی ندارند.
تقریب یک سیستم با استفاده از شبکه عصبی و الگوریتم پس انتشار
نمودار بلوکی تقریب سیستم با استفاده از شبکه عصبی پس انتشار در شکل ۱۳ نشان داده شده است.
شکل ۱۴ نیز ساختار شبکه عصبی را برای تقریب نشان میدهد.
هدف، بهروزرسانی وزنها به گونهای است که شبکه عصبی با خطای قابل قبولی سیستم را تقریب بزند. الگوریتم پس انتشار خطا به صورت زیر است:
۱. محاسبه پیشخور:
ورودی لایه مخفی برابر است با:
خروجی لایه مخفی نیز به صورت زیر است:
در نتیجه، میتوان نوشت:
خروجی لایه خروجی نیز برابر است با:
بنابراین، خطای تقریب به صورت زیر قابل محاسبه است:
تابع شاخص خطا را اینگونه تعریف میکنیم:
۲. الگوریتم یادگیری پس انتشار
طبق الگوریتم روش شدیدترین کاهش (گرادیان) مقدار وزن برابر است با:
مقدار وزن در لحظه به صورت زیر است:
یادگیری مقدار وزن برابر است با:
که در آن، از قاعده زنجیرهای زیر استفاده شده است:
مقدار وزن در لحظه برابر است با:
با در نظر گرفتن اثر تغییر مقدار وزن قبلی، الگوریتم محاسبه وزن به صورت زیر خواهد بود:
که در آن، نرخ یادگیری و ضریب مومنتوم است.
با استفاده از تقریب شبکه عصبی پس انتشار، مقدار ژاکوبی را میتوان به صورت زیر محاسبه کرد:
شبیهسازی تقریب شبکه عصبی با یادگیری پس انتشار در متلب
فرض کنید سیستمی با معادله زیر داده شده است:
سیگنال ورودی است. بردار ورودی شبکه عصبی RBF را به صورت و ساختار شبکه عصبی را انتخاب میکنیم. مقدار اولیه و را یک مقدار تصادفی، بین در نظر میگیریم.
همچنین، و را انتخاب میکنیم.
برای انجام شبیهسازی در متلب، یک m-فایل را با نام exp_1.m ذخیره کرده و برنامه زیر را در آن مینویسیم. حاصل اجرای برنامه زیر، شکلهای ۱۵ تا ۱۷ است. همانطور که میبینیم، شبکه عصبی با خطای کمی تابع مورد نظر را تقریب زده است.
1%BP approximation
2clear all;
3close all;
4xite=0.50;
5alfa=0.05;
6wjo=rand(6,1);
7wjo_1=wjo;wjo_2=wjo_1;
8wij=rand(2,6);
9wij_1=wij;wij_2=wij;
10dwij=0*wij;
11x=[0,0]';
12u_1=0;
13y_1=0;
14I=[0,0,0,0,0,0]';
15Iout=[0,0,0,0,0,0]';
16FI=[0,0,0,0,0,0]';
17ts=0.001;
18for k=1:1:1000
19time(k)=k*ts;
20u(k)=0.50*sin(3*2*pi*k*ts);
21y(k)=u_1^3+y_1/(1+y_1^2);
22x(1)=u(k);
23x(2)=y(k);
24for j=1:1:6
25I(j)=x'*wij(:,j);
26Iout(j)=1/(1+exp(-I(j)));
27end
28yo(k)=wjo'*Iout; % Output of NNI networks
29e(k)=y(k)-yo(k); % Error calculation
30wjo=wjo_1+(xite*e(k))*Iout+alfa*(wjo_1-wjo_2);
31for j=1:1:6
32FI(j)=exp(-I(j))/(1+exp(-I(j)))^2;
33end
34for i=1:1:2
35for j=1:1:6
36dwij(i,j)=e(k)*xite*FI(j)*wjo(j)*x(i);
37end
38end
39wij=wij_1+dwij+alfa*(wij_1-wij_2);
40%%%%%%%%%%%%%%Jacobian%%%%%%%%%%%%%%%%
41yu=0;
42for j=1:1:6
43yu=yu+wjo(j)*wij(1,j)*FI(j);
44end
45dyu(k)=yu;
46wij_2=wij_1;wij_1=wij;
47wjo_2=wjo_1;wjo_1=wjo;
48u_1=u(k);
49y_1=y(k);
50end
51figure(1);
52plot(time,y,'r',time,yo,'b');
53xlabel('times');ylabel('y and yo');
54figure(2);
55plot(time,y-yo,'r');
56xlabel('times');ylabel('error');
57figure(3);
58plot(time,dyu);
59xlabel('times');ylabel('dyu');
فیلم آموزش ویدیویی شبکههای عصبی مصنوعی در متلب
برای آشنایی بیشتر با شبکههای عصبی و پیادهسازی آنها در متلب میتوانید به دروه آموزش ویدئویی «مجموعه آموزش های شبکه های عصبی مصنوعی در متلب» مراجعه کنید. در این آموزشِ ۲۷ ساعت و ۴۶ دقیقهای که شامل ۷ بخش اصلی است، میتوانید با شبکههای عصبی مصنوعی و پیادهسازی آنها در متلب از سطح مقدماتی تا پیشرفته آشنا شوید. در بخش اول و دوم این مجموعه، به ترتیب، شبکههای عصبی پرسپترون چندلایه یا MLP و شبکههای عصبی شعاعی پایه یا RBF در متلب ارائه شده است. در بخش سوم، ماشینهای بردار پشتیبان یا SVM در متلب بیان شده است. یادگیری غیر نظارت شده و خوشهبندی با الگوریتم k-Means، موضوع بخش چهارم از این مجموعه ویدئویی است. شبکههای عصبی رقابتی و نگاشت خودسازمانده یا SOM، تحلیل مؤلفه اساسی یا PCA و شبکههای عصبی هاپفیلد یا Hopfield Neural Network نیز درسهای پنجم تا هفتم از این مجموعه آموزش را تشکیل میدهند.
- برای دیدن فیلم آموزش شبکه های عصبی مصنوعی در متلب + اینجا کلیک کنید.
اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای شبکههای عصبی مصنوعی
- آموزش شبکههای عصبی مصنوعی در متلب
- مجموعه آموزشهای هوش مصنوعی
- آموزش کاربردی شبکههای عصبی مصنوعی
- ساخت شبکه عصبی (Neural Network) در پایتون — به زبان ساده
- ساخت شبکه های عصبی در نرم افزار R
- شبکه عصبی مصنوعی و پیادهسازی در پایتون — راهنمای کاربردی
^^
این کدی در مطالب بالا توضیح داده شده تابع شعاعی با مقادیر توزیع یکنواخت هستش. بهتر بود کد با آموزش پارامتر های تابع گوسی هم بگین