یادگیری خودگام برای یادگیری ماشین

شما شبکه عصبی خود را با وارد کردن بی‌رحمانه داده‌ها به آن شکنجه می‌دهید! معمولا، هنگامی که یک مدل یادگیری ماشین با کاهش تلفات تصادفی (SGD) آموزش داده می‌شود، مجموعه داده‌های آموزشی به هم ریخته می‌شوند. به این ترتیب، ما اطمینان حاصل می‌کنیم که مدل نقاط داده مختلف را بدون هیچ نظم خاصی می‌بیند و می‌تواند کار را به طور مساوی بدون گرفتار شدن در بهینه‌سازی محلی یاد بگیرد. با این حال، در سال ۲۰۰۹، بنجیو و همکاران نشان داد که یک مرتب‌سازی خاص مفید است. آن‌ها رویکرد خود را یادگیری برنامه آموزشی نامیدند و نشان دادند که یک مدل یادگیری ماشین اگر داده‌های آموزشی آن در یک ترتیب خاص باشد، به دقت بالاتری می‌رسد. به طور دقیق‌تر، نمونه‌های آسان‌تر در ابتدا و نمونه‌های سخت‌تر در آخر. آن‌ها برای آزمایش‌های خود از یک مدل از قبل آموزش‌دیده استفاده کردند و اجازه دادند که آن مدل تصمیم بگیرد که کدام نقاط داده آسان یا سخت هستند. سپس یک مدل جدید بر روی مجموعه داده‌های درست مرتب شده آموزش داده شد و نسبت به مدل‌هایی که براساس ترتیب تصادفی یا برنامه‌درسی مخالف آموزش داده شده‌بودند، به دقت بالاتری همگرا شد.


من در حین کار بر روی پروژه فعلی خود، با تکنیکی به نام یادگیری خود گام (SPL: Self-Peaced Learning) مواجه شدم. این ایده جدیدی نیست و مقاله مربوطه حدود ۱۰ سال پیش منتشر شد. به هر حال، این تکنیک کاملا جالب و مهم است چون به کاهش شدید تصادفی (SGD) برای هم‌گرایی سریع‌تر و حتی با دقت بالاتر کمک می‌کند. از نقاط داده‌ای خاصی که بسیار سخت در نظر گرفته می‌شوند، استفاده می‌کند. این سیستم براساس یادگیری برنامه آموزشی است اما داده‌ها را به هنگام آموزش دسته‌بندی می‌کند. نیازی به یک مدل از پیش آموزش‌دیده اضافی وجود ندارد که در مورد ترتیب تصمیم‌گیری کند. از این رو نام یادگیری خود - گام به آن داده شده.

شهود پشت SPL

واژه یادگیری خودگام از تکنیک یادگیری به کار رفته توسط انسان نشات می‌گیرد. این به شما این امکان را می‌دهد که سرعت خود را متناسب با الگوهای یادگیری خود تعریف کنید. SPL می‌تواند به عنوان مطالعه و یا آموزش یک مهارت ویژه به عنوان مثال ریاضی دیده شود. زمانی که یادگیری ریاضیات را شروع کردیم، شمارش را شروع کردیم، سپس جمع، تفریق و غیره را ادامه دادیم. ما در مورد ضرب ماتریس یا مشتقات تا یک سن مشخص چیزی نشنیدیم. به همین ترتیب، SPL برای یادگیری ماشین با نمونه‌های بسیار آسان شروع می‌شود و، زمانی که یاد گرفته شد، با نمونه‌های سخت‌تر که از «اصول اولیه» آموخته‌شده، ادامه می‌یابد. من SPL را به عنوان نوعی محدود کردن یک کار در طول زمان تصور می‌کنم. یک کار طبقه‌بندی ساده در یک فضای دو بعدی و یک مدل را در نظر بگیرید که باید دو ابر نقطه‌ای را در نقطه درست تقسیم کند. نمونه‌های آسان‌تر از منطقه متقاطع بسیار دور هستند. نمونه‌های سخت‌تر به منطقه متقاطع نزدیک هستند. حالت اولیه مدل یک خط در جایی در این فضا است. اگر ما تنها با نقاط داده آسان شروع کنیم، مدل گرادیان می‌گیرد که به آن می‌گوید در یک جهت خاص حرکت کند. اگر ما کار را تنها با نقاط سخت شروع کنیم، مدل ما می‌داند که اشتباه است و مسیری برای رفتن به آن پیدا می‌کند اما ممکن است دوباره به سمت دیگر برود. کم کردن نقاط به سمت صحیح به مدل کمک می‌کند تا از پرش بیش از حد اجتناب کرده و به نرمی همگرا شود، همانطور که در انیمیشن که در زیر ایجاد کردم دیده می‌شود.

یادگیری خود گام بر روی یک مجموعه داده ساده
یادگیری خود گام بر روی یک مجموعه داده ساده

الگوریتم

حقه خیلی ساده است. از آستانه ای استفاده می‌کند که ما آن را لامبدا می‌نامیم. برای مقایسه با مقادیر از دست دادن نقاط داده در مجموعه آموزشی وجود دارد. معمولا، لامبدا با عددی نزدیک به صفر خیلی کم شروع می‌کند. با هر اپوک، لامبدای در یک عامل ثابت بزرگ‌تر از ۱ ضرب می‌شود. مدلی که در حال آموزش است باید مقادیر اتلاف نقاط آموزشی خود را برای انجام SGD محاسبه کند. به طور کلی، این مقادیر زیان با تکرار آموزش بیشتر، کوچک‌تر می‌شوند زیرا مدل در وظایف آموزشی بهتر می‌شود و اشتباهات کمتری ایجاد می‌کند. آستانه لامبدا در حال حاضر تعیین می‌کند که آیا نقطه داده آسان است یا سخت. هر زمان که از دست دادن یک نقطه داده زیر لامبدا باشد، یک نقطه داده آسان است. اگر بالا باشد، سخت در نظر گرفته می‌شود. در طول آموزش، مرحله پس انتشار تنها روی نقاط داده آسان انجام می‌شود و نقاط داده سخت نادیده گرفته می‌شوند.از این رو، این مدل دشواری نمونه‌های آموزشی را در طول آموزش، هر زمان که به اندازه کافی پیشرفت کرده باشد، افزایش می‌دهد. قطعا، در ابتدا، مدل ممکن است هیچ نقطه داده‌ای را آسان در نظر نگیرد و اصلا آموزش داده نشود. بنابراین، نویسندگان SPL یک فاز گرم کردن را معرفی کردند که در آن هیچ پرش مجاز نیست و تنها یک زیرمجموعه کوچک از مجموعه آموزش استفاده می‌شود.

ریاضیات

مقاله SPL یک رویکرد یادگیری دو مرحله‌ای را معرفی می‌کند. در اینجا تابع زیان دو بار آموزش داده می‌شود تا برخی متغیرها برای هر مرحله ثابت نگه‌داشته شوند. تابع تلفات باید با توجه به وزن مدل w و متغیرهای v به حداقل برسد. در تابع زیان، ما چندین عبارت را می‌بینیم.

عبارت اول (r(w یک عبارت منظم کننده معمول است که به مدل کمک می‌کند از بیش برازش اجتناب کند. همچنین بخشی از دیگر توابع زیان است که به SPL مرتبط نیست. عبارت دوم مجموع تلفات نقطه داده (f(x،y،w مدل ما ضرب شده در متغیر v است. این متغیر "v" بعدا در مورد اینکه آیا نقطه داده فعلی "(x، y)" به اندازه کافی برای آموزش آسان است یا خیر تصمیم‌گیری خواهد کرد. عبارت سوم، مجموع تمام ضرب v در آستانه "لامبدا" است که قبلا در بخش‌های قبلی ذکر کردیم. متغیر‌های “v” عددی هستند و تنها می‌توانند “0” یا “1” باشند. در مرحله اول یادگیری، متغیرهای «w» ثابت هستند و تنها متغیرهای «v» با توجه به بهینه‌سازی تغییر می‌کنند. اگر به دقت به تابع زیان نگاه کنید، می‌بینیم که در واقع "لامبدا" به عنوان یک آستانه عمل می‌کند. اگر "(f (x، y، w" کوچک‌تر از لامبدا باشد و "v" یکی باشد، ما چیزی را از نرم کردن کم می‌کنیم. اگر "(f(x، y، w" بزرگ‌تر از لامبدا و "v = 1" باشد، " (f (x، y، w لامبدا مثبت خواهد بود و ما چیزی اضافه خواهیم کرد. بنابراین، با "v = 0"، ما هیچ چیزی اضافه نمی‌کنیم، که کوچک‌تر از اضافه کردن چیزی است. به طور خلاصه، هر زمان که "(f(x، y، w" کوچک‌تر از "لامبدا" باشد، اولین گام با تنظیم "v" به "۱" و در غیر این صورت به "۰" بهینه‌سازی می‌شود. مرحله دوم "v" محاسبه‌شده را اصلاح می‌کند و "w" را بهینه می‌کند. اگر "v"برابر "۱" باشد، به عنوان مثال نوسازی مدل بازگشتی‌خطا انجام می‌شود. اگر "v" برابر با "0" باشد، گرادیان‌های f(x،y، w)" نیز "0" خواهد بود و هیچ به روز رسانی ای انجام نخواهد شد (به جز برای عبارت تنظیم‌کننده اما شما می‌توانید این را برای درک بهتر نادیده بگیرید). تنظیم آستانه به یک عدد بسیار پایین، در ابتدا، به هیچ چیزی منجر نخواهد شد چون همه "v ها "0" خواهند بود چون هیچ افت نقطه داده‌ای زیر آستانه نخواهد. بنابراین، نویسندگان SPL پیشنهاد دادند که یک فاز گرم کردن بدون SPL برای تعداد معینی از تکرارها داشته باشند و سپس با SPL شروع شوند.

پیاده‌سازی با پای‌تورچ

در مثال کد زیر، من نشان می‌دهم که چگونه SPL را با پای‌تورچ روی مجموعه داده ساختگی اجرا کردم. به طور خاص، ما آموزش انیمیشنی که من در ابتدای این پست وبلاگ نشان داده‌ام را اجرا خواهیم کرد. در ابتدا، ما یک مدل بسیار ساده را با در نظر گرفتن ۲ ویژگی و خروجی بیش از دو عدد تعریف می‌کنیم که احتمال هر کلاس را تعریف می‌کنند. خروجی به ما می‌گوید که مدل فکر می‌کند چه کلاسی را می‌بیند. برای تبدیل خروجی در احتمالات، از یک تابع نیم بیشینه استفاده می‌کنیم. با این حال، در این کد، من از تابع log_softmax استفاده می‌کنم. این به خاطر تابع تلفاتی است که من بعدا از آن استفاده خواهم کرد. در پایان، مدل به همان روش آموزش داده می‌شود.

import torch
import torch.nn as nn

class Model(nn.Module):
    def __init__(self, input_size, output_size):
        super(Model, self).__init__()
        self.input_layer = nn.Linear(input_size, output_size)

    def forward(self, x):
        x = self.input_layer(x)
        return torch.log_softmax(x, dim=1)


کد تابع تلفات را می توان در بخش بعدی مشاهده کرد. در اینجا، ما اتلاف هر نقطه را محاسبه می‌کنیم، که همان تلفات NLL است. اگر زیان کوچک‌تر از آستانه باشد، زیان را با یک ضرب می‌کنیم، در غیر این صورت با صفر. بنابراین، تلفات ضرب صفر هیچ تاثیری بر آموزش ندارد.

import torch
from torch import Tensor
import torch.nn as nn

class SPLLoss(nn.NLLLoss):
    def __init__(self, *args, n_samples=0, **kwargs):
        super(SPLLoss, self).__init__(*args, **kwargs)
        self.threshold = 0.1
        self.growing_factor = 1.3
        self.v = torch.zeros(n_samples).int()

    def forward(self, input: Tensor, target: Tensor, index: Tensor) -> Tensor:
        super_loss = nn.functional.nll_loss(input, target, reduction=&quotnone&quot)
        v = self.spl_loss(super_loss)
        self.v[index] = v
        return (super_loss * v).mean()

    def increase_threshold(self):
        self.threshold *= self.growing_factor

    def spl_loss(self, super_loss):
        v = super_loss < self.threshold
        return v.int()

عملکرد آموزشی، در نهایت، مانند همیشه به نظر می‌رسد. ما یک بارگذار داده را بارگذاری می‌کنیم، مدل و بهینه‌ساز را راه‌اندازی می‌کنیم، و شروع به تکرار روی مجموعه داده چند دوره‌ای می‌کنیم. برای سادگی، من تابع ترسیم نمودار را برای انیمیشن کنار گذاشتم.

import torch.optim as optim

from model import Model
from dataset import get_dataloader
from loss import SPLLoss

def train():
    model = Model(2, 2, 2, 0)
    dataloader = get_dataloader()
    criterion = SPLLoss(n_samples=len(dataloader.dataset))
    optimizer = optim.Adam(model.parameters())

    for epoch in range(10):
        for index, data, target in dataloader:
            optimizer.zero_grad()
            output = model(data)
            loss = criterion(output, target, index)
            loss.backward()
            optimizer.step()
        criterion.increase_threshold()
    return model

کل پروژه را می توان در مخزن گیت‌هاب من یافت. آزادید که با آن بازی کنید. همچنین تابع ترسیم نمودار را می توان در آنجا یافت.

تشخیص ناهنجاری

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

برای این آزمایش، من از کد مذکور استفاده کردم و تعداد ثابتی از دوره‌ها را اجرا نکردم. در عوض، من تمرین را تا زمانی اجرا کردم که بیش از ۵ نقطه داده بالای آستانه وجود داشته باشد و در نتیجه سخت در نظر گرفته شود. زمانی‌که، من ۵ یا کم‌تر نقطه دارم، آموزش را متوقف می‌کنم و آن‌ها را به عنوان نقاط قرمز طرح می‌کنم. همانطور که می‌توانید در انیمیشن زیر ببینید، الگوریتم یک ناهنجاری را در قسمت پایین سمت چپ ابر آبی یافت. من این ناهنجاری را با بردن دورترین نقطه از مرکز جرم نارنجی و تغییر کلاس آن به «نارنجی» اضافه کردم

عدم تعادل به صورت نقاط قرمز در انتها
عدم تعادل به صورت نقاط قرمز در انتها


قطعا، این مثال سخت نیست، اما نشان می‌دهد که تشخیص ناهنجاری با مشکل مواجه است. اگر ابعاد بیش از ۲ یا ۳ وجود داشته باشد، این کار ناهنجاری‌های پیچیده‌تر و بدیهی‌تری را به دست می‌آورد، همانطور که در مثال ما به این آسانی پیدا نشده است.

نتیجه‌گیری

چرا همه از SPL استفاده نمی‌کنند؟ پیدا کردن مقادیر فاکتور شروع و رشد مناسب برای آستانه زمان می‌برد زیرا این چیز عمومی نیست و براساس مدل‌ها، توابع زیان و مجموعه داده‌ها تغییر می‌کند. برای مثال‌هایی که در این مقاله استفاده کردم، باید چندین بار سعی می‌کردم تا در نهایت پیکر بندی‌های مناسب را پیدا کنم. تصور کنید که یک مجموعه داده بسیار بزرگ و همچنین یک مدل بسیار بزرگ دارید. اساسا چک کردن کل پیشرفت چندین بار قبل از شروع آموزش واقعی غیر عملی است. با این حال، چندین تکنیک دیگر برای یادگیری وجود دارد که با تنظیمات آموزشی مختلف متناسب است. با وجود این نکات، ایده فعلی یک ایده بسیار شهودی بوده‌است که درک آن آسان و کار کردن با آن سرگرم‌کننده است. این در واقع تنها مجموعه دیگری از پارامترهای بیش از حد مورد نیاز برای بهینه‌سازی است.


منتشرشده در: مجله towardsdatascience به تاریخ ۱۵ فوریه ۲۰۲۰
نویسنده: Phillip Wenig
لینک مقاله اصلی: https://towardsdatascience.com/self-paced-learning-for-machine-learning-f1c489316c61

این مقاله توسط ربات مترجم هوشمند مقالات علمی و به صورت خودکار ترجمه شده و به صورت محدود مورد بازبینی انسانی قرار گرفته و می‌تواند دارای اشکالات ترجمه باشد.