بهبود دقت با افزودن دندریت‌ها.
بهبود دقت با افزودن دندریت‌ها.

مدل‌های بهبود یافته PyTorch در چند دقیقه با Perforated Backpropagation — راهنمای گام به گام

Perforated Backpropagation یک تکنیک بهینه‌سازی است که از نوع جدیدی از نورون مصنوعی بهره می‌برد و به‌روزرسانی‌ای که مدت‌ها منتظر آن بودیم را برای مدل کنونی مبتنی بر علوم اعصاب سال ۱۹۴۳ به ارمغان می‌آورد. نورون جدید مفهوم دندریت‌های مصنوعی را نمونه‌برداری می‌کند و موازی با قدرت محاسباتی که دندریت‌ها در سیستم‌های بیولوژیکی به نورون‌ها اضافه می‌کنند، ایجاد می‌کند. برای جزئیات بیشتر در مورد نحوه کار نورون جدید، مقاله اول من را در اینجا بررسی کنید. این مقاله یک راهنمای گام به گام برای فرایند کوتاه افزودن این ابزار به پایپ‌لاین آموزشی PyTorch شما با استفاده از مثال پایه MNIST از مخزن رسمی PyTorch است.

گام ۱

اولین گام صرفاً نصب بسته است. این کار را می‌توان از طریق PyPi با استفاده از pip انجام داد:

pip install perforatedai

گام ۲

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

from perforatedai import pb_globals as PBG
from perforatedai import pb_models as PBM
from perforatedai import pb_utils as PBU

گام ۳

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

    model = Net().to(device)
    model = PBU.initializePB(model)

گام ۴

گام چهارم اولین گامی است که نیاز به کمی کدنویسی بیشتر دارد. پشت صحنه، توابع دندریتیک توسط یک شیء ردیاب Perforated Backpropagation مدیریت می‌شوند. این شیء سوابق بهبودهای آموزشی را نگهداری کرده و در مورد زمان افزودن دندریت‌ها به ماژول‌های شبکه تصمیم‌گیری می‌کند. برای بهترین عملکرد، ردیاب همچنین optimizer و scheduler را مدیریت می‌کند. این بدان معنی است که تغییر زیر باید هنگام تنظیم اولیه آن‌ها اعمال شود.

# Original:
optimizer = optim.Adadelta(model.parameters(), lr=args.lr)
scheduler = StepLR(optimizer, step_size=1, gamma=args.gamma)

# New Format:
PBG.pbTracker.setOptimizer(optim.Adadelta)
PBG.pbTracker.setScheduler(StepLR)
optimArgs = {'params':model.parameters(),'lr':args.lr}
schedArgs = {'step_size':1, 'gamma': args.gamma}
optimizer, scheduler = PBG.pbTracker.setupOptimizer(model, optimArgs, schedArgs)

این کد همان optimizer و scheduler را با همان تنظیمات ایجاد می‌کند، اما ردیاب نیز به آن‌ها اشاره دارد. علاوه بر این، optimizer.step() باید باقی بماند، اما scheduler.step() باید از حلقه آموزش حذف شود.

گام ۵

آخرین تغییری که باید اعمال شود، ارسال امتیازات اعتبار سنجی شما به ردیاب هر بار که یک چرخه اعتبار سنجی اجرا می‌شود، است. برای مثال MNIST، این کار با اضافه کردن بلوک کد زیر به تابع test انجام می‌شود:

model, restructured, trainingComplete = PBG.pbTracker.addValidationScore(100. * correct / len(test_loader.dataset), 
    model) 
    model.to(device)
if(restructured): 
    optimArgs = {'params':model.parameters(),'lr':args.lr}
    schedArgs = {'step_size':1, 'gamma': args.gamma}
    optimizer, scheduler = PBG.pbTracker.setupOptimizer(model, optimArgs, schedArgs)
return model, optimizer, scheduler, trainingComplete

اگر دندریت‌ها اضافه شده باشند، model یک معماری مدل جدید با همان وزن‌ها به جز ماژول‌های دندریت جدید خواهد بود. اگر این اتفاق به تازگی افتاده باشد، restructured درست خواهد بود. در این اپوک‌ها optimizer و scheduler باید برای اشاره به پارامترهای مدل جدید تنظیم مجدد شوند. خروجی سوم تابع addValidationScore متغیر trainingComplete است. این متغیر زمانی درست خواهد بود که ردیاب تصمیم بگیرد افزودن دندریت‌های اضافی عملکرد را بهبود نخواهد بخشید. در نهایت، تمام متغیرها باید از تابع test بازگردانده شوند تا برای اپوک آموزش بعدی در دسترس باشند. از آنجا که این متغیرها اکنون بازگردانده می‌شوند، دو تغییر زیر نیز مورد نیاز است:

# Original test Definition:
def test(model, device, test_loader):
# New Format
def test(model, device, test_loader, optimizer, scheduler, args):

# Original training loop
for epoch in range(1, args.epochs + 1):
    train(args, model, device, train_loader, optimizer, epoch)
    test(model, device, test_loader)
    scheduler.step()
# New Format
for epoch in range(1, args.epochs + 1):
    train(args, model, device, train_loader, optimizer, epoch)
    model, optimizer, scheduler, trainingComplete = test(model, device, test_loader, optimizer, scheduler, args)
    if(trainingComplete):
        break

اجرای اولین آزمایش شما

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

PBG.testingDendriteCapacity = False

با این تنظیمات، اکنون می‌توانید مجدداً اجرا کرده و نتایج زیر را بازتولید کنید که نشان‌دهنده کاهش ۲۹ درصدی در خطای باقی‌مانده مدل MNIST است.

استفاده از دندریت‌ها برای فشرده‌سازی

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

برای ساخت مدل‌های کاهش یافته با افزودن پارامترها، گام اساسی این است که با مدلی کوچک‌تر از مدل اصلی شروع کنید. برای مثال MNIST، این کار را می‌توان با اضافه کردن پارامتر width به تعریف مدل خود به صورت زیر انجام داد:

class Net(nn.Module):
    def __init__(self, num_classes, width):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, int(32*width), 3, 1)
        self.conv2 = nn.Conv2d(int(32*width), int(64*width), 3, 1)
        self.dropout1 = nn.Dropout(0.25)
        self.dropout2 = nn.Dropout(0.5)
        self.fc1 = nn.Linear(144*int(64*width), int(128*width))
        self.fc2 = nn.Linear(int(128*width), num_classes)

پس از اضافه کردن پارامتر width، می‌توانید تنظیمات width مختلفی را امتحان کنید. نمودار زیر با مقدار width ۰.۶۱ پس از اضافه کردن یک دندریت به مدل اصلی تولید شده است:

نمودار نشان‌دهنده عملکرد مدل فشرده شده با Perforated Backpropagation در مقابل مدل اصلی MNIST.
فشرده‌سازی مدل ۴۴% بدون از دست دادن دقت با استفاده از Perforated Backpropagation

همانطور که نمودار نشان می‌دهد، مدل کاهش‌یافته در داده‌های MNIST عملکرد بدتری دارد، اما کاهش width یک مدل با لایه‌های کاملاً متصل، کاهش درجه دوم در تعداد پارامترها را فراهم می‌کند. افزودن دندریت‌ها تنها با افزایش خطی همراه است. این چیزی است که به افزودن یک دندریت به هر نورون در مدل اجازه می‌دهد تا با دقت اصلی همگام شود، در حالی که مدل نهایی ۴۴٪ کوچک‌تر از تنظیمات اصلی باقی می‌ماند.

نتیجه‌گیری و فراخوان اقدام

Perforated Backpropagation را می‌توان در هر سیستم مبتنی بر PyTorch برای آزمایش ادغام کرد و در حال حاضر در طول تست بتا رایگان است. این سیستم را می‌توان برای فشرده‌سازی مدل‌ها (NLP، طبقه‌بندی اسید آمینه، پیش‌بینی سری زمانی، بینایی کامپیوتر Edge) و افزایش دقت (پیش‌بینی سهام، PEFT با LoRA، بینایی کامپیوتر) در تقریباً تمام فرمت‌های داده‌ای که امتحان کرده‌ایم، استفاده کرد. اگر مدل شما از افزایش دقت تا ۴۰٪ یا فشرده‌سازی مدل تا ۹۰٪ تنها با چند دقیقه کدنویسی بهره‌مند خواهد شد، برای تبدیل شدن به یک تست‌کننده بتا در اینجا ثبت نام کنید.