جونیور دیتاساینتیتست
عمیقتر و عمیقتر در عمق یادگیری عمیق و شبکههای عصبی مصنوعی
# پارت 3 : انواع مهم ترین معماری های شبکه های عصبی عمیق (RNN / LSTM / CNN)
باید به لایه های عمیق تری نفوذ کنیم!
"معماری دنیای جدید"
این مقاله در سه پارت کامل می شود که به شرح زیر است :
پارت 1 : تاریخچه هوش مصنوعی و چگونگی عملکرد شبکه های عصبی ساده
پارت 3 : انواع مهم ترین معماری های شبکه های عصبی عمیق (RNN / LSTM / CNN)
که در این 3 پارت به این موضوعات خواهیم پرداخت که شبکه های عصبی مصنوعی چیه ؟ چطور کار میکند ؟ یادگیری عمیق چیه ؟ در شبکه های عمیق یادگیری چطور انجام می شه و انواع روش های یادگیری شبکه چیه ؟ انواع معماری های اصلی شبکه های عمیق چی هست ؟ آیا واقعا کارکرد شبکه های عصبی مصنوعی مانند نورون های شبکه عصبی انسان است یا فقط الهامی از آن هست ؟ کاربردهای شبکه عصبی چیه ؟ معایبی هم داره ؟
مرور مطالب پیشین و پیش رو
در پارت 2 تعدادی از مهم ترین توابع فعالسازی و کارکرد هاشون همچنین مزایا و معایب و تفاوت هایی که دارن رو بررسی کردیم و یکی از مهم ترین الگوریتم های کاربردی یادگیری عمیق یعنی پس انتشار که به جرات می تونیم بگیم بدون اون یادگیری وجود نداشت چرا که در بسیاری از تسک ها بدون آپدیت کردن وزن ها امکان به وجود اومدن کارکرد های امروزه شبکه های عمیق وجود نداشت.
در پارت 3 میخواهیم به معماری های شبکه های عصبی مصنوعی بپردازیم. می توانیم بگوییم از مهم ترین کارهای ساختن شبکه های عصبی انتخاب نوع معماری هست. در گذشته معماری هایی که داشتیم بیشتر برای تسک های خاص بود مثلا CNN در زمان مطرح شدن تنها برای پردازش تصویر مطرح شد اما امروزه می دانیم که از این نوع معماری برای انجام تسک های دیگر هم می توان بهره برد. معماری قدرتمند RNN ها با گیت هایی که دارد رو بررسی می کنیم و تفاوت هایی که با LSTM داره. LSTM در واقع حافظه کوتاه مدت - بلند در مدل های زبانی است. مثلا ChatGPT که بعد از چندین پرامپت (به سوالاتی که از ChatGPT میپرسیم پرامپت میگن) اگر از اون راجع به پرامپت های قبلی سوال کنیم مطالب قبلی را به یاد می آورد. معماری CNN ها رو بررسی می کنیم و کارکرد هایی که داره از تشخیص چهره تا تولید عکس و پردازش تصویر و ماشین های خودران تا... که همه به کمک CNN ها امکان پذیر هستند. میخوایم بفهمیم که padding چیه ؟ لایه های کانولوشنی چطور کار میکنن ؟ pooling ها رو بررسی کنیم و اینکه چه تفاوت هایی دارن ؟ لایه های کاملا متصل (FC) ها رو بررسی خواهیم کرد. من بسیار هیجان زده هستم که این ها رو بدونم شما چطور ؟ مثل من هستید؟ بریم داخل...!
معماری شبکه های عصبی (Neural network architecture)
معماری شبکه های عصبی نحوه کارکرد این شبکه را مشخص می کند. عامل بسیار مهمی برای انجام تسک های مختلف و کاربردهای بیشتر شبکه های عصبی و عمدتا در دو رویکرد یعنی شبکه های عصبی پیشخور(Feedforward Network) و شبکه های عصبی بازخورد(Feedforward). که در این مقاله پس از تجزیه و تحلیل کامل هر کدام، مقایسه ای عمیق از هر دو معماری ارائه می دهیم و از طریق برخی موارد استفاده هر ساختار شبکه عصبی را مقایسه می کنیم. برای پیاده سازی شبکه های عمیق از دو رویکرد sequential and Functional استفاده می شود در این بخش می خواهیم نحوه ساخت و رویکرد های معماری شبکه را بررسی کنیم. با من همراه باشید .
روشهای sequential and Functional in Deep learning
در Deep Learning، دو روش متفاوت برای معماری مدل های شبکه عصبی وجود دارد. sequential and Functional. استفاده از هر روش بستگی به نوع مسئله و پیچیدگی مدل و نیاز های ما می تواند باشد. هر دو روش sequential and Functional در فریم ورک های Keras و PyTorch قابل اجرا هستند.
به صورت ترکیبی هم می توانیم از هر دو روش استفاده کنیم. یعنی بخشی از مدل را با sequential بسازیم و بخشی دیگر را با روش Functional. به شرطی که ساختار مدل شما به درستی تعریف شده باشد و ورودی ها و خروجیهای هر بخش با هم سازگار باشند. مثلا در سیستم های تشخیص چهره بخشی از مدل که برای پردازش تصاویر با شبکه های کتنولوشنی (CNN) به روش Sequential ساخته و در بخش دیگر از شبکه عصبی بازگشتی (Recurrent Neural Network - RNN) برای تحلیل دنباله ها از ویژگی های تشخیص چهره با روش Functional طراحی کنید.
روش (The sequential model)
ما مدل را لایه به لایه ایجاد می کنیم. مدل Sequential به صورت خطی و ترتیبی از لایهها ساخته میشوند. یعنی خروجی یک لایه به عنوان ورودی لایه بعدی است، بدون اینکه ارتباطی میان لایههای غیرمجاوروجود داشته باشد. اما اشتراک گذاری لایه ها یا انشعاب لایه ها مجاز نیست ( در برخی مدل های شبکه که چند تسک را همزمان انجام می دهند انشعاب لایه ها را داریم ) همچنین، نمی توانید چندین ورودی یا خروجی داشته باشید.
در Keras، برای پیاده سازی مدل Sequential ابتدا کتابخانه های مورد نیاز را فراخوانی می کنیم و سپس یک مدل از Sequential را می سازیم و با استفاده از متد add() لایه ها را یکی پس از دیگری به مدل اضافه می کنیم. قطعه کد زیر یک پیاده سازی ساده از مدل Sequential است :
#Import the libraries
from keras.models import Sequential
from keras.layers import Dense
# Create a Sequential model
model = Sequential()
# Add layers to the model
model.add(Dense(units=64, activation='relu', input_shape=(100,)))
model.add(Dense(units=64, activation='relu'))
model.add(Dense(units=10, activation='softmax'))
# summary model
model.summary()
این کد یک مدل Sequential با سه لایه ایجاد میکند : دو لایه dense با توابع فعالسازی ReLU و یک لایه خروجی dense با تابع فعالسازی softmax.
روش (The functional model)
در Keras، Functional API راهی برای تعریف مدلهای یادگیری عمیق پیچیده تراست که دارای ورودیهای متعدد، خروجیهای متعدد یا لایههای مشترک هستند. Functional API روشی انعطاف پذیرتر و قدرتمند تر برای تعریف مدلها در مقایسه با مدل Sequential است که فقط پشته های خطی لایهها را پشتیبانی میکند. در یک functional models ، همچنین می توانید یک ترتیب خطی از لایه ها را با اتصال آنها به صورت پشت سرهم ایجاد کنید، اما شما می توانید معماری های بیشتری با ادغام لایهها ایجاد کنید. به این معنا که در حالی که لایه ها به صورت خطی با یکدیگر اتصال می یابند، معماری کلی مدل ممکن است خطی نباشد و شامل لایههای مختلف باشد. تفاوت اصلی بین این دو مدل در نحوه اتصال لایه ها و انعطاف پذیری آنهاست.
روش Functional API میتواند مدل هایی با معماری غیرخطی، لایههای مشترک و حتی ورودی یا خروجیهای متعدد را مدیریت کند. ایده اصلی پشت Functional API این است که هر لایه را به عنوان یک شی مجزا تعریف کنیم و سپس با تعریف صریح ورودی و خروجی هر لایه، لایه ها را به هم متصل کنیم. شبه کد زیر ابتدا لایهی ورودی با استفاده از Input تعریف میشود. سپس با استفاده از Dense، یک لایه کاملاً متصل (Fully Connected) به عنوان خروجی تعریف میشود و با استفاده از Model، مدل با ورودی و خروجی مشخص شده ساخته میشود. در نهایت، با فراخوانی summary()، خلاصهای از معماری مدل چاپ میشود. یک پیاده سازی ساده از مدل Functional API است :
#Import the libraries
from keras.layers import Input, Dense
from keras.models import Model
# The definition of input and output layers
input_layer = Input(shape=(784,))
output_layer = Dense(10, activation='softmax')(input_layer)
# Creating the model
model = Model(inputs=input_layer, outputs=output_layer)
# summary model
model.summary()
در ادامه به بررسی معماری های شگفت انگیز شبکه های عصبی می پردازیم و کاربردها و مزایا و معایب آنها را بررسی خواهیم کرد. بیایید با هم این مرزها رو بشکافیم و به قلمرو اونها سفر کنیم آماده اید ؟ بیایید بریم .
شبکه عصبی پیشخور(Feedforward Network)
این شبکه غیر تکراری است. در واقع نقطه مقابل شبکه های عصبی بازگشتی است . شبکههای عصبی فید فوروارد عمدتاً برای یادگیری نظارت شده در مواردی استفاده میشوند که دادههایی که باید آموخته شوند نه متوالی و نه وابسته به زمان هستند.
یک شبکه عصبی پیشخور از سه بخش اصلی تشکیل شده است: یک لایه ورودی، یک یا چند لایه پنهان (در صورت وجود ) و یک لایه خروجی. هر لایه اطلاعات را پردازش کرده و به لایه بعدی منتقل میکند در واقع می توان گفت که سیگنال فقط می تواند در یک جهت جریان پیدا کند. در چنین شبکه ای حلقه ها وجود ندارند و لایه خروجی به طور متمایز از لایه های دیگر عمل می کند یعنی تابع بازگشتی در آن وجود ندارد.
انواع شبکه عصبی پیشخور(Feedforward)
انواعی از شبکه های عصبی پیشخوروجود دارد که هر کدام دارای ویژگی و معماری خاصی برای کاربردهای مختلف دارند برخی از رایج ترین انواع آن عبارتند از :
شبکه عصبی پیشخور تک لایه ( Single layer feedforward network) :
ساده ترین نوع شبکه های عصبی پیشخور(feedforward network) پرسپترون (perceptron) است بنابراین، یک perceptron فقط یک لایه ورودی و یک لایه خروجی دارد. واحدهای خروجی مستقیماً از مجموع حاصل ضرب وزن (W) آنها با واحدهای ورودی مربوطه به اضافه بایاس (bias) محاسبه می شوند. این شبکهها تنها میتوانند روابط خطی بین دادهها را یاد بگیرند و به دادههای نادرست حساس هستند و بیشتر برای کارهای طبقه بندی ساده قابل استفاده است.
شبکه عصبی پیشخور چند لایه (Multilayer feedforward network) :
این نوع شبکه دارای یک یا چند لایه پنهان بین لایه های ورودی و خروجی است. مفهوم آن این است که ANN پیشخور دارای بیش از یک لایه وزنی (لایه پنهان) است . لایههای مخفی به شبکه اجازه میدهد تا راههای پیچیدهتری برای نمایش دادههای دریافتی خود بیاموزد، که باعث میشود مشکلات پیچیدهتر را حل کند.
شبکه های عصبی بازخورد (Feedback Network)
شبکه های عصبی بازخورد همانطور که از نام آن پیداست برخلاف شبکه های عصبی دارای مسیرهای بازخورد است. که به سیگنال ها اجازه می دهد از حلقه ها برای حرکت در هر دو جهت استفاده کنند. اتصالات عصبی را می توان به هر طریقی ایجاد کرد این شبکه ها می توانند مقداری پیچیده تر باشند زیرا سیگنالها دائما در حال رفت و برگشت هستند .
هدف شبکه های عصبی بازخورد رسیدن به حالت تعادل است. حالت تعادل تا زمانی ادامه میابد که تغییری در ورودی ایجاد نشود. شبکه های پیشخور نیاز به "اندازه گیری اختلال" دارند در حالی که در شبکه های بازخورد مورد نیاز نیست. مهم ترین جز در شبکه های عصبی پیشخور ورودی داده است در حالیکه در شبکه های عصبی بازخورد خروجی مهم ترین جز است. چون که مقدار خروجی دوباره به عنوان ورودی به شبکه وارد می شود و وزن و بایاس جدید مشخص می شود تا خروجی جدید مشخص شود و این چرخه تا زمانیکه نتیجه مطلوب حاصل شود ادامه پیدا میکند.
شبکه عصبی بازخورد میتواند شامل انوع مختلفی از توپولوژی ها باشد که هر کدام با استفاده از حلقه ها می توانند مسائل مختلف را به خوبی حل کنند .
1. شبکه های عصبی مکرر (Recurrent neural network (RNN))
یکی از انواع مهم و پایه ای شبکه های عصبی مصنوعی است که جهت جریان داده ها درآن به صورت بازخورد است. در واقع یک شبکه عصبی دو طرفه است . به عبارت دیگر داده ها به شبکه وارد می شود بعد از پردازش داده ها و اعمال وزن ها خروجی تولید شده از طریق پس انتشار مجدد برای تنظیم وزن های جدید به شبکه باز می گردد. ما می توانیم از RNN هایی که با داده های زمانی کار می کنند برای پردازش ویدئو و پردازش صدا مثلا در خودرو های خودران استفاده کنیم . مهم ترین مشکلی که RNN ها می توانند داشته باشند مشکل گرادیان محو شونده (Vanishing Gradient Problem) که ممکن است در زمان آموزش به وجود بیاید. این مشکل معمولاً در شبکههای RNNs ساده ای که با استفاده از بازگشت به عقب در زمان (BPTT) آموزش داده میشوند وجود دارد.
در واقع، در هنگام عمیقتر شدن شبکه، در فرآیند پس انتشار گرادیان (Backpropagation)، گرادیانها (مشتقات جزئی) که از لایههای بالاتر به لایههای پایینتر منتقل میشوند، به سمت صفر میل میکنند و در نتیجه وزنهایلایههای پایین تر بروزرسانی نمی شوند که باعث می شود این لایهها اطلاعات کمتری از ورودیها به دست بیاورند و باعث مشکل در یادگیری و حفظ اطلاعات بر روی دنبالههای بلند میشود.
شبکه های بازشگتی مکرر میتوانند انواع مختلفی داشته باشند و هر کدام برای وظیفه خاصی مورد استفاده قرار می گیرند :
شبکههای بازگشتی ساده ((Simple RNNs :
معمولا با یک لایه بازگشتی ساده ساخته می شوند ومی توانند مشکلات لحظه ای را برای مسائل کوچک حل کنند. مثلا می توانند پیشبینی یک حرف بعدی در یک رشته متنی یا یک عدد بعدی در یک دنباله عددی مناسب باشد . اما در طول زمان چون که فقط از یک واحد حافظه استفاده میکنند ممکن است با مشکل محو شوندگی (Vanishing Gradient Problem) مواجه شود .
شبکههای بازگشتی پرسه ((Gated Recurrent Unit – GRU :
مانند LSTM ها از یک ساختار پیچیده برخوردار هستند که امکان یادگیری و حفظ اطلاعات طولانی مدت را فراهم میکند. GRU ها از لحاظ محاسباتی سبک تر از LSTM ها هستند چون که برای یادگیری از دو گیت استفاده می کنند. که باعث می شود GRU ها برای آموزش و اجرا سریعتر باشند.
در واقع GRU ها می توانند از حافظه طولانی مدت برای یادگیری الگوهای پیچیده در زبان ها استفاده کنند. به این دلیل است که GRU ها از دو گیت استفاده می کنند: گیت ورودی (Update Gate) تعیین می کند که چه مقدار از اطلاعات گذشته باید با اطلاعات جدید ترکیب شود. گیت خروجی (Reset Gate) تعیین می کند که چه مقدار از اطلاعات گذشته باید حفظ شود و چه مقدار باید فراموش شود. در واقع، هر دو LSTM و GRU می توانند از حافظههای طولانی مدت برای نگه داری الگوها و اطلاعات طولانی مدت استفاده کنند، اما با رویکردهای متفاوتی این کار را انجام می دهند.
همچنین LSTM ها نیز حافظه بلند مدت دارند. اما به این دلیل که دروازه فراموشی (Forget Gate) گیت فراموشی دارند و این گیت تعیین می کند که چه مقدار از اطلاعات گذشته باید فراموش شود. و در GRU چون دروازه فراموشی (Forget Gate) ندارد می تواند حافظه بلند مدت تری داشته باشد. در واقع رویکرد و ساختار دقیق آنها متفاوت است.
در برخی موارد، LSTM همچنان به عنوان یک انتخاب معمول برای وظایفی مانند مدلسازی زبانی یا ترجمه ماشینی مورد استفاده قرار میگیرد به دلیل قدرت بیشتری در نگهداری و کنترل اطلاعات دارند .
مثلا Google Translate گوگل ترنسلیت از یک ترکیبی از GRU ها و LSTM ها استفاده می کند. این ترکیب به گوگل ترنسلیت اجازه می دهد تا هم از مزایای GRU ها و هم از مزایای LSTM ها بهره مند شود.
شبکههای بازگشتی دوطرفه (Bidirectional RNNs) :
از دو لایه RNN که در جهت جلو و عقب هستند استفاده می کند که این امکان را به شبکه می دهد در لحظه از اطلاعات قبلی و بعدی استفاده کند. این نوع شبکه می تواند در تفسیر متون و دنباله ها موثر باشد. روش های یادگیری در آن می تواند مانند یادگیری در شبکه های یک طرفه باشد.
روشهای یادگیری شبکههای بازگشتی دوطرفه (Bidirectional RNNs) می تواند سه نوع باشد .
نوع اول جلو به عقب (Forward-Backward Learning) در این روش، دو لایه RNN در جهت جلو و عقب دنباله ورودی به ترتیب یاد می گیرند.
نوع دوم پیشبینی همزمان (Simultaneous Prediction) در این روش، خروجی شبکه از هر دو جهت (جلو و عقب) همزمان پیشبینی میشود.
نوع سوم پیش بینی و تصمیمگیری (Prediction and Decision Making) در این روش، ابتدا با استفاده از شبکه دوطرفه خروجیهای مورد نیاز برای تصمیم گیری یا پیشبینی محاسبه میشوند . در همه انواع یادگیری خروجی نهایی با ترکیب خروجی های هر دو لایه به دست می آید و این مسئله باعث می شود در وظایفی مانند ترجمه ماشینی، تحلیل احساسات و تولید متن، شبکههای بازگشتی دوطرفه اطلاعات قبلی و بعدی را در نظر بگیرند و نتایج بهتری ارائه دهند. و به عنوان یکی از روشهای موثر و قدرتمند در این حوزهها شناخته میشود.
شبکههای بازگشتی طولانی-مدت کوتاه (Long Short-Term Memory - LSTM) :
حافظه کوتاه-مدت بلند یا LSTM یک نوع معماری شبکه عصبی بازگشتی است. که برای حل مشکل گرادیان ناپدید شونده که در شبکههای عصبی بازگشتی سنتی رخ میدهد طراحی شده است. اصلیترین تفاوت بین LSTM (حافظه کوتاه-مدت بلند) و RNN های سنتی (شبکههای عصبی بازگشتی) در توانایی آنها برای گرفتن و حفظ وابستگیهای بلندمدت در دادههای دنبالهای است. LSTM این مشکل را با معرفی یک سلول حافظه با دروازههایی (دروازه ورودی، دروازه فراموشی و دروازه خروجی) که جریان اطلاعات را کنترل میکنند، حل میکند. این دروازهها لایههای شبکه عصبی هستند که تصمیم می گیرند کدام اطلاعات در سلول حافظه حذف یا ذخیره یا خروجی شوند. این معماری اجازه میدهد تا LSTM حافظه بلندمدت را حفظ کرده و بهطور انتخابی آن را در طول زمان بهروزرسانی کند.
درواقعLSTM ها با استفاده از بازگشت عمیق زمانی (BPTT) آموزش داده میشوند، در این فرایند مدلها را به گذشته "عمیق" تر از یک فرآیند بازگشتی ساده میبریم. که در دو مرحله که شامل فید فوروارد (Forward Pass) است که ، داده ورودی به مدل داده می شود و خروجی محاسبه می شود. این خروجی با خروجی مورد انتظار مقایسه می شود تا خطا محاسبه شود.و سپس بازگشت در زمان (Backpropagation) که شبیه به مرحله عادی بازگشت به عقب است. با استفاده از قاعده زنجیرهای، گرادیان خطا نسبت به وزن ها و پارامترهای دیگر شبکه محاسبه میشود. بروزرسانی پارامترها در این مرحله، وزنها و سایر پارامترهای شبکه با استفاده از گرادیانهای محاسبه شده بروزرسانی میشوند تا خطا کمترین مقدار شود.
شبکه LSTMها برای وابستگیهای بلندمدت حیاتی هستند، مانند ترجمه ماشینی، تشخیص گفتار و تحلیل احساس، مناسب تر هستند. LSTM با حافظه کوتاه مدت انسان برخی ویژگی ها و اصول کاری مشترکی را دارند. همانطور که حافظه کوتاه مدت انسان می تواند اطلاعات را برای مدت زمان طولانی (مانند چند دقیقه تا چند ساعت) حفظ کند، LSTM نیز با استفاده از مکانیسم های خود می تواند اطلاعات را برای مدت زمان طولانی در حافظه سلولی خود نگهداری کند. هر دو دارای مکانیسم هایی برای فراموشی و حذف اطلاعات غیرضروری هستند. مثلاً، در LSTM، دروازه فراموشی مسئول حذف اطلاعات غیرمهم از حافظه سلولی است. هر دو قادرند الگوها و وابستگی های پیچیده در داده های ورودی را یاد بگیرند و حفظ کنند. به همین دلیل، در برخی موارد، میتوان از LSTM به عنوان یک مدل مفهومی برای توصیف حافظه کوتاه مدت الهام گرفت.
2. شبکهی بازگشتی کامل (Fully recurrent network)
همانطور که از نام آن مشخص است در این نوع از معماری شبکه های عصبی همه نورون ها در لایه ها کاملا به نورون های دیگر متصل اند. یعنی هر نورون هم به عنوان ورودی و هم به عنوان خروجی عمل می کند. شبکه های کاملاً بازگشتی برای پردازش داده های توالی با طول های متفاوت مناسب هستند. مانند متن، گفتار، ترجمه ماشینی یا پیش بینی سری های زمانی، مانند پیش بینی قیمت های بازار مالی یا ترافیک. اما یکی از مشکلات اصلی گرادیان ناپایدار(Gradient Descent) است که در شبکههای عصبی، از جمله شبکههای بازگشتی کامل، مطرح است. که موجب محو یا انفجار گرادیانها میشود.
در حالت محو گرادیان، گرادیان ها به سمت صفر کاهش می یابند و بنابراین قدرت یادگیری شبکه کاهش می یابد. در حالت انفجار گرادیان، مقادیر گرادیان ها به سمت بی نهایت افزایش می یابند. می تواند به انحراف از مسیر بهینه یا حتی منجر به خرابی شبکه شود. برای حل این مشکل، میتوان از تکنیک های بهبود گرادیان استفاده کرد. یکی از این تکنیکها آموزش با نزول گرادیان برگشتی و(Backpropagation Through Time) است.
مشکل دیگر FRNN ها پیچیدگی محاسباتی آنها است. تعداد زیاد ارتباطات بین نورون ها می تواند آموزش FRNN ها را کند و دشوار کند. علاوه بر این، FRNN ها می توانند به راحتی دچار بیش برازش شوند، به خصوص با داده های محدود.
با انجام بهبودها در روشهای آموزش و بهینهسازی، همچنین استفاده از تکنیکهای کاهش پیچیدگی مانند روشهای تقریب و تحلیل داده، ممکن است این چالشها در شبکههای عصبی بازگشتی بازنگری و عملکرد آنها را بهبود داد.
3. شبکه های Elman و Jordan
شبکههای جوردان ( Jordan network) ساده ترین نوع از شبکههای عصبی بازگشتی (RNN) هستند. اطلاعات ورودی به هر نورون از شبکه وارد می شوند و به همان نورون به عنوان ورودی ارسال می شود. این شبکه ها تنها یک لایه پنهان دارند. فعالسازی هم در لایه پنهان و هم در لایه خروجی انجام می شود. از الگوریتم های Backpropagation برای بهینه سازی پارامترها استفاده می کنند.
شبکه های جوردن می توانند وابستگی های طولانی مدت در دادههای دنبالهای را یاد بگیرند. مانند سایر RNN ، شبکههای جوردن نیز می توانند دچار vanishing gradient problem شوند، که باعث می شود یادگیری وابستگی های طولانی مدت دشوار شود. این معماری به شبکه اجازه می دهد تا اطلاعات را از لحظهی فعلی به لحظهی بعدی منتقل کند.
می توان از آن برای پیش بینی قیمتها، تحلیل سری های زمانی مالی، یا پردازش زبان طبیعی (NLP) استفاده کرد. شبکههای Elman مانند شبکه های جوردن هستن با این تفاوت مهم که فعالسازی را فقط در لایه پنهان انجام می دهند، فعاسازی در لایه خروجی به شبکه های جوردن اجازه می دهد تا وابستگی های طولانی مدت را بهتر از شبکههای Elman یاد بگیرند. البته همین ویژگی می تواند باعث کاهش کارایی محاسباتی شبکه های جوردن شود.
به دلیل سادگی زیاد و عدم توانایی حل مسائل پیچیده که امروزه مورد استفاده هستند و این معماری شبکه کارایی خاصی ندارد. البته بستگی به نوع کاری که انجام می شود ممکن است مورد استفاده قرار بگیرند.
4. شبکه های عصبی کانولوشنی (convolutional neural networks)
شبکه های عصبی کانولوشنی یا CNN واژه ای که نام آن را بارها شنیده ایم. می توان گفت انقلابی که هم اکنون شاهد آن هستیم یکی از پایه های اصلی آن شبکه های CNN اما سوال اینجاست که CNN چطور کار میکنه ؟ تفاوتش با بقیه شبکه ها در چیه ؟ باید به گذشته برویم . با من همراه باشید سفر جالبیه میگی نه ؟ امتحان کن !
اولین بار در دهه 80 توسط Yann LeCun مطرح شد. اما برای پیاده سازی آن نیاز به محاسبات زیادی بود که در آن زمان میسر نشد. تا اینکه در سال 1998 مقاله ای با عنوان" Gradient-based learning applied to document recognition" در کنفرانس IEEE ارائه شد . پس از ارئه این مقاله استفاده از شبکههای عصبی پیچشی به طور گسترده تر در حوزه تشخیص الگو و پردازش تصویر بسیار افزایش پیدا کرد. مخصوصا با پیشرفت هایی که در انجام محاسبات سریع در شبکه های عمیق انجام شد و با ظهو GPUs استفاده از شبکه های عصبی کانولوشنی بسیار مورد توجه قرار گرفت . تشخیص اشیاء، تشخیص چهره، تشخیص اثر انگشت، خودروهای خود ران ، پردازش زبان طبیعی و غیره .
اما CNN ها چطور کار مکنن؟
ما زمانیکه به یک تصویر نگاه می کنیم در کسری از ثانیه با پردازش هایی که در مغز انجام می شود و با دانشی که از قبل داریم به سرعت تصویر را تشخیص دهیم اما برای کامپیوتر به این صورت نیست ماشین ها باید پیکسل به پیکسل یک تصویر را ببینند.
الگوی اتصال بین نورون ها در CNN ها از قشر بینایی حیوانات الهام گرفته شده است . بیشترین شباهت آنها این است که هر دو معمولاً از یک ساختار سلسله مراتبی برای پردازش اطلاعات استفاده می کنند، به این معنا که اطلاعات از لایه به لایه پردازش می شوند و ویژگیهای پیچیده تر در لایههای بالاتر به دست میآید. CNN ها از فیلترهای کانولوشنی برای استخراج ویژگی ها از تصاویر استفاده میکنند، که الهام گرفته از نحوه عملکرد نورونهای قشر بینایی مغز است.
عملکرد CNN ها و عاملی که تفاوت آنها را با سایر معماری های شبکه مشخص می کند اصول این معماری است. در واقع در هر لایه CNN پیچید گی را افزایش می دهد و بخش های بیشتری از تصویر را شناسایی می کند. لایه اول لایه های کانولوشنی است. اعمال فیلترها برای فهمیدن ویژگی ها. سپس لایه ادغام (pooling)که در لایه های پنهان برای استخراج مهم ترین ویژگی ها برای فرستادن به لایه آخر که لایه کاملا متصل (Fully connected layers) است تا وظایف بینایی ماشین انجام شود .
با من همراه باشید تا لایه های CNN را بشکافیم.
لایه کانولوشنی (Convolutional Layer)
لایه اصلی CNN است و بیشتر محاسبات در آن انجام می شود. تصاویری که به این لایه وارد می شود. می تواند با پیچیدگی بیشتر یا کمتر همراه باشد. تصاویر 2D که داری عرض و ارتفاع هستند و می توانند تک کاناله (خاکستری ) باشد یا 3 کاناله RGB (رنگی) و تصاویر 3D که عمق هم دارند مانند تصاویر پزشکی (سی تی اسکن و ام ار ای) که پیچیدگی مدل را بیشتر می کند .
قطعه کد زیر با استفاده ازمتد `Conv2D` یکی از اعضای ماژول `layers` برای ساختن یک لایه کانولوشنال در Keras است :
# Adding a convolutional layer with 3 filters of size 3x3 and ReLU activation function
model.add(layers.Conv2D(3, (3, 3), activation='relu', input_shape=(28, 28, 1)))
پارامترinput_shape شکل دادههای ورودی را مشخص می کند که ابعاد آن (28,28,1) است و تصویر خاکستری با ابعاد 28 x 28 پیکسل را نمایش می دهد.
لایه کانولوشنی شامل فیلترهای کانولوشنی است. این فیلترها همچنین به عنوان کرنلها (kernel) نیز شناخته می شوند. هر نورون در لایه کانولوشنی به یک فیلتر مشخص وزن دار (یا همان ماتریس وزن) متصل است. برای نمایش اطلاعات فیلترها، میتوانیم از ویژگیهای لایه استفاده کنیم. این ویژگیها معمولاً پس از تعلیم مدل دسترسی پیدا میکنند. به عنوان مثال، پس از آموزش مدل، میتوانید به وزنهای هر لایه دسترسی پیدا کنید و آنها را چاپ کنید.
قطعه کد زیر در Keras چگونگی دسترسی به وزنهای لایه کانولوشنال را نشان می دهد :
# Accessing the weights of the convolutional layer
weights = model.layers[0].get_weights()[0]
# Printing the dimensions of the filter weights
print("Filter dimensions:", weights.shape)
هر کدام از این فیلتر ها ویژگی های مختلفی از تصویر را استخراج می کنند. این ویژگی های استخراج شده شامل لبه ها، نقاط روشن و تیرگی هستند که به آن نقشه ویژگیها ( Feature Map) می گویند. فیلتر Sobel و فیلتر Scharr از فیلترهای پرکاربرد در پردازش تصویر هستند که برای تشخیص لبه های عمودی و افقی و علامتگذاری گرادیانها در تصویر استفاده میشوند. زمانی که این فیلترها بر روی تصویر اعمال میشوند، از طریق محاسبه مشتقهای جزئی تصویر در جهتهای افقی و عمودی، میزان تغییرات شدت رنگ یا روشنایی در نقاط مختلف تصویر را اندازه گیری می کنند.
با این حال، تفاوت اصلی بین این دو فیلتر در ویژگیهای هسته (یا ماتریس)آنها است. هسته یا ماتریس فیلتر Sobel با تمرکز بیشتر بر روی تغییرات افقی و عمودی در تصویر تعریف شده است. تشخیص لبهها توسط فیلتر Scharr مستقل از جهت آنها است، به عبارت دیگر، اگر لبهای در تصویر وجود داشته باشد، بدون درنظر گرفتن اینکه لبه افقی یا عمودی باشد فیلترScharr می تواند آن را به خوبی تشخیص دهد، به طور مثال در تشخیص اشیاء یا اجزای تصویر، جهت لبه ممکن است اهمیت کمتری داشته باشد و مهم این است که لبهها به درستی شناسایی شوند.
نمونه کد برای اعمال فیلترهای Sobel و Scharr در Python و OpenCV:
# Calling the OpenCV library
import cv2
# Apply Sobel filter
sobel_x = cv2.Sobel(image, cv2.CV_64F, 1, 0, ksize=3)
sobel_y = cv2.Sobel(image, cv2.CV_64F, 0, 1, ksize=3)
# Apply Scharr filter
scharr_x = cv2.Scharr(image, cv2.CV_64F, 1, 0)
scharr_y = cv2.Scharr(image, cv2.CV_64F, 0, 1)
پدینگ (Padding )
برای ساختن مدلهای پیچیده مانند شبکه های عصبی کانولوشن (CNN) یا شبکههای عصبی تکراری (RNN)، یک شکل ورودی استانداردمورد نیاز است. هنگامی که فیلتر از ابتدای تصویر حرکت میکند، بخشی از اطلاعات از لبههای تصویر از دست می رود و این باعث کاهش ابعاد تصویر خروجی از لایههای کانولوشنال میشود.
عدم وجود Padding ممکن است باعث شود که ابعاد تصویر خروجی از لایههای کانولوشنال به اندازه ای کوچکشود که عملیات Convolution بر روی آنها را به درستی انجام نشود. یکی از مزایای اصلی paddingتوانایی آن در استاندارد سازی داده های ورودی است. عملیات Padding در CNN با افزودن مقادیر صفر به لبههای تصاویر ورودی یا نقشه ویژگی اشاره دارد. معمولا با دو روش قابل پیاده سازی است.
پدینگ صفر) ( Zero Padding
در روش Zero Padding ، اطلاعاتی که به لبه های تصویر اضافه می شوند با مقادیر صفر پر می شوند. که می تواند باعث کاهش وضوح تصویر شود. استفاده از Zero Padding میتواند منجر به افزایش مصرف حافظه در مدلهای عصبی شود، زیرا با افزودن صفرها به لبههای تصویر، حجم دادهها افزایش مییابد که می تواند برای پردازش تصاویر بزرگ مشکل آفرین باشد. Zero Padding امکان ایجاد شبکه های عمیق تر با حفظ ابعاد خروجی و حفظ اطلاعات مربوط به لبه های تصاویر و افزایش سرعت محاسبات را می دهد اما ممکن است هزینه محاسباتی را بیشتر کند. می تواند برای افزایش اندازه تصویر و حفظ وضوح لبه ها برای بهبود دقت تشخیص اشیاء استفاده شود.
برای اجرای عملیات Zero Padding در کتابخانه TensorFlow میتوانید از تابع () tf.pad استفاده کنید. این تابع به شما اجازه میدهد تا با اضافه کردن صفرها یا مقادیر دلخواه دیگر به لبههای تصویر، Padding را انجام دهید:
# Apply Zero Padding by adding 2 rows and 2 columns of zeros to the edges of the image
padded_image = tf.pad(image, [[0, 0], [2, 2], [2, 2], [0, 0]], "CONSTANT")
پدینگ معتبر (Valid Padding)
در روش Valid Padding ، در مقایسه با Zero Padding، هیچ داده ای به لبه های تصویر اضافه نمی شود. در واقع هیچگونه Padding ای انجام نمی شود. به عبارت دیگر، فیلترها (کرنلها) به طور کامل فقط بر روی قسمتهایی از ورودی که اندازهی کرنل با آن مطابقت دارد، حرکت میکنند. در نتیجه تصویر خروجی از لایههای کانولوشنال اندازهی کوچکتری نسبت به تصویر ورودی خواهد داشت که منجر به کاهش حجم دادهها و همچنین کاهش پیچیدگی محاسباتی میشود همچنین زمان اجرا کاهش مییابد.
وقتی که ما به دنبال استخراج ویژگیها و الگوهای موجود در تصویر هستیم و اندازه تصویر خروجی برای وظایف بعدی ما اهمیت زیادی ندارد، میتوان از Valid Padding استفاده کرد. در واقع خیلی از معایب Zero Padding را نداریم . در دنیای واقعی، روش Valid Padding معمولاً در وظایفی مانند تشخیص اشیاء، طبقهبندی تصاویر، و شناسایی الگوها استفاده میشود که افزایش اندازه تصویر خروجی مورد نیاز نیست و ما به دنبال افزایش سرعت و کارایی محاسباتی هستیم. در شبه کد ساده زیر یک لایه Conv2D با Valid Padding تعریف میکنیم که با تنظیم پارامتر padding به 'valid' انجام میشود:
# Define a Conv2D layer with Valid Padding
conv_layer = Conv2D(filters=16, kernel_size=(3, 3), padding='valid', activation='relu', input_shape=(28, 28, 1))
استفاده از هر کدام از روش های Padding بستگی به نوع مسئله و شرایط دارد. Paddingمعمولاً در مرحلهی پیشپردازش تصاویر و قبل از عملیات Convolution انجام میشود. در مدلهای شبکه عصبی، Padding میتواند به عنوان یک لایه جداگانه به مدل اضافه شود و یا در تابعیت Convolution اعمال شود.Top of Form
این داده ها سپس به Pooling layers شبکه CNN منتقل می شوند تا ویژگیهای پیچیده تری را برای وظایفی مانند تصویربرداری یا دسته بندی تصاویر استخراج کنند.
یکی از تفاوت های اساسی CNN برای پردازش تصویر با روش های قدیمی آن این است که قبلا این فیلتر ها با استفاده از فیلترهای محلی (Local Filters)باید دستی انجام می شد.
لایه Pooling layers
برای کاهش ابعاد فضایی (طول و عرض) نقشه ویژگیها ( Feature Map) با حفظ اطلاعات مهم عملیاتpooling انجام می شود. Pool ها معمولاً به صورت پنجرههای متحرکی روی نقشه ویژگی ها حرکت می کنند و هر بار مقداری از نقطه شروع تا نقطه پایان این پنجره را با استفاده از معیار مشخص شده (مثل ماکسیمم یا میانگین) انتخاب می کنند. این عملیات به صورت مکرر اعمال می شود تا ابعاد فضایی نقشه ویژگی ها کاهش یابد و اطلاعات مهم حفظ شود. این عملیات به کاهش پیچیدگی مدل کمک میکند و از جمله عواملی است که باعث افزایش سرعت و کارایی شبکه میشود. همچنین مواردی مانند overfitting را کاهش میدهد. Pooling دو نوع رایج دارد که هر کدام برای وظایف خاصی مناسب هستند.
روش Max Pooling
وقتی فیلتر (یا همان kernel) کانولوشنی روی تصویر ورودی حرکت میکند. بخشی از فیلتر اغلب با بخشی از تصویر قبلی و قسمت دیگری از فیلتر با بخشی از تصویر جدید همپوشانی دارد. این مدل بیشترین مقادیر از هر ناحیه همپوشانی (Overlapping Region) در نقشه ویژگیها را می گیرید و مقدار بیشینه آن را به عنوان مقدار خروجی این ناحیه انتخاب میکنیم. با این حال، Max Pooling ممکن است اطلاعات دقیق را از دست بدهد زیرا تنها مقدار بیشینهرا برای هر ناحیه انتخاب می کند و مقادیر کوچک تر را نادیده می گیرد.
ناحیه همپوشانی به نوعی hyperparameter محسوب می شود. میتوان آن را براساس نیاز و ویژگی های مسئله تنظیم کرد. ممکن است افزایش ناحیه همپوشانی، باعث افزایش تعداد ویژگی های استخراج شده مدل آموزش بیشتری نیاز داشته باشد و زمان آموزش مدل افزایش یابد. این می تواند باعث افزایش پیچیدگی مدل و بیشبرازش (overfitting) شود.
در ادامه یک شبه کد ساده برای Max Pooling در Keras داریم که لایه MaxPooling2D از Keras برای انجام عملیات Max Pooling استفاده کردایم و pool_size اندازه فیلتر Max Pooling را مشخص میکند:
# Importing the necessary layers from Keras
from keras.layers import MaxPooling2D
# Adding a Max Pooling layer to the model
model.add(MaxPooling2D(pool_size=(2, 2), strides=None, padding='valid'))
روش Average Pooling
در این روش، برخلاف Max Pooling ، میانگین مقادیر در هر ناحیهی همپوشانی را می گیریم و آن را به عنوان مقدار خروجی انتخاب میکنیم. Average Pooling معمولاً برای کاهش ابعاد فضایی نقشه ویژگیها استفاده میشود و باعث ایجاد یک تصویر با کیفیت واضح ترمی شود. در این روش اطلاعات دقیقی که در ناحیه های کوچکی از تصویر ورودی وجود دارند، میانگین گیری می شوند. که ممکن است به ویژگی های محلی که در آن ناحیه ها وجود دارند، کمتر توجه شود و اطلاعات دقیق آنها از بین برود. این کاهش اطلاعات جزئی می تواند باعث جلوگیری از آموزش مدل و کم برازش (underfitting) شود. به خصوص در مواردی که جزئیات کوچکی از تصویر برای وظایف مختلف اهمیت دارند، مانند تشخیص الگوهای دقیق یا تصویربرداری دقیق . بنابراین این روش باید با دقت و با در نظر گرفتن موارد خاص مسئله استفاده شود.
یک شبه کد ساده برای فهمیدن بهتر Average Pooling در Keras در زیر مشاهده کنید :
from keras.layers import AveragePooling2D
# Add Average Pooling layer with specified pool size
model.add(AveragePooling2D(pool_size=(2, 2)))
لایه Fully connected layers
در یک لایههای کاملاً متصل (Fully connected layers)، هر نورون یا گره به هر نورون در لایه قبلی متصل است. این بدان معناست که تمام سیگنالهای ورودی از لایه قبلی برای خروجی هر نورون در نظر گرفته می شوند.
لایه های Fully connected اغلب در مراحل نهایی یک شبکه عصبی برای وظایفی مانند طبقه بندی یا رگرسیون استفاده می شوند. مشکل اصلی دراین لایه ها که دارای تعداد زیادی پارامتر با قابلیت حفظ اطلاعات زیادی هستند overfitting است. برای جلوگیری از این مشکل دو راه حل افت گذاری (dropout) و رگولاریزاسیون می تواند موثر باشد.
در روش dropout ، در هر مرحله از آموزش، به طور تصادفی تعدادی از نورون ها و اتصالات بین آن ها حذف میشوند. dropout به طور کلی باعث ایجاد یک شبکه عصبی انعطاف پذیرتر می شود. همچنین رگولاریزاسیون هم با هدف کاهش پیچیدگی مدل، به کمک ضریب معینی از وزن ها به تابع هدف اضافه میشود تا مقدار وزنها را محدود کند و از بزرگ شدن آن ها جلوگیری کند. معمولاً از رگولاریزاسیون L1 و L2 استفاده می شود که به ترتیب به عنوان "رگولاریزاسیون لیسو و رگولاریزاسیون مربعی" شناخته میشوند.
در L1، جمله رگولاریزاسیون به صورت مجموع مقادیر مطلق وزن ها اضافه میشود. این باعث میشود که برخی از وزن ها صفر شوند، و به این ترتیب مدل وزن های غیرضروری را حذف کند. در L2، جمله رگولاریزاسیون به صورت مجموع مربعات وزن ها اضافه می شود. این باعث می شود که وزن ها کوچک شوند اما به صورت پیوسته، بدون اینکه به صفر برسند. این اجازه را می دهد که همه ویژگی ها با وزن های مختلف مؤثر باشند، اما به اندازه کمتری نسبت به بدون رگولاریزاسیون.
همه توضیحات داده شده راجع به FC را در قطعه کد زیر به طور خلاصه میبینیم:
import tensorflow as tf
# Define the model
model = tf.keras.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28)), # Input layer: Convert images to vectors
tf.keras.layers.Dense(128, activation='relu'), # Fully connected layer with 128 neurons and ReLU activation
tf.keras.layers.Dropout(0.2), # Dropout with rate 0.2
tf.keras.layers.Dense(64, activation='relu'), # Fully connected layer with 64 neurons and ReLU activation
tf.keras.layers.Dropout(0.2), # Dropout with rate 0.2
tf.keras.layers.Dense(10, activation='softmax') # Output layer with 10 neurons for classifying 10 different classes and softmax activation
])
این کد لایههای کاملاً متصل (FC) را تعریف میکند و از افتگذاری (Dropout) برای رگولاریزاسیون استفاده میکند.
نتیجهگیری پارت 3
در این مقاله سعی کردم که مهم ترین و پایه ای ترین مباحث مربوط به شبکه های عصبی و deep learning را از آغاز تا الان بیان کنم و عمیق و عمیق تر به لایه های بسیارمتراکم deep learning وارد شویم. اما این آغاز راه است. چون که مرزهای deep learning بسیار باریک است و شبکه های مختلف deep در حال کامل شدن هستند. در واقع امروزه استفاده از شبکه های بادگیری عمیق برای انجام وظایف مختلف ترکیب شده است. همانطور که می دانیم محصولاتی داریم که همزمان در آنها پردازش زبان طبیعی انجام شده باشد و هم مثلا تولید عکس انجام دهد یا برعکس. بنابراین مرزهای یادگیری عمیق در حال تنیده تر شدن هستند و خیلی از مباحث در این مقاله پوشش داده نشد در آینده به مباحث بیشتر خواهیم پرداخت .
ممنون از شما که در این سفر به دنیای Deeps با من همراه بودید.
لینک مقاله به انگلیسی در Medium
پارت 1 : تاریخچه هوش مصنوعی و چگونگی عملکرد شبکه های عصبی ساده
پارت 3 : انواع مهم ترین معماری های شبکه های عصبی عمیق (RNN / LSTM / CNN )
لطفا اگر مایل بودید مقاله دیگر من " آیا DeepFake فناوری آیندهای است یا یک تهدید؟ آیا خط میان واقعیت و ساختگی از بین خواهد رفت؟" رو در ویرگول ببینید .
استخراج داده با پایتون – راهنمای جامع برای بهرهبرداری از APIها
امیدوارم از مطالب لذت برده باشید .
مطلبی دیگر از این انتشارات
آموزش Unit Test در Golang
مطلبی دیگر از این انتشارات
سری OOP (قسمت اول)
مطلبی دیگر از این انتشارات
آموزش نصب پایتون روی ویندوز