در این مطلب، آموزش ساخت یک «شبکه عصبی» (Neural Network | NN) ساده با استفاده از کتابخانه یادگیری عمیق «کرس» (Keras) در «پایتون» (Python) ارائه شده است. برای فراگیری هر چه بهتر این مطلب، آشنایی با کتابخانه‌های «سایکیت‌لِرن» (scikit-learn) و دیگر بسته‌های علمی مانند «پانداس» (Pandas) و «نام‌پای» (Numpy) پیش‌نیاز محسوب می‌شود.

آموزش یک شبکه عصبی مصنوعی

آموزش دادن (train) یک «شبکه عصبی مصنوعی» (Artificial Neural Network | NN) شامل گام‌های زیر است:

  1. وزن‌ها به طور تصادفی با مقادیر نزدیک به صفر (ولی غیر صفر) مقداردهی اولیه می‌شوند.
  2. مشاهدات مجموعه داده به لایه ورودی خورانده می‌شود.
  3. انتشار به جلو (از چپ به راست): نورون‌ها فعال می‌شوند و مقادیر پیش‌بینی شده مشاهده می‌شوند.
  4. نتایج پیش‌بینی شده کامپیوتری با مقادیر واقعی مقایسه می‌شوند و نرخ خطا اندازه‌گیری می‌شود.
  5. بازگشت به عقب (از راست به چپ): وزن‌ها تنظیم می‌شوند.
  6. مراحل 1 تا ۵ تکرار می‌شود.
  7. هنگامی که کل «مجموعه آموزش» (Train Set) از شبکه عصبی رد شد، یک «دوره» (Epoch) حاصل می‌شود.

مساله کسب‌و‌کار

اکنون زمان آن فرا رسیده که یک مساله واقعی از کسب‌و‌کار با استفاده از شبکه عصبی و کتابخانه پایتون کِرَس حل شود. یک شرکت بیمه دارای مجموعه داده‌ای از ادعاهای پیشین مشتریان خود است. شرکت بیمه از کارشناس داده‌کاوی می‌خواهد تا به آن‌ها در پیش‌بینی اینکه کدام ادعاها کلاهبرداری به نظر می‌رسند کمک کند. با انجام این کار، داده‌کاو به شرکت بیمه کمک می‌کند تا سالانه میلیون‌ها دلار پول را ذخیره کند. چنین مساله‌ای، از جمله مسائل دسته‌بندی محسوب می‌شود. ستون‌های این مجموعه داده (ادعاهای مشتریان شرکت بیمه) در تصاویر زیر نشان داده شده است.

مجموعه داده شرکت بیمه
برای مشاهده تصویر در ابعاد اصلی، روی آن کلیک کنید.
مجموعه داده شرکت بیمه
برای مشاهده تصویر در ابعاد اصلی، روی آن کلیک کنید.
مجموعه داده شرکت بیمه
برای مشاهده تصویر در ابعاد اصلی، روی آن کلیک کنید.

پیش‌پردازش داده‌ها

همچون بسیاری از مسائل کسب‌و‌کار، داده‌های گردآوری شده در اینجا نیز آماده انجام تحلیل نیستند. بنابراین داده‌کاو باید آن‌ها را به شکلی که قابل ارائه به الگوریتم باشد آماده‌سازی کند. با توجه به مجموعه داده مشهود است که چند ستون با نوع داده «طبقه‌ای» (Categorical) وجود دارند.

به منظور آنکه الگوریتم یادگیری عمیق قادر به درک این داده‌ها باشد، نیاز به تبدیل آن‌ها به صفر و یک است. دیگر مساله‌ای که باید به آن توجه کرد این است که باید مجموعه داده به صورت آرایه NumPy به مدل خورانده شود. با استفاده از قطعه کد زیر، بسته‌های لازم ایمپورت می‌شوند، پس از آن مجموعه داده ادعاهای بیمه بارگذاری می‌شود.

سپس، ستون‌های طبقه‌ای به «متغیرهای ظاهری» (Dummy Variables | متغیرهای مجازی) تبدیل می‌شوند.

در اینجا، از drop_first=True برای ممانعت از «تله» (Trap) متغیرهای ظاهری استفاده می‌شود. برای مثال، اگر d ، c ، b ، a طبقه‌ها باشند، می‌توان d را به عنوان متغیر ظاهری حذف کرد. این امر بدین دلیل به وقوع می‌پیوندد که اگر چیزی درون b ،a و c قرار نگرفته بود، قطعا در d هست. به این اتفاق «هم‌خطی چندگانه» (Multicollinearity) گفته می‌شود. اکنون از train_test_split کتابخانه سایکیت‌لِرن برای تقسیم داده‌ها به دسته‌های «آموزش» (training) و «تست» (test) استفاده می‌شود.

اکنون، باید اطمینان حاصل کرد که ستون هنگام پیش‌بینی حذف می‌شود تا از سرریز آن در مجموعه آموزش و تست جلوگیری شود. شایان توجه است که باید از انتخاب مجموعه داده مشابه برای آموزش و تست مدل جلوگیری شود. به منظور دریافت آرایه NumPy، در پایان مجموعه داده «values.» تنظیم می‌شود. این در واقع راهی است که مدل «یادگیری عمیق» (Deep Learning) داده‌ها را می‌پذیرد. این گام از این جهت حائز اهمیت است که مدل یادگیری ماشین ساخته شده در این مطلب داده‌ها را به شکل آرایه می‌پذیرد.

سپس، داده‌ها به مجموعه‌های آموزش و تست تقسیم می‌شوند. 0.7 از داده‌ها برای آموزش و 0.3 برای تست استفاده می‌شود.

در ادامه باید مجموعه داده را با استفاده از StandardScaler کتابخانه Sklearn «مقیاس» (Scale) کرد. به دلیل حجم بالای محاسباتی که در یادگیری عمیق انجام می‌شود، مقیاس کردن ویژگی، اجباری است. مقیاس کردن ویژگی طیف متغیرهای مستقل را استانداردسازی می‌کند.

ساخت شبکه عصبی مصنوعی

برای ساخت شبکه عصبی مصنوعی، اولین کاری که باید انجام شود ایمپورت کردن کتابخانه کِرَس است. Keras به طور پیش‌فرض از تنسورفلو به عنوان بک‌اند خود استفاده می‌کند.

سپس، نیاز به ایمپورت کردن چند ماژول از Keras است. ماژول Sequential برای مقداردهی اولیه به ANN و ماژول Dense برای ساخت لایه‌های شبکه عصبی مصنوعی استفاده می‌شود.

در ادامه، نیاز به مقداردهی اولیه به ANN با ساخت یک نمونه از Sequential است. تابع Sequential یک پشته خطی از لایه‌ها را مقداردهی اولیه می‌کند. این امر به کاربر امکان اضافه کردن لایه‌ها را در آینده و با استفاده از ماژول Dense می‌دهد.

اضافه کردن لایه ورودی (اولین لایه پنهان)

از روش add برای افزودن لایه‌های مختلف به شبکه عصبی استفاده می‌شود. اولین پارامتر تعداد «گره‌هایی» (Nodes) است که کاربر قصد دارد به این لایه اضافه کند. هیچ قاعده سرانگشتی برای محاسبه اینکه چه تعدادی گره باید اضافه کرد وجود ندارد. اگرچه، یک استراتژی متداول انتخاب تعداد گره‌ها برابر با میانگین تعداد گره‌های موجود در لایه ورودی و تعداد گره‌های لایه خروجی است.

برای مثال، اگر پنج متغیر مستقل و یک خروجی وجود داشته باشد، مجموع آن‌ها محاسبه شده و بر دو تقسیم می‌شود که برای مثال بیان شده برابر با سه است. همچنین می‌توان با روشی که «تنظیم پارامتر» (Parameter Tuning) نامیده می‌شود آزمایش کرد. دومین پارامتر، یعنی kernel_initializer، تابعی است که برای مقداردهی اولیه به وزن‌ها مورد استفاده قرار می‌گیرد. در این مورد، از یک «توزیع یکنواخت» (Uniform Distribution) برای حصول اطمینان از اینکه وزن‌ها اعداد کوچک نزدیک به صفر هستند استفاده می‌شود.

پارامتر بعدی یک «تابع فعال‌سازی» (Activation Function) است. در اینجا از تابع «یکسوساز» (Rectifier) که به صورت relu خلاصه شده به عنوان تابع فعال‌سازی استفاده می‌شود. اغلب از این تابع برای لایه پنهان در ANN استفاده می‌شود. پارامتر نهایی input_dim است که تعداد گره‌ها در لایه پنهان محسوب می‌شود. این پارامتر نشانگر تعداد متغیرهای مستقل است.

افزودن دومین لایه پنهان

افزودن دومین لایه پنهان مشابه روش مورد استفاده برای افزودن اولین لایه پنهان است.

نیازی به تعیین پارامتر input_dim نیست، زیرا در حال حاضر در اولین لایه پنهان مشخص شده است. در اولین لایه پنهان این متغیر مشخص شده تا به لایه این امکان داده شود که بداند انتظار چه تعدادی گره ورودی را داشته باشد. در دومین لایه پنهان، ANN می‌داند که باید انتظار چه تعدادی گره ورودی را داشته باشد، بنابراین نیازی به تکرار این کار نیست.

افزودن لایه خروجی

اولین پارامتر باید تغییر کند زیرا در گره خروجی انتظار یک گره می‌رود. به این دلیل که در این مساله، هدف صرفا مشخص کردن کلاهبرداری بودن یا نبودن یک ادعا است. این کار با استفاده از «تابع فعال‌سازی سیگموئید» (Sigmoid Activation Function) انجام می‌شود. در شرایطی که مساله دسته‌بندی و دارای بیش از دو کلاس باشد (مانند دسته‌بندی گربه‌ها، سگ‌ها و میمون‌ها)، نیاز به تغییر دو چیز وجود دارد. پارامتر اول به 3 و تابع فعال‌سازی به «سافت‌مَکس» (softmax) تغییر کند. Softmax یک تابع سیگموئید اعمال شده به یک متغیر مستقل با بیش از دو دسته است.

کامپایل کردن شبکه عصبی مصنوعی

«کامپایل کردن» (Compiling) اساسا اعمال «گرادیان کاهشی تصادفی» (Stochastic Gradient Descent) به کل شبکه عصبی است. اولین پارامتر، الگوریتمی است که مقرر شده از آن برای گرفتن مجموعه بهینه‌ای از وزن‌ها در شبکه عصبی استفاده شود. انواع گوناگونی از این پارامترها وجود دارند. یکی از الگوریتم‌های موثر برای این کار «آدام» (Adam) است. دومین پارامتر «تابع زیان» (Loss Function) درون الگوریتم گرادیان کاهشی تصادفی است. از آنجا که طبقه‌ها دودویی هستند، از تابع زیان binary_crossentropy استفاده می‌شود. در غیر این صورت، از categorical_crossentopy استفاده می‌شد. آرگومان نهایی معیاری است که برای ارزیابی مدل مورد استفاده قرار می‌گیرد. در این مثال از «صحت» (Accuracy) برای ارزیابی مدل استفاده می‌شود.

برازش ANN به مجموعه آموزش

X_train متغیرهای مستقلی که برای آموزش شبکه عصبی مورد استفاده قرار می‌گیرند را نشان می‌دهد و y_train بیانگر ستونی است که پیش‌بینی می‌شود. دوره‌ها (Epochs) نشانگر تعداد دفعاتی هستند که مجموعه داده کامل به شبکه عصبی مصنوعی پاس داده خواهد شد. Batch_size تعداد مشاهداتی است که بر اساس آن وزن‌ها به روز رسانی خواهند شد.

پیش‌بینی با استفاده از مجموعه آموزش

این کد، احتمال اینکه یک ادعا کلاهبردارانه باشد را نشان می‌دهد. سپس، آستانه ٪۵۰ برای دسته‌بندی یک ادعا به عنوان کلاهبرداری در نظر گرفته می‌شود. این یعنی هر ادعا با احتمال ۰.۵ یا بیشتر به عنوان کلاهبرداری در نظر گرفته می‌شود.
بدین شکل شرکت بیمه می‌تواند اولا قادر به پیگیری ادعاهایی باشد که مظنون نیستند و سپس زمان بیشتری را به ارزیابی ادعاهایی اختصاص دهد که به عنوان کلاهبرداری علامت‌گذاری شده‌اند.

بررسی ماتریس درهم‌ریختگی

«ماتریس درهم‌ریختگی» (Confusion Matrix) را می‌توان به صورت زیر تفسیر کرد. از میان 2۰۰۰ مشاهده،  1۷۵ + 1۵۵۰ مشاهده به درستی پیش‌بینی شده‌اند. در حالیکه 4۵ + 23۰ مورد اشتباه پیش‌بینی شده‌اند. می‌توان صحت را با تقسیم تعداد پیش‌بینی‌های صحیح به کل پیش‌بینی‌ها محاسبه کرد. در این مثال، 2۰۰۰/ (1۷۵ + 1۵۵۰)، است که برابر با صحت ۸۶٪ می‌شود.

انجام یک پیش‌بینی

فرض می‌شود که شرکت بیمه یک ادعا را به داده‌کاو می‌دهد. آن‌ها می‌خواهند بدانند که این ادعا کلاهبرداری است یا خیر. چطور می‌توان چنین چیزی را فهمید؟

در کد بالا، d ،c ،b ،a نمایانگر ویژگی‌هایی هستند که وجود دارد.

از آنجا که «دسته‌بند» (Classifier) انتظار آرایه‌های NumPy را به عنوان ورودی دارد، باید یک مشاهده مجرد به آرایه NumPy تبدیل شود و از «مقیاس‌گر» (Scaler) استاندارد برای مقیاس کردن آن استفاده شود.

ارزیابی شبکه عصبی مصنوعی ساخته شده

پس از آموزش دادن مدل برای یک یا دو بار، می‌توان متوجه شد که صحت‌های متفاوتی حاصل می‌شود. بنابراین نمی‌توان اطمینان داشت که کدام یک صحیح است. این موضوع، مساله «موازنه بایاس و واریانس» (Bias Variance Trade-Off) را به میان می‌آورد. اساسا، تلاش می‌شود تا مدلی آموزش داده شود که صحیح باشد و واریانس زیادی برای صحت پس از چندین بار آموزش داده شدن نداشته باشد. برای حل این مساله، از «اعتبارسنجی متقابل K-fold» با K مساوی 1۰ استفاده می‌شود. این موجب می‌شود که مجموعه آموزش روی 1۰ fold تنظیم شود. سپس، مدل روی ۹ fold آموزش داده شده و روی fold‌های باقی‌مانده تست می‌شود. از آنجا که 1۰ fold وجود دارد، تلاش می‌شود تا این کار به صورت بازگشتی از طریق 1۰ ترکیب انجام شود. هر تکرار صحتی را به دست می‌دهد. سپس میانگین همه صحت‌ها محاسبه و از آن به عنوان صحت مدل استفاده می‌شود. همچنین، واریانس نیز برای حصول اطمینان از اینکه کمینه است محاسبه می‌شود. Keras دارای یک پوشش سایکیت‌لِرن (KerasClassifier) است که کاربر را قادر می‌سازد اعتبارسنجی متقابل K-fold را در کد کِرَس قرار دهد.

سپس، تابع اعتبارسنجی متقابل K-fold از scikit_learn ایمپورت می‌شود.

KerasClassifier انتظار دارد که یکی از آرگومان‌های آن یک تابع باشد، بنابراین نیاز به ساخت آن تابع است. هدف از این تابع ساخت معماری شبکه عصبی مصنوعی است.

این تابع «دسته‌بند» (Classifier) را می‌سازد و آن را برای استفاده در گام بعدی باز می‌گرداند. تنها چیزی که باید در این وهله انجام شود «پوشش‌دهی» (Wrap) معماری ANN قبلی در تابع و بازگرداندن دسته‌بندی است. سپس، یک دسته‌بند جدید با استفاده از اعتبارسنجی متقابل K-fold ساخته و پارامتر build_fn به عنوان تابعی که در بالا ساخته شده به آن پاس داده می‌شود.

برای اعمال تابع اعتبارسنجی متقابل K-fold، از تابع cross_val_score کتابخانه scikit-learn استفاده می‌شود. برآوردگر دسته‌بندی است که با استفاده از make_classifier ساخته شد و n_jobs=-1 استفاده از همه پردازنده‌های موجود را امکان‌پذیر می‌سازد. cv تعداد fold‌ها و 1۰ یک انتخاب متداول است. cross_val_score ده صحت از ده fold تست استفاده شده در محاسبات را باز می‌گرداند.

برای به دست آوردن «تطابق نسبی» (Relative Accuracies)، میانگین صحت‌ها گرفته می‌شود.

واریانس را می‌توان به صورت زیر محاسبه کرد.

هدف داشتن واریانس کم بین صحت‌ها است.

مبارزه با بیش‌برازش

«بیش‌برازش» (Overfitting) در یادگیری ماشین، هنگامی به وقوع می‌پیوندد که مدل جزئیات و «نویز» (نوفه | Noise) موجود در مجموعه داده را می‌آموزد و در نتیجه روی مجموعه داده تست ضعیف عمل می‌کند. این اتفاق هنگامی مشاهده می‌شود که تفاوت زیادی بین صحت مجموعه تست و مجموعه آموزش وجود دارد و یا هنگامی که واریانس بالایی هنگام اعمال اعتبارسنجی متقابل K-fold موجود باشد. در شبکه‌های عصبی مصنوعی، با این مساله با استفاده از روشی که «Dropout Regularization» نام دارد مقابله می‌شود. Dropout Regularization با غیر فعال‌سازی تصادفی برخی از نورون‌ها در هر تکرار از آموزش برای جلوگیری از مستقل بودن بیش از اندازه آن‌ها نسبت به هم کار می‌کند.

در این مثال، می‌توان dropout را پس از اولین لایه خروجی و پس از دومین لایه پنهان انجام داد. استفاده از نرخ ۰.1 بدین معنا است که ٪1 از نورون‌ها در هر تکرار غیرفعال خواهند شد. پیشنهاد می‌شود که کار با نرخ ۰.1 انجام پذیرد. اگرچه، نباید هرگز بیش از ۰.4 شود، زیرا مدل دچار «کم‌برازش» (Underfitting) می‌شود.

تنظیم پارامتر

هنگامی که صحت مورد نظر به دست آمد، می‌توان پارامترها را برای گرفتن صحت بالاتر تنظیم کرد. جست‌و‌جوی Grid کاربر را قادر می‌سازد تا پارامترهای گوناگون را به منظور به دست آوردن بهترین پارامترها محاسبه کند. اولین گام در اینجا ایمپورت کردن ماژول GridSearchCV از sklearn است.

همچنین، نیاز به ویرایش تابع make_classifier به صورتی است که در ادامه آموزش داده شده. یک متغیر جدید با نام optimizer نیز ساخته می‌شود تا امکان افزودن بیش از یک بهینه‌ساز در متغیر params ایجاد شود.

همچنان از KerasClassifier استفاده می‌شود، اما اندازه دسته (batch size) و تعداد دوره‌ها (epochs) پاس داده نمی‌شوند، زیرا این‌ها پارامترهایی هستند که قرار است تنظیم شوند.

گام بعدی ساخت یک دیشکنری با پارامترهایی است که مقرر شده تنظیم شوند (در اینجا batch size، تعداد دوره‌ها و تابع بهینه‌ساز این پارامترها هستند). همچنان از adam به عنوان بهینه‌ساز استفاده می‌شود و یک بهینه‌ساز جدید با عنوان rmsprop نیز اضافه می‌شود. در مستندات Keras استفاده از rmsprop هنگام کار با «شبکه‌های عصبی بازگشتی» (Recurrent Neural Network) توصیه شده است. اگرچه می‌توان از آن برای این شبکه عصبی مصنوعی نیز استفاده کرد تا تاثیر آن بر بهبود نتایج را مورد بررسی قرار داد.

سپس، از Grid Search برای تست این پارامترها استفاده می‌شود. تابع Grid Search از برآوردگر پارامترهایی که تعریف شد، سنجه امتیازدهی و تعداد k-fold‌ها را می‌خواهد.

مانند اشیای قبلی نیاز به برازش مجموعه داده آموزش است.

می‌توان بهترین انتخاب از پارامترها را با استفاده از best_params از شی grid search گرفت. به همین ترتیب از ـbest_score برای گرفتن بهترین امتیاز استفاده می‌شود.

لازم به توجه است که این فرآیند به دلیل آنکه برای بهترین پارامترها جست‌و‌جو می‌کند، مدتی زمان می‌برد.

نتیجه‌گیری

شبکه عصبی عمیق تنها یکی از انواع شبکه‌های عصبی مصنوعی به شمار می‌آید. دیگر انواع آن عبارتند از «شبکه‌های عصبی بازگشتی» (Recurrent Neural Networks | RNN)، «شبکه‌های عصبی پیچشی» (Convolutional Neural Network | CNN) و «ماشین بولتزمن» (Boltzmann Machine). شبکه عصبی بازگشت (RNN) می‌تواند افزایش یا کاهش قیمت سهام در آینده را پیش‌بینی کند. CNN در بینایی کامپیوتری مورد استفاده قرار می‌گیرد (تشخیص سگ‌ها و گربه‌ها در یک مجموعه یا تشخیص حضور سلول‌های سرطانی در تصویرهای حاصل از تصویربرداری مغز). ماشین بولتزمن در سیستم‌های توصیه‌گر برنامه نویسی استفاده می‌شود.

اگر نوشته بالا برای شما مفید بوده، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

^^

آیا این مطلب برای شما مفید بود؟

نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

برچسب‌ها