گرادیان ها، مشتقات جزئی و قانون زنجیره ای
دو تا از آخرین قطعات پازل، قبل از ادامه کدنویسی شبکه عصبی، مفاهیم مرتبط گرادیان ها و مشتقات جزئی هستند. مشتقاتی که تاکنون حل کرده ایم مواردی بوده اند که فقط یک متغیر مستقل در تابع وجود دارد – یعنی نتیجه فقط به x بستگی دارد. با این حال ، شبکه عصبی ما به عنوان مثال از نورون ها تشکیل شده است که دارای ورودی های متعدد هستند. هر ورودی در وزن مربوطه ضرب می شود (تابعی از 2 پارامتر) ، و آنها با بایاس جمع می شوند (تابعی از پارامترهای به تعداد ورودی ها ، به علاوه یک پارامتر برای بایاس). همانطور که به زودی با جزئیات توضیح خواهیم داد، برای یادگیری تأثیر تمام ورودی ها، وزن ها و بایاس ها بر خروجی نورون و در پایان تابع از دست دادن، باید مشتق هر عملیات انجام شده در طول عبور رو به جلو در نورون و کل مدل را محاسبه کنیم. برای انجام این کار و دریافت پاسخ، باید از قانون زنجیره ای استفاده کنیم که به زودی در این فصل توضیح خواهیم داد.
مشتق جزئی
مشتق جزئی میزان تأثیر یک ورودی واحد بر خروجی یک تابع را اندازه گیری می کند. روش محاسبه مشتق جزئی مانند مشتقات توضیح داده شده در فصل قبل است. ما به سادگی باید این فرآیند را برای هر یک از ورودی های مستقل تکرار کنیم.
هر یک از ورودی های تابع بر خروجی این تابع تأثیر می گذارد، حتی اگر تأثیر 0 باشد. ما باید این تأثیرات را بدانیم. این بدان معناست که ما باید مشتق را با توجه به هر ورودی جداگانه محاسبه کنیم تا در مورد هر یک از آنها بیاموزیم. به همین دلیل است که ما این مشتقات جزئی را با توجه به ورودی داده شده می نامیم – ما بخشی از مشتق مربوط به یک ورودی مفرد را محاسبه می کنیم. مشتق جزئی یک معادله واحد است و مشتق تابع چند متغیره کامل از مجموعه ای از معادلات به نام گرادیان تشکیل شده است. به عبارت دیگر، گرادیان بردار اندازه ورودی های حاوی جواب های مشتق جزئی با توجه به هر یک از ورودی ها است. به زودی به گرادیان ها برمی گردیم.
برای نشان دادن مشتق جزئی، از نماد اویلر استفاده می کنیم. این بسیار شبیه به نماد لایبنیتس است، زیرا ما فقط باید عملگر دیفرانسیل d را با ∂ جایگزین کنیم. در حالی که عملگر d ممکن است برای نشان دادن تمایز یک تابع چند متغیره استفاده شود، معنای آن کمی متفاوت است – می تواند به معنای نرخ تغییر تابع نسبت به ورودی داده شده باشد، اما زمانی که ورودی های دیگر نیز ممکن است تغییر کنند، و بیشتر در فیزیک استفاده می شود. ما به مشتقات جزئی علاقه مند هستیم، وضعیتی که در آن سعی می کنیم تأثیر ورودی داده شده را بر خروجی بیابیم در حالی که همه ورودی های دیگر را به عنوان ثابت در نظر می گیریم. ما به تأثیر ورودی های منفرد علاقه مند هستیم زیرا هدف ما در مدل به روز رسانی پارامترها است. عملگر ∂ به صراحت به این معنی است که – مشتق جزئی:
مشتق جزئی یک مجموع
محاسبه مشتق جزئی با توجه به یک ورودی معین به معنای محاسبه آن مانند مشتق منظم یک ورودی است، درست در حالی که سایر ورودی ها را به عنوان ثابت در نظر بگیرید. مثلا:
ابتدا، ما قانون جمع را اعمال کردیم – مشتق یک مجموع مجموع مشتقات است. سپس، ما قبلا می دانیم که مشتق x نسبت به x برابر با 1 است. چیز جدید مشتق y با توجه به x است. همانطور که اشاره کردیم ، y به عنوان یک ثابت در نظر گرفته می شود ، زیرا وقتی نسبت به x مشتق می شویم تغییر نمی کند و مشتق ثابت برابر با 0 است. در حالت دوم ، ما با توجه به y به دست آوردیم ، بنابراین x را ثابت در نظر گرفتیم. به عبارت دیگر ، صرف نظر از مقدار y در این مثال ، شیب x به y بستگی ندارد. با این حال، همانطور که به زودی خواهیم دید، همیشه اینطور نخواهد بود.
بیایید مثال دیگری را امتحان کنیم:
در این مثال، ابتدا قانون مجموع را نیز اعمال کردیم، سپس ثابت ها را به خارج از مشتقات منتقل کردیم و آنچه را که با توجه به x و y باقی مانده است به صورت جداگانه محاسبه کردیم. تنها تفاوت مشتقات غیر چند متغیره فصل قبل، بخش “جزئی” است، به این معنی که ما با توجه به هر یک از متغیرها به طور جداگانه مشتق می کنیم. به غیر از آن، هیچ چیز جدیدی در اینجا وجود ندارد.
بیایید چیزی به ظاهر پیچیده تر را امتحان کنیم:
کاملا ساده – ما دائما قوانین یکسانی را بارها و بارها اعمال می کنیم، و هیچ محاسبه یا قانون جدیدی را در این مثال اضافه نکرده ایم.
مشتق جزئی ضرب
قبل از اینکه ادامه دهیم ، بیایید مشتق جزئی عملیات ضرب را معرفی کنیم:
قبلا اشاره کردیم که باید متغیرهای مستقل دیگر را به عنوان ثابت در نظر بگیریم و همچنین آموخته ایم که می توانیم ثابت ها را به خارج از مشتق منتقل کنیم. دقیقا اینگونه است که ما محاسبه مشتق جزئی ضرب را حل می کنیم – متغیرهای دیگر را به عنوان ثابت مانند اعداد در نظر می گیریم و آنها را به خارج از مشتق منتقل می کنیم. به نظر می رسد که وقتی با توجه به x استخراج می کنیم ، y به عنوان یک ثابت در نظر گرفته می شود و نتیجه برابر است با y ضرب در مشتق x نسبت به x ، که 1 است. سپس کل مشتق با y حاصل می شود. شهود پشت این مثال این است که هنگام محاسبه مشتق جزئی با توجه به x، هر تغییر x در 1 خروجی تابع را با y تغییر می دهد. به عنوان مثال، اگر y=3 و x=1، نتیجه 1·3=3 است. وقتی x را در 1 تغییر می دهیم بنابراین y=3 و x=2، نتیجه 2·3=6 است. ما x را با 1 تغییر دادیم و نتیجه با 3 تغییر کرد، با y. این چیزی است که مشتق جزئی این تابع با توجه به x به ما می گوید.
بیایید یک متغیر ورودی سوم را معرفی کنیم و ضرب متغیرها را برای مثال دیگری اضافه کنیم:
تنها عملیات جدید در اینجا، همانطور که گفته شد، متغیرهای متحرک غیر از متغیری است که ما با توجه به آن به دست می آوریم، خارج از مشتق. نتایج در این مثال پیچیده تر به نظر می رسد، اما فقط به دلیل وجود متغیرهای دیگر در آنها – متغیرهایی که در طول اشتقاق به عنوان ثابت در نظر گرفته می شوند. معادلات مشتقات طولانی تر هستند، اما لزوما پیچیده تر نیستند.
دلیل یادگیری در مورد مشتقات جزئی این است که ما به زودی مشتقات جزئی توابع چند متغیره را محاسبه خواهیم کرد که نمونه ای از آن نورون است. از دیدگاه کد و کلاس لایه متراکم، به طور خاص، متد فوروارد این کلاس، ما یک متغیر واحد را ارسال می کنیم – آرایه ورودی، که شامل دسته ای از نمونه ها یا خروجی های لایه قبلی است. از دیدگاه ریاضی، هر مقدار از این متغیر منفرد (یک آرایه) یک ورودی جداگانه است – به اندازه داده هایی که در آرایه ورودی داریم، شامل ورودی است. به عنوان مثال، اگر بردار 4 مقداری را به نورون منتقل کنیم، یک متغیر منفرد در کد است، اما 4 ورودی جداگانه در معادله دارد. این تابعی را تشکیل می دهد که چندین ورودی می گیرد. برای آشنایی با تأثیری که هر ورودی بر خروجی تابع می گذارد، باید مشتق جزئی این تابع را با توجه به هر یک از ورودی های آن محاسبه کنیم، که در فصل بعدی به طور مفصل توضیح خواهیم داد.
مشتق جزئی مکس
مشتقات و مشتقات جزئی به عملیات جمع و ضرب یا ثابت ها محدود نمی شوند. ما باید آنها را برای توابع دیگری که در پاس رو به جلو استفاده کردیم استخراج کنیم، یکی از آنها مشتق تابع () maxاست:
تابع max بیشترین ورودی را برمی گرداند. ما می دانیم که مشتق x نسبت به x برابر با 1 است ، بنابراین مشتق این تابع نسبت به x برابر با 1 است اگر x بزرگتر از y باشد ، زیرا تابع x را برمی گرداند. در حالت دیگر، جایی که y بزرگتر از x است و به جای آن برگردانده می شود، مشتق() max نسبت به x برابر با 0 است – ما y را به عنوان یک ثابت در نظر می گیریم و مشتق y با توجه به x برابر با 0 است. ما می توانیم آن را به عنوان 1(x > y) نشان دهیم، که در صورت برآورده شدن شرط به معنای 1 و 0 در غیر این صورت است. ما همچنین می توانیم مشتق جزئی() max را با توجه به y محاسبه کنیم، اما در هیچ کجای این کتاب به آن نیاز نخواهیم داشت.
یک مورد خاص برای مشتق تابع() maxزمانی است که ما فقط یک پارامتر متغیر داریم و پارامتر دیگر همیشه در 0 ثابت است. این بدان معنی است که ما هر کدام را در ازای آن بزرگتر می خواهیم – 0 یا مقدار ورودی، به طور موثر مقدار ورودی را در 0 از سمت مثبت قطع می کنیم. مدیریت این موضوع زمانی مفید خواهد بود که مشتق تابع فعال سازی ReLU را محاسبه کنیم ، زیرا آن تابع فعال سازی به صورت max(x, 0) تعریف می شود:
توجه داشته باشید که از آنجایی که این تابع یک پارامتر واحد می گیرد، ما از عملگر d به جای ∂ برای محاسبه مشتق غیر جزئی استفاده کردیم. در این حالت، مشتق 1 است وقتی x بزرگتر از 0 باشد، در غیر این صورت، 0 است.
گرادیان
همانطور که در ابتدای این فصل اشاره کردیم ، گرادیان بردار متشکل از تمام مشتقات جزئی یک تابع است که با توجه به هر متغیر ورودی محاسبه می شود.
بیایید به یکی از مشتقات جزئی عملیات جمع که قبلا محاسبه کردیم برگردیم:
اگر تمام مشتقات جزئی را محاسبه کنیم، می توانیم یک گرادیان از تابع تشکیل دهیم. با استفاده از نمادهای مختلف، به شرح زیر است:
این تمام چیزی است که ما باید در مورد گرادیان بدانیم – این بردار تمام مشتقات جزئی احتمالی تابع است، و ما آن را با استفاده از ∇ نشان می دهیم – نماد نابلا که شبیه یک نماد دلتای معکوس است.
ما از مشتقات توابع تک پارامتری و گرادیان های توابع چند متغیره برای انجام نزول گرادیان با استفاده از قانون زنجیره یا به عبارت دیگر، برای انجام پاس به عقب که بخشی از آموزش مدل است، استفاده خواهیم کرد. اینکه دقیقا چگونه این کار را انجام خواهیم داد، موضوع فصل بعدی است.
قانون زنجیره ای
در طول عبور رو به جلو، ما داده ها را از طریق نورون ها منتقل می کنیم، سپس از طریق تابع فعال سازی، سپس از طریق نورون ها در لایه بعدی، سپس از طریق یک تابع فعال سازی دیگر و غیره. ما یک تابع را با یک پارامتر ورودی فراخوانی می کنیم، یک خروجی می گیریم و از آن خروجی به عنوان ورودی به تابع دیگر استفاده می کنیم. برای این مثال ساده ، بیایید 2 تابع را در نظر بگیریم: f و g:
x داده های ورودی است، z خروجی تابع f است، اما همچنین یک ورودی برای تابع g و y خروجی تابع g است. ما می توانیم همان محاسبه را به شرح زیر بنویسیم:
در این فرم، ما از متغیر z میانی استفاده نمی کنیم، که نشان می دهد تابع g خروجی تابع f را مستقیما به عنوان ورودی می گیرد. این تفاوت چندانی با 2 معادله فوق ندارد اما ویژگی مهمی از توابع زنجیره ای شده به این روش را نشان می دهد – از آنجایی که x ورودی تابع f است و سپس خروجی تابع f ورودی تابع g است، خروجی تابع g به نوعی تحت تأثیر x قرار می گیرد. بنابراین باید مشتقی وجود داشته باشد که بتواند ما را از این تأثیر آگاه کند.
عبور رو به جلو از مدل ما زنجیره ای از توابع مشابه این مثال ها است. ما در حال عبور نمونه ها هستیم، داده ها از طریق تمام لایه ها جریان می یابند و توابع فعال سازی برای تشکیل یک خروجی انجام می شود. بیایید معادله و کد مدل نمونه را از فصل 1 بیاوریم:
شکل 8.01: کدی برای عبور رو به جلو از یک مدل شبکه عصبی نمونه.
اگر به دقت نگاه کنید، خواهید دید که ما از دست دادن را به عنوان یک تابع بزرگ یا زنجیره ای از توابع از ورودی های متعدد – داده های ورودی، وزن ها و تعصبات ارائه می دهیم. ما داده های ورودی را به لایه اول منتقل می کنیم که در آن وزن ها و بایاس های آن لایه را نیز داریم، سپس خروجی ها از طریق تابع فعال سازی ReLU جریان می یابند، و لایه دیگری، که وزن ها و بایاس های بیشتری را به ارمغان می آورد، و یک فعال سازی ReLU دیگر، تا انتها – لایه خروجی و فعال سازی softmax. خروجی مدل، همراه با تارگت ها، به تابع ضرر منتقل می شود که خطای مدل را برمی گرداند. ما می توانیم به تابع ضرر نه تنها به عنوان تابعی نگاه کنیم که خروجی و اهداف مدل را به عنوان پارامترهایی برای تولید خطا می گیرد، بلکه به عنوان تابعی که اهداف، نمونه ها و همه وزن ها و بایاس ها را به عنوان ورودی می گیرد، اگر همه توابع انجام شده در طول پاس رو به جلو را همانطور که در تصاویر نشان داده ایم، زنجیر کنیم. برای بهبود فقدان، باید یاد بگیریم که چگونه هر وزن و سوگیری بر آن تأثیر می گذارد. چگونه این کار را برای زنجیره ای از توابع انجام دهیم؟ با استفاده از قانون زنجیره ای. این قانون می گوید که مشتق یک زنجیره تابع محصول مشتقات تمام توابع این زنجیره است ، به عنوان مثال:
ابتدا مشتق تابع بیرونی، f(g(x)) را با توجه به تابع داخلی، g(x) نوشتیم، زیرا این تابع درونی پارامتر آن است. در مرحله بعد ، ما آن را در مشتق تابع داخلی ، g (x) ، با توجه به پارامترهای آن ، x ضرب کردیم. ما همچنین این مشتق را با استفاده از 2 نماد مختلف نشان دادیم. با 3 تابع و ورودی های متعدد ، مشتق جزئی این تابع با توجه به x به شرح زیر است (در این مورد نمی توانیم از نماد اول استفاده کنیم زیرا باید ذکر کنیم که کدام متغیر را با توجه به آن به دست می آوریم):
برای محاسبه مشتق جزئی زنجیره ای از توابع با توجه به برخی پارامترها، مشتق جزئی تابع بیرونی را با توجه به تابع داخلی در یک زنجیره به پارامتر می گیریم. سپس این مشتق جزئی را در مشتق جزئی تابع داخلی با توجه به تابع درونی تر در یک زنجیره به پارامتر ضرب کنید، سپس آن را در مشتق جزئی تابع درونی تر نسبت به تابع دیگر در زنجیره ضرب کنید. ما این را تا پارامتر مورد نظر تکرار می کنیم. به عنوان مثال، توجه کنید که مشتق میانی نسبت به h(x, z) چگونه است و نه y زیرا h(x, z) در زنجیره به پارامتر x است. به نظر می رسد که قانون زنجیره مهمترین قانون در یافتن تأثیر ورودی منفرد بر خروجی زنجیره ای از توابع است که محاسبه ضرر در مورد ما است. ما در فصل بعدی دوباره از آن استفاده خواهیم کرد، زمانی که در مورد پس انتشار کدنویسی می کنیم. در حال حاضر، بیایید مثالی از قانون زنجیره را پوشش دهیم.
بیایید مشتق از h(x) = 3(2x2)5.
اولین چیزی که در اینجا می توانیم متوجه شویم این است که ما یک تابع پیچیده داریم که می توان آن را به دو تابع ساده تر تقسیم کرد. اول یک قسمت معادله موجود در داخل پرانتز است که می توانیم آن را به صورت g(x) = 2x2.
این تابع داخلی است که ما آن را نمایی می کنیم و با بقیه معادله ضرب می کنیم. سپس قسمت باقیمانده معادله را می توان به صورت نوشت f(y) = 3(y)5. y
در این مورد همان چیزی است که ما به عنوان g(x)=2x2
و وقتی آن را دوباره ترکیب می کنیم، به دست می آوریم h(x) = f(g(x)) = 3(2x2)5 .
برای محاسبه مشتق این تابع ، ما با گرفتن توان خارجی ، 5 شروع می کنیم و آن را در مقابل مؤلفه ای که نمایی می کنیم قرار می دهیم تا بعدا آن را در 3 پیشرو ضرب کنیم ، به ما 15 می دهیم. سپس 1 را از توان 5 کم می کنیم و 4 برای ما باقی می ماند.
سپس قانون زنجیره به ما اطلاع می دهد که مشتق فوق تابع بیرونی را با مشتق تابع داخلی ضرب کنیم و به ما بدهیم:
به یاد بیاورید که 4x مشتق 2×2 بود که تابع داخلی g(x) است. این مفهوم قانون زنجیره ای را در یک مثال برجسته می کند و به ما امکان می دهد مشتقات توابع پیچیده تر را با زنجیر کردن مشتقات به هم محاسبه کنیم. توجه داشته باشید که ما در مشتق آن تابع داخلی ضرب کردیم، اما تابع داخلی را بدون تغییر در مشتق تابع بیرونی باقی گذاشتیم.
در تئوری، ما فقط می توانیم در اینجا با یک مشتق کاملا قابل استفاده از تابع متوقف شویم. ما می توانیم برخی از ورودی ها را وارد کنیم 15(2x2)4 · 4x
و پاسخ را دریافت کنید. با این حال، ما همچنین می توانیم ادامه دهیم و این عملکرد را برای تمرین بیشتر ساده کنیم. برگردیم به مشکل اصلی، تا کنون متوجه شده ایم:
برای ساده سازی این تابع مشتق شده، ابتدا (2x2)4
و 4 توان را توزیع کنید:
ترکیب x’s:
و ثابت ها:
ما مشتقات را بعدا برای محاسبات سریعتر نیز ساده خواهیم کرد – هیچ دلیلی برای تکرار همان عملیات وجود ندارد زمانی که بتوانیم آنها را از قبل حل کنیم.
امیدواریم اکنون متوجه شده باشید که مشتقات و مشتقات جزئی چیست، گرادیان چیست، مشتق تابع ضرر با توجه به وزن ها و تعصبات به چه معناست و چگونه از قانون زنجیره استفاده کنید. در حال حاضر، این اصطلاحات ممکن است جدا به نظر برسند، اما ما می خواهیم از همه آنها برای انجام نزول گرادیان در مرحله پس انتشار استفاده کنیم، که موضوع فصل های بعدی است.
خلاصه
بیایید قوانینی را که در این فصل آموخته ایم خلاصه کنیم.
مشتق جزئی مجموع با توجه به هر ورودی برابر با 1 است:
مشتق جزئی عملیات ضرب با 2 ورودی، نسبت به هر ورودی، برابر با ورودی دیگر است:
مشتق جزئی تابع حداکثر 2 متغیر نسبت به هر یک از آنها اگر این متغیر بزرگترین باشد 1 و 0 در غیر این صورت است. نمونه ای از x:
مشتق حداکثر تابع یک متغیر منفرد و 0 برابر با 1 است اگر متغیر بزرگتر از 0 و 0 باشد در غیر این صورت:
مشتق توابع زنجیره ای برابر با حاصل ضرب مشتقات جزئی توابع بعدی است:
همین امر در مورد مشتقات جزئی نیز صدق می کند. مثلا:
گرادیان بردار تمام مشتقات جزئی ممکن است. نمونه ای از تابع ورودی سه گانه:
مواد تکمیلی: https://nnfs.io/ch8
کد فصل، منابع بیشتر و اشتباهات این فصل.
فصل 9-پس انتشار