- معامله
- برنامه تجاری
- اکسپرت ادوایزرها برای NetTradeX
- ایجاد یک شبکۀ عصبی در NTL+
ایجاد یک شبکۀ عصبی در NTL+
مقدمه
شکبۀ عصبی مصنوعی - مدل های ریاضی و کاربردهای سخت افزار یا نرم افزارشان که بر مبنای سازمان و عملکرد زیستی شبکه های عصبی ایجاد می شوند - شبکه های سلول های عصبی (نورون های) مغز.
در حال حاضر، شبکه های عصبی به شکل گسترده ای در بسیاری از وظایف تشخیص، رده بندی، حافظۀ پیوندی، تعیین الگوها، تخمین و غیره مورد استفاده قرار می گیرند.
به منظور کار با شبکه های عصبی، محصولات ریاضی جداگانه ای وجود دارند و مدل های دیگری برای بسته های نرم افزار ریاضی اصلی که ظرفیت گسترده ای از ایجاد شبکه های مختلف و شکلبندی فراهم می کنند.
از طرف دیگر، ما تلاش خواهیم کرد تا با استفاده از زبان NTL+ ، شبکۀ خنثای خودمان را ایجاد و قابلیت های برنامه نویسی شی ء گرایش را بسنجیم.
انتخاب یک عمل
در این مقاله به بیان این فرضیه می پردازیم که به پشتوانۀ میله های قبلی این امکان وجود دارد که نوع احتمالی (صعودی یا نزولی) میلۀ بعدی را پیش بینی کنیم.
این عمل با رده بندی ها ارتباط دارد. ما همچنین اطلاعات تاریخی گسترده ای دربارۀ ابزارهای مالی در اختیار داریم که اجازه می دهد بتوانیم از آمار تاریخی، خروجی (اکسپرت) دلخواه مان را به دست آوریم. به همین دلیل، شبکه ای بر اساس perceptron چند لایه ایجاد خواهیم کرد.
اکنون، شبکه ای ایجاد می کنیم که بر اساس بسته شدن قیمت های میله های k نوع میلۀ بعدی را پیش بینی می کند. اگر قیمت بسته شدن از قیمت بسته شدن میلۀ قبلی بالاتر باشد، خروجی دلخواه بعدی را 1 در نظر می گیریم (افزایش قیمت). در موارد دیگر، خروجی دلخواه برابر با 0 است (قیمت تغییر نمی کند یا افت می کند).
ایجاد شبکه
به طور کلی یک perceptron چند لایه دارای یک لایۀ ورودی و یک یا چند لایۀ پنهان و یک لایۀ خروجی است. دارا بودن یک لایۀ پنهان برای تبدیل ورودی ها از طریق یک تقسیم خطی نمایش ورودی کافی است. استفاده از لایۀ های پنهان بیشتر، اغلب باعث ایجاد یک کاهش قابل توجه در سرعت آموزش یک شبکه بدون هیچ مزیت قابل توجهی در کیفیت یادگیری می شود.
همینک یک شبکه با یک لایۀ ورودی، یک لایۀ پنهان و یک لایۀ خروجی ایجاد می کنیم. تصویر زیر در نمایی کلی ساختار شبکه مان را نشان می دهد. x1 - xn ورودی ها (قیمت های بسته شدن)، wi,j - وزن های لبه های برآمده از گرۀ i و رونده بسوی گرۀ j؛ عصب های y1 - ym مربوط به لایۀ پنهان، خروجی های شبکۀ o1 - ok .
ضمن اینکه، شیب های ورودی در شبکه وجود دارند. کاربرد این ورودی ها، این قابلیت را به شبکه مان می دهد تا تابع فعال سازی را در راستای محورx انتقال دهد بنابراین نه تنها شبکه می تواند شیب تابع فعال سازی را تغییر دهد بلکه تغییر خطی اش را نیز میسر می کند.
1. نمودار تابع فعال سازی در = 1
2. نمودار تابع فعاال سازی در =2 و = 1
3. نمودار تابع فعال سازی با انتقال در =2, = 1 و = 1
مقدار هر گره از شبکه طبق فرمول زیر محاسبه خواهد شد:
در اینجا (f(x برابر است تابع فعال سازی و n برابر است با تعداد گره ها در لایۀ قبلی.
تابع های فعال سازی
تابع فعال سازی، علامت خروجی را محاسبه می کند علامتی که پس از عبور مخزن دریافت کرده است. عصب مصنوعی معمولاً به عنوان یک تابع غیرخطی از یک شناسۀ واحد نمایش داده می شود. اغلب تابع های فعال سازی زیر مورد استفاده قرار می گیرند:
تابع فِرمی (منحنی نمایی):منحنی گویا:
تانژانت هیپربولیک:
منحنی گویا برای محاسبۀ خروجی های هر لایه انتخاب شده است چراکه محاسبه اش زمان پردازندۀ کمتری می گیرد.
روند آموزش شبکه
برای آموزش شبکه مان، از روش توزیع معکوس استفاده خواهیم کرد. این روش یک الگوریتم تکراری است که برای به حداقل رساندن خطای کار یک perceptron چندلایه استفاده می شود. ایدۀ بنیادی الگوریتم: پس از محاسبۀ خروجی های شبکه، تطابق ها برای هر گره و خطا ω برای هر لبه محاسبه می شوند، محاسبۀ خطا در آن در جهت از خروجی های شبکه به ورودی هایش می رود. سپس اصلاح وزن های ω طبق مقادیر خطای محاسبه شده رخ می دهد. این الگوریتم تنها الزام در تابع فعال سازی را وضع می کند - باید متمایز باشد. منحنی ها و تانژانت هیپربولیک این الزام را برآورده می سازند.
هم اکنون برای انجام روند آموزش، به توالی مراحل زیر نیاز داریم:
- . ارائۀ مقادیر تصادفی کوچک به وزن های تمام لبه ها
- محاسبۀ تطابقات برای تمام خروجی های شبکه
، که در اینجا oj برابر است با خروجی محاسبه شدۀ شبکه، و tj برابر است با مقدار مورد انتظار (واقعی) - برای هر گره به استثناء آخرین محاسبۀ یک تطابق طبق فرمول
، که در اینجا ωj,k برابر است با وزن ها در لبه ها که از سوی گره می آیند که برای آن تطابق محاسبه شده و برابر است با تطابق های محاسبه شده برای گره های واقع شده نزدیک تر به لایۀ خروجی. - محاسبۀ تطابق برای هر لبۀ شبکه:
در اینجا oi برابر است با خروجی محاسبه شدۀ گره که لبه از آن می آید. خطار برای این لبه محاسبه می شود و برابر است با تطابق محاسبه شده برای گره که لبۀ تعیین شده به آن می آید. - مقادیر وزن صحیح برای تمام لبه ها:
- تکرار مراحل 2 - 5 برای تمامی مثال های آموزش یا معیار ثبت شده برای کیفیت آموزش تحقق یابد.
آماده کردن آمار ورودی
برای اجرای روند آموزش شبکه، آماده کردن آمار ورودی ضروری است، آمار ورودی کیفیت بالا دارای یک تاثیر مهم بر کار شبکه و سرعت تثبیت ضرایبw اش است، که به معنای خود روند آموزش می باشد.
توصیه می شود که تمامی بردارهای ورودی عادی سازی شوند بطوریکه مؤلفه های شان در محدودۀ [0;1] یا [-1;1] قرار بگیرند. عادی سازی باعث می شود که تمامی بردارهای ورودی در روند آموزش شبکه تناسب پیدا کنند و در آخر یک روند صحیح آموزش حاصل گردد.
ما بردارهای ورودی مان را عادی می سازیم - مقادیر مؤلفه های شان را به محدودۀ [0;1] تبدیل می کنیم و برای این کار فرمول زیر را به کار می بریم:
قیمت های بسته شدن میله ها به عنوان اجزای بردار مورد استفاده قرار خواهند گرفت. آنهایی که با شاخص های [n+k;n+1] هستند به عنوان خروجی ها تغذیه خواهند شد که در آنجا k برابر است با اندازۀ بردار ورودی. ما مقدار دلخواه را بر اساس میلۀ nام تعیین خواهیم کرد. ما مقدار را اساس این منطق شکل می دهیم که: اگر قیمت بسته شدن برای میلۀ nام بالاتر از قیمت بسته شدن میلۀ n+1 باشد (افزایش قیمت)، خروجی دلخواه را در 1 ثبت خواهیم کرد، اگر قیمت افت کند یا تغییری نداشته باشد، مقدار را در 0 ثبت خواهیم کرد.
میله هایی که در شکل گیری هر کدام نقش دارند در این تصویر با رنگ زرد مشخص شده اند. میله ای که برای تعیین مقدار دلخواه مورد استفاده قرار می گیرد با رنگ نارنجی مشخص شده است.
توالی آمار ارائه داده شده همچنین بر روند آموزش تاثیر می گذارد. اگر تمام بردارهای مرتبط با 1 و 0 بطور مساوی تغذیه شوند، روند آموزش استوارتر رخ می دهد.
علاوه بر این، یک مجموعۀ مستقل از آمار ایجاد می کنیم که برای ارزیابی تاثیر شبکه مان مورد استفاده قرار می گیرد. شبکه در این آمار آموزش داده نخواهد شد و فقط برای محاسبۀ خطا با روش کوچکترین مربع ها استفاده می شود. ما %10 از مثال های اولیه را برای سنجش مجموعۀ آمار اضافه خواهیم کرد. در نتیجه، از 90% از مثال ها برای آموزش و 10% برای سنجش استفاده خواهیم کرد.
تابع، محاسبۀ خطا با روش کوچکترین مربع ها، مانند زیر است:
,
در اینجا - برابر است با علامت خروجی شبکه و - برابر است با مقدار دلخواه علامت خروجی.
همینک به بررسی کد اسکریپت می پردازیم که بردارهای ورودی را برای شبکۀ عصبی مان آماده می کند.
همینک به بررسی ردۀ DataSet می پردازیم - مجموعۀ آمار. این رده شامل موارد زیر می شود:
- آرایش بردارهای مقادیر ورودی - ورودی
- مقدار خرجی شکل گرفته - خروجی
- روش 'Normalize' - عادی سازی آمار
- روش 'OutputDefine' - تعیین مقدار واقعی در ارتباط قیمت ها
- روش 'AddData' - ضبط مقادیر در آرایش بردار ورودی و متغییر مقدار واقعی
- روش 'To_file' - گردآوری آمار در آرایش مشترک برای ضبط متعاقب در فایل
همینک به سنجش کد برنامه با استفاده از تابع Run() و اجرای ترتیب زیر از اعمال می پردازیم:
- بارگذاری تمامی داده های تاریخی موجود در ترمینال در یک آرایۀ داخلی. بارگذاری برای نماد و چهارچوب زمانی ای اجرا می شود که نمودار فعلی برایش به نمایش درآمده است.
- آراستن آرایۀ میله به اندازه ای معادل با n برابر بردار داخلی + مقدار خروجی
- ایجاد آرایه های بردارهای ورودی؛ عادی سازی این بردارها؛ تعیین مقدار دلخواه 0 یا 1
- ایجاد آرایۀ بردارهای ورودی چیده شده درجائیکه که بردارها با موفقیت بر جایگزین 0 و 1 منطبق هستند
- ضبط بخش اصلی آرایه همراه با بردارهای ورودی چیده شده در فایل همراه با داده ها و ضبط بخش باقی ماندۀ داده ها در آرایه برای سنجش و متعاقباً ارزیابی همراه با روش کوچکترین مربع ها.
شما همچنین باید متغییر جهانی int state = 0 را در این فایل تعریف کنید، این متغییر برای جایزگینی بردارهای ورود لازم است.
ایجاد رده های شبکه
برای شبکه مان به موارد زیر نیاز داریم:
- یک نمونه از ردۀ 'layer' برای ارتصال ورود و لایه های پنهان شبکه
- یک نمونه از ردۀ 'layer' برای اتصال لایه های پنهان و خروجی و شبکه
- یک نمونه از ردۀ 'net' برای اتصال لایۀ شبکه مان
ایجاد ردۀ 'layer'
هم اکنون به رده ای نیاز داریم که دربرگیرندۀ مشخصات و روش های زیر باشد:
- آرایۀ 'input' برای چیدن ورودی های شبکه
- آرایۀ 'output' برای چیدن خروجی های شبکه
- آرایۀ 'delta' برای چیدن تطابق ها
- دو آرایۀ اندازه ای 'weights' برای وزن های لبه ها
- روش 'LoadInputs' برای اختصاص داده مقادیر تعیین شده در آرایۀ ورودی به ورودی های لایه
- روش 'LoadWeights' برای بارگذاری مقادیر وزن لایه از درایو سخت
- روش 'SaveWeights' برای ذخیرۀ مقادیر وزن لایه در درایو سخت
- سازنده حجم ضروری حافظه را برای آرایه های استفاده شده تخصیص می دهد
- روش 'RandomizeWeights' - پرکردن وزن ها با مقادیر تصادفی
- روش 'OutputCalculation' - محاسبۀ مقادیر خروجی
- روش 'CalculatingDeltaLast' و 'CalculatingDeltaPrevious' - محاسبۀ تطبیق مقادیر
- روش 'WeightsCorrection' - تصحیح مقادیر وزن
- روش های دیگر (تشخیصی) برای نمایش اطلاعات بر صفحۀ نمایش:
- PrintInputs() - چاپ ورودی های یک لایه
- PrintOutputs() - چاپ خروجی یک لایه (پس از محاسبۀ ورودی با استفاده از 'OutputCalculation' فراخوانده می شود)
- PrintDelta() - چاپ تطابق ها برای یک لایه (باید پس از محاسبۀ تطابق ها با استفاده از 'CalculatingDeltaLast' یا 'CalculatingDeltaPrevious' فراخوانده شود)
- PrintWeights() - چاپ وزن های w از یک لایه
- روش 'Calculate' - مرتبط کردن لایه ها برای محاسبۀ خروجی شبکه. از این روش بعداً برای کار با شبکۀ آموزش یافته استفاده خواهد شد.
- روش 'CalculateAndLearn' - محاسبۀ خروجی ها، خطاها و تطابق ها. ما برای محاسبۀ خروجی ها، روش قبلی را فرامی خوانیم و روش های مرتبط با هر لایه را برای خطاها و تطابق ها فراخوانده خواهد خواند.
- روش 'SaveNetwork' - ذخیرۀ ضرایب (وزن ها) شبکه
- روش 'LoadNetwork' - بارگذاری ضرایب (وزن ها) شبکه
- ایجاد شیء NT از ردۀ 'net'
- قرائت ضرایب (وزن ها)w و بارگذاری آنها در NT
- ایجاد آرایه های ورودی ها و خروجی ها شبکه
- قرائت ورودی ها در یک مدار و قراردادن آنها در آرایۀ 'x' ، قرائت خروجی ها و قراردادن آن در آرایۀ 'reals'
- محاسبۀ خروجی شبکه، تغذیۀ آرایۀ 'x' به عنوان یک ورودی
- محاسبۀ error به عنوان مجموع مربع های اختلاف ها بین تمام مقادیر محاسبه شده و مقادیر مورد انتظار (واقعی)
- پس از رسیدن به انتهای فایل، خطا را نمایش می دهیم و کار اسکریپت را خاتمه می دهیم
اجازه دهید ردۀ ایجاد شده را به یک فایل مجزا حذف کنیم. ضمناً این فایل شامل ساختار شبکه خواهد بود: تعداد گره ها در لایه های خروجی، پنهان و ورودی. این متغییرها خارج از رده قرار داده شدند تا برای شان در اسکریپت برای آماده سازی دادۀ ورودی استفاده شود.
ما همچنین به تابع های دیگری نیاز داریم که خارج از رده ها قرارشان خواهیم داد. اینها دو تابع هستند: عادی سازی یک بردار ورودی و تابع فعال سازی.
ایجاد ردۀ 'net'
ما به رده ای نیاز داریم که لایه های مان را به یک شبکۀ واحد ملحق کند، به این ترتیب این رده باید شامل موارد زیر باشد:
بررسی کار شبکه
در این بخش، در یک مثال ابتدایی که برای تعیین صحت رده بندی بردارهای ورودی استفاده خواهد شد، کار شبکه مان را بررسی خواهیم کرد. برای این منظور از یک شبکه با دو ورودی، دو گره در لایۀ پنهان و یک خروجی استفاده می کنیم. پارامترnu را به 1 ثبت می کنیم. دادۀ ورودی به عنوان مجموعه های جایگزین ارائه داده خواهد شد که شامل موارد زیر می شود:
ورودی 1،2 و مقدار مورد انتظار 1
ورود 2،1 و مقدار مورد انتظار 0
آنها در فایلی به این شکل مشخص می شوند:
شما با تغذیۀ ورودی تعداد متفاوتی از مثال های آموزشی، می توانید نحوۀ روند آموزش شبکه مان را مشاهده کنید.
خط قرمز در تصویر فوق نشان دهندۀ مثال آموزش مرتبط با 1 است. خط آبی نیز با 0 مرتبط است. عدد مربوط به مثال های آموزشی کنار محور x درج شده اند و مقدار شبکۀ محاسبه شده نیز در راستای محور y درج شده اند. واضح است که هرگاه تعداد اندکی از میله های شبکه (25 عدد یا کمتر) وجود داشته باشند، شبکه بردارهای ورودی متفاوت را تشخیص نمی دهد، و هرگاه تعداد میله ها بیشتر باشند، بطور آشکاری به دو رده تقسیم می شود.
برآورد عملکرد شبکه
به منظور ارزیابی تاثیر آموزش، اجازه دهید که از محاسبۀ تابع خطا با روش کوچکترین مربع ها استفاده می کنیم. برای این منظور، سودمندی را با کد زیر ایجاد کرده و آن را اجرا می کنیم. برای اینکه کار کند به دو فایل نیاز خواهیم داشت: "test.txt" - داده ها و مقادیر دلخواه استفاده شده برای محاسبۀ خطا و "NT.txt" - فایلی که ضرایب برای شبکه را محاسبه کرده است.
این اسکریپت توالی فعالیت های زیر را انجام می دهد:
array CalculatedOutput (L2_Innersize);
تعریف می کنیم؛ . در مقدار دهی اولیۀ تابع شاخص مان، پارامترهای شاخص، نوع اش، مقادیر وابستۀ نمودار ستونی با دو مقدار بافر را تعیین خواهیم کرد. ما همچنین باید پارامترهای شبکه مان را بازیابی کنیم یعنی اینکه تمامی ضرایب وزن که در خلال روند آموزش محسابه شده اند را در آن بارگذاری کنیم. این با استفاده از روش LoadNetwork(string s) شیء NT همراه با تنها پارامتر - نام فایل، دربرگیرندۀ ضرایب وزن انجام می شود. ما در تابع Draw ورودی بردار x
مرتبط با قیمت های بسته شدن نمودارها را ایجاد می کنیم همراه با شاخص ها [pos+inputVectorSize-1; pos]، که در آن 'pos' برابر است با تعداد میله ای که مقدار را برایش و اندازۀ 'inputVectorSize' بردار ورودی را محاسبه کرده ایم. در آخر، روش 'Calculate' از شیء NT فراخوانده می شود. این آرایۀ مقادیر را باز می گرداند (اگر شبکه مان چندین خروجی داشته باشد)، اما ازآنجائیکه فقط یک خروجی داریم، از عنصر آرایه با یک شاخص 0 استفاده خواهیم کرد.
نمودار فوق، تخمین شبکه از میلۀ بعدی را نشان می دهد. مقادیر از 0.5 تا 1 نشان می دهد که میلۀ بعدی بیشتر از افت، احتمال صعود خواهد داشت. مقادیر از 0 تا 0.5 به این موضوع اشاره دارند که احتمال ریزش بیشتر از صعود است. مقدار 0.5 وضعیتی دوجنبه را نشان می دهد: ممکن است میلۀ بعدی ریزش داشته باشد یا صعود کند.
خلاصه
شبکه های عصبی، ابزارهای قدرتمندی برای تحلیل داده ها به شمار می روند. این مقاله به روند ایجاد یک شبکۀ عصبی با استفاده از برنامۀ نویسی شیء گرا در زبان NTL+ می پردازد. کاربرد برنامه نویسی شی ء گرا این امکان را فراهم می کند که بتوان کد را ساده کرد و آن را در اسکریپت های آینده، بیش از پیش قابل استفادۀ مجدد کرد. در پیاده سازی ارائه داده شده، نیاز داشتیم برای تعریف لایه ای از شبکۀ عصبی، ردۀ layer را ایجاد کنیم و برای تعریف کل شبکه، ردۀ net را ایجاد کنیم. برای شاخص، محاسبۀ خطا و محاسبۀ وزن های داخلی شبکه، از ردۀ 'net' استفاده می کنیم. ضمن اینکه، با مثالی از شاخص - نمودار ستونی که پیش بینی شبکه از تغییر قیمت را فراهم می کرد، نحوۀ استفاده از شبکۀ آموزش دیده بیان شد.