دریابید که چرا پس انتشار و نزول گرادیان کلید پیش بینی در یادگیری ماشین هستند، سپس با آموزش یک شبکه عصبی ساده با استفاده از گرادیان نزول و کد جاوا شروع کنید.
امروزه بیشتر هوش مصنوعی با استفاده از نوعی شبکه عصبی پیاده سازی می شود. در دو مقاله آخرم، شبکه های عصبی را معرفی کردم و به شما نشان دادم چگونه یک شبکه عصبی در جاوا بسازید. قدرت یک شبکه عصبی تا حد زیادی از ظرفیت آن برای یادگیری عمیق ناشی می شود و این ظرفیت بر اساس مفهوم و اجرای پس انتشار با نزول گرادیان ساخته شده است. من این سری کوتاه از مقالات را با یک فرو رفتن سریع در پس انتشار و نزول گرادیان در جاوا به پایان خواهم رساند.
انتشار پسانداز در یادگیری ماشین
گفته شده است که هوش مصنوعی آنقدرها هم هوشمند نیست، که عمدتاً فقط انتشار پسانداز است. بنابراین، این سنگ بنای یادگیری ماشین مدرن چیست؟
برای درک پس انتشار، ابتدا باید نحوه عملکرد یک شبکه عصبی را درک کنید. اساساً، یک شبکه عصبی یک گراف جهت دار از گره ها به نام نورون ها است. نورونها ساختار خاصی دارند که ورودیها را میگیرد، آنها را با وزنها ضرب میکند، یک مقدار بایاس اضافه میکند و همه اینها را از طریق یک تابع فعالسازی اجرا میکند. نورون ها خروجی خود را به نورون های دیگر تغذیه می کنند تا زمانی که به نورون های خروجی برسند. نورون های خروجی خروجی شبکه را تولید می کنند. (برای معرفی کاملتر به سبکهای یادگیری ماشین: مقدمهای بر شبکههای عصبی مراجعه کنید.)
من از اینجا فرض میکنم که متوجه میشوید که چگونه یک شبکه و نورونهای آن، از جمله پیشخور، ساختار یافتهاند. مثال و بحث بر روی پس انتشار با نزول گرادیان متمرکز خواهد بود. شبکه عصبی ما دارای یک گره خروجی، دو گره پنهان و دو گره ورودی خواهد بود. استفاده از یک مثال نسبتا ساده، دیدن ریاضیات مرتبط با الگوریتم را آسان تر می کند. شکل ۱ نموداری از نمونه شبکه عصبی را نشان می دهد.
شکل ۱. نموداری از شبکه عصبی که برای مثال خود استفاده خواهیم کرد.
ایده در پس انتشار با نزول گرادیان این است که کل شبکه را به عنوان یک تابع چند متغیره در نظر بگیریم که ورودی یک تابع از دست دادن را فراهم می کند. تابع ضرر با مقایسه خروجی شبکه با نتایج خوب شناخته شده، عددی را محاسبه می کند که نشان می دهد شبکه چقدر خوب عمل می کند. مجموعه داده های ورودی جفت شده با نتایج خوب به عنوان مجموعه آموزشی شناخته می شود. تابع ضرر برای افزایش مقدار عدد طراحی شده است، زیرا رفتار شبکه از صحیح فاصله می گیرد.
الگوریتمهای نزولی گرادیان تابع ضرر را میگیرند و از مشتقات جزئی برای تعیین اینکه هر متغیر (وزنها و بایاسها) در شبکه چه کمکی به مقدار ضرر کرده است استفاده میکنند. سپس به عقب حرکت می کند، از هر متغیر بازدید می کند و آن را برای کاهش مقدار ضرر تنظیم می کند.
حساب نزول گرادیان
درک نزول گرادیان شامل چند مفهوم از حساب دیفرانسیل و انتگرال است. اولین مورد، مفهوم مشتق است. MathsIsFun.com معرفی عالی برای مشتقات دارد. به طور خلاصه، یک مشتق شیب (یا نرخ تغییر) یک تابع در یک نقطه را به شما می دهد. به عبارت دیگر، مشتق یک تابع نرخ تغییر را در ورودی داده شده به ما می دهد. (زیبایی حساب دیفرانسیل و انتگرال در این است که به ما امکان می دهد تغییر را بدون نقطه مرجع دیگری پیدا کنیم – یا بهتر است بگوییم، به ما امکان می دهد یک تغییر بی نهایت کوچک را در ورودی فرض کنیم.)
مفهوم مهم بعدی مشتق جزئی است. یک مشتق جزئی به ما امکان میدهد یک تابع چند بعدی (که به عنوان چند متغیر نیز شناخته میشود) بگیریم و فقط یکی از متغیرها را برای یافتن شیب بعد معین جدا کنیم.
مشتقات به این سوال پاسخ می دهند: نرخ تغییر (یا شیب) یک تابع در یک نقطه خاص چقدر است؟ مشتقات جزئی به این سوال پاسخ می دهند: با توجه به متغیرهای ورودی چندگانه به معادله، نرخ تغییر فقط برای این یک متغیر چقدر است؟
نزول گرادیان از این ایدهها برای بازدید از هر متغیر در یک معادله و تنظیم آن برای به حداقل رساندن خروجی معادله استفاده میکند. این دقیقاً همان چیزی است که ما در آموزش شبکه خود می خواهیم. اگر تابع ضرر را در نمودار ترسیم کنیم، میخواهیم با افزایش به سمت حداقل یک تابع حرکت کنیم. یعنی ما می خواهیم حداقل جهانی را پیدا کنیم.
توجه داشته باشید که اندازه یک افزایش به عنوان “نرخ یادگیری” در یادگیری ماشین شناخته می شود.
نزول گرادیان در کد
ما در حین بررسی ریاضیات پس انتشار با نزول گرادیان، به کد نزدیک میشویم. وقتی ریاضیات خیلی انتزاعی می شود، نگاه کردن به کد به ما کمک می کند تا در زمین باقی بمانیم. بیایید با نگاه کردن به کلاس Neuron
خود، نشان داده شده در فهرست ۱ شروع کنیم.
class Neuron {
Random random = new Random();
private Double bias = random.nextGaussian();
private Double weight1 = random.nextGaussian();
private Double weight2 = random.nextGaussian();
public double compute(double input1, double input2){
return Util.sigmoid(this.getSum(input1, input2));
}
public Double getWeight1() { return this.weight1; }
public Double getWeight2() { return this.weight2; }
public Double getSum(double input1, double input2){ return (this.weight1 * input1) + (this.weight2 * input2) + this.bias; }
public Double getDerivedOutput(double input1, double input2){ return Util.sigmoidDeriv(this.getSum(input1, input2)); }
public void adjust(Double w1, Double w2, Double b){
this.weight1 -= w1; this.weight2 -= w2; this.bias -= b;
}
}
کلاس Neuron
فقط سه عضو دو
دارد: weight1
، weight2
و bias< /code>. چند روش هم دارد. روش مورد استفاده برای فید فوروارد
compute()
است. دو ورودی را می پذیرد و کار نورون را انجام می دهد: هر کدام را در وزن مناسب ضرب کنید، بایاس را اضافه کنید و آن را از طریق یک تابع سیگموئید اجرا کنید.
قبل از اینکه به جلو برویم، بیایید مفهوم فعالسازی سیگموئید را که در معرفی شبکههای عصبی نیز مورد بحث قرار دادم، مرور کنیم. فهرست ۲ یک تابع فعال سازی سیگموئید مبتنی بر جاوا را نشان می دهد.
public static double sigmoid(double in){
return 1 / (1 + Math.exp(-in));
}
تابع سیگموئید ورودی را می گیرد و شماره اویلر را افزایش می دهد (Math.exp) به منفی آن، ۱ را اضافه کرده و آن را بر ۱ تقسیم کنید. اثر این است که خروجی بین ۰ و ۱ فشرده می شود و اعداد بزرگتر و کوچکتر به طور مجانبی به مرزها نزدیک می شوند.
یک تابع سیگموئید چیست؟
DeepAI.org یک معرفی خوبی برای تابع سیگموئید دارد در یادگیری ماشین.
با بازگشت به کلاس Neuron
در فهرست ۱، فراتر از روش compute()
، getSum()
و getDerivedOutput( )
. getSum()
فقط محاسبه weights * inputs + bias را انجام می دهد. توجه داشته باشید که compute()
getSum()
را می گیرد و آن را از طریق sigmoid()
اجرا می کند. روش getDerivedOutput()
getSum()
را از طریق یک تابع دیگر اجرا می کند: مشتق تابع سیگموئید.
مشتق در عمل
اکنون به فهرست ۳ نگاهی بیندازید، که یک تابع مشتق سیگموئید را در جاوا نشان می دهد. ما به صورت مفهومی در مورد مشتقات صحبت کرده ایم، در اینجا یکی در عمل است.
public static double sigmoidDeriv(double in){
double sigmoid = Util.sigmoid(in);
return sigmoid * (1 - sigmoid);
}
به خاطر داشته باشید که یک مشتق به ما میگوید تغییر یک تابع برای یک نقطه در نمودار آن چقدر است، میتوانیم احساس کنیم که این مشتق چه میگوید: میزان تغییر تابع سیگموید را به من بگویید ورودی داده شده. می توانید بگویید که به ما می گوید که نورون از قبل فعال شده از فهرست ۱ چه تأثیری بر نتیجه نهایی و فعال شده دارد.
قوانین مشتق
شاید تعجب کنید که چگونه میدانیم تابع مشتق سیگموئید در فهرست ۳ صحیح است. پاسخ این است که اگر تابع مشتق شده توسط دیگران تأیید شده باشد، درست است و اگر بدانیم توابع به درستی متمایز شده دقیق هستند بر اساس قوانین خاص. ما مجبور نیستیم به اصول اولیه برگردیم و این قواعد را پس از فهمیدن آنچه میگویند و به درستی آنها اعتماد کنیم، دوباره کشف کنیم—مثل اینکه قوانین را برای سادهسازی معادلات جبری میپذیریم و اعمال میکنیم.
بنابراین، در عمل، با پیروی از قوانین مشتق مشتقات را پیدا می کنیم. اگر به تابع سیگموئید و مشتق آن نگاه کنید، خواهید دید که با پیروی از این قوانین می توان به تابع سیگموئید دست یافت. برای اهداف شیب نزولی، باید قوانین مشتق را بدانیم، به کارکرد آنها اعتماد کنیم و نحوه اعمال آنها را درک کنیم. ما از آنها برای یافتن نقشی که هر یک از وزن ها و سوگیری ها در نتیجه ضرر نهایی شبکه ایفا می کند استفاده خواهیم کرد.
نشانگذاری
نشان f اول f'(x) یکی از راههای گفتن "مشتق f از x" است. دیگری این است:
این دو معادل هستند:
نماد دیگری که به زودی خواهید دید نماد مشتق جزئی است:
این می گوید، مشتق f را برای متغیر x به من بدهید.
قانون زنجیره
کنجکاوترین قواعد مشتق قانون زنجیره ای است. می گوید که وقتی یک تابع مرکب است (یک تابع در یک تابع، با نام مستعار یک تابع مرتبه بالاتر) می توانید آن را به این صورت گسترش دهید:
ما از قانون زنجیره برای بازگشایی شبکه خود و دریافت مشتقات جزئی برای هر وزن و بایاس استفاده خواهیم کرد.
پست های مرتبط
نزول گرادیان در جاوا
نزول گرادیان در جاوا
نزول گرادیان در جاوا