چیت‌شیت

مفاهیم ضروری PyTorch

PyTorch Essentials

تنسورها، مشتق‌گیری خودکار، nn.Module، حلقه آموزش، DataLoader و دستگاه‌ها، از درس‌ها.

  • ۱۲ بخش
  • ۴ درس مرتبط
  • کد و دستورها عیناً از دوره‌ی اصلی
فهرست مطالب
  1. وظایف
  2. گام آموزش
  3. پایپ‌لاین آموزش
  4. آموزش و ارزیابی
  5. داده و دقت ترکیبی
  6. عملیات تنسور
  7. ماژول‌ها
  8. پیش‌فرض‌ها و اعداد
  9. مفاهیم کلیدی
  10. عیب‌یابی
  11. پروب‌های دیباگ
  12. نکات

وظایف

کار و کد
وظیفهکد
انتخاب یک دستگاهdevice = torch.device("cuda" if torch.cuda.is_available() else "cpu")
ساخت یک تنسور روی آنx = torch.randn(3, 4, device=device)
انتقال مدل و دستهmodel = model.to(device)
شمارش پارامترهاsum(p.numel() for p in model.parameters())
ذخیره وزن‌هاtorch.save(model.state_dict(), "model.pt")
بارگذاری وزن‌هاmodel.load_state_dict(torch.load("model.pt", weights_only=True))
ارزیابی بدون گراف`model.eval()` then `with torch.no_grad():`
بررسی GPUtorch.cuda.get_device_name(0)

گام آموزش

گام‌به‌گام
  1. DataLoaderیک دسته از ورودی‌ها و اهداف را تحویل می‌دهد.
  2. دستگاهinputs.to(device), targets.to(device) دسته را منتقل می‌کند.
  3. بهینه‌سازoptimizer.zero_grad() گرادیان‌های قبلی را پاک می‌کند.
  4. مدلoutputs = model(inputs) گذر رو به جلو را اجرا می‌کند.
  5. تابع زیان (loss)criterion(outputs, targets) یک مقدار اسکالر برمی‌گرداند.
  6. مشتق‌گیری خودکارloss.backward() نوار را به صورت معکوس بازپخش می‌کند.
  7. بهینه‌سازoptimizer.step() پارامترها را به‌روزرسانی می‌کند.

پایپ‌لاین آموزش

معماری
نمونه‌هادستهخروجی‌هاپس‌انتشارگرادیان‌هابه‌روزرسانیDataset__len__, __getitem__DataLoaderدسته، بُر زدن، ورکرهاnn.Moduleforward(), parameters()تابع زیان (loss)لاجیت‌ها و تارگت‌هامشتق‌گیری خودکارloss.backward()بهینه‌سازstep(), zero_grad()

آموزش و ارزیابی

کد
python
criterion = nn.CrossEntropyLoss()  # لاجیت‌های خام را می‌گیرد
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
for epoch in range(num_epochs):
    model.train()                  # دراپ‌اوت و نرمال‌سازی دسته روشن است
    for inputs, targets in train_loader:
        inputs, targets = inputs.to(device), targets.to(device)
        optimizer.zero_grad()      # گرادیان‌ها جمع می‌شوند
        outputs = model(inputs)    # گذر رو به جلو
        loss = criterion(outputs, targets)
        loss.backward()            # محاسبه گرادیان‌ها
        optimizer.step()           # به‌روزرسانی وزن‌ها
model.eval()                       # حالت ارزیابی (eval) برای تست
with torch.no_grad():              # بدون گراف، حافظه کمتر
    outputs = model(images)

داده و دقت ترکیبی

کد
python
class MNISTDataset(Dataset):
    def __len__(self):
        return len(self.labels)         # تعداد نمونه‌ها
    def __getitem__(self, idx):
        return self.images[idx], self.labels[idx] # one sample
loader = DataLoader(dataset, batch_size=64, shuffle=True, num_workers=4)
scaler = GradScaler()                   # از torch.amp
for inputs, targets in loader:
    with autocast(device_type="cuda"):  # گذر رو به جلو با float16
        outputs = model(inputs)
        loss = criterion(outputs, targets)
    scaler.scale(loss).backward()       # پس‌انتشار مقیاس‌شده
    scaler.step(optimizer)
    scaler.update()
    optimizer.zero_grad()

عملیات تنسور

دستورها
دستورعملکرد
x.view(2, 12)تغییر شکل. تنسور باید پیوسته در حافظه باشد
x.reshape(6, 4)تغییر شکل. همیشه کار می‌کند
x.permute(2, 0, 1)تغییر ترتیب ابعاد
x.unsqueeze(0)افزودن یک بُعد، (1, 2, 3, 4)
x.squeeze()حذف ابعاد با اندازه 1
`x.to("cuda")` / `x.cpu()`انتقال تنسور بین دستگاه‌ها
.detach()جدا کردن تنسور از گراف
labels.long()تبدیل نوع برچسب‌ها برای آنتروپی متقاطع

ماژول‌ها

دستورها
دستورعملکرد
nn.Linear(in, out)$Wx + b$، پارامترهای in*out + out
nn.Conv2d(in_ch, out_ch, k)کانولوشن دوبعدی
nn.BatchNorm1d(features)نرمال‌سازی اکتیویشن‌ها، features * 2
nn.LayerNorm(dim)نرمال‌سازی به ازای هر نمونه، dim * 2
nn.Dropout(p)صفر کردن تصادفی، 0 پارامتر
nn.ReLU()$\max(0, x)$
nn.Embedding(vocab, dim)جدول جستجو، vocab * dim
nn.Sequential(...)اجرای ماژول‌ها به ترتیب

پیش‌فرض‌ها و اعداد

پیش‌فرض‌ها
تنظیمپیش‌فرضنکته
Tensor dtypefloat32دقت پیش‌فرض آموزش
LLM training dtypebfloat16بازه float32، دقت کمتر
Adam learning rate1e-3نقطه شروع پیش‌فرض
SGD start learning rate1e-2یا 1e-1، طبق درس دیباگ
DataLoader batch_size64لودر آموزش در درس
num_workers4فرایندهای موازی بارگذاری
Dropout in MNIST MLP0.2بعد از هر ReLU پنهان
fp16 bytes per parameter2حافظه GPU را بر 2 تقسیم کن، حاشیه نگه دار

مفاهیم کلیدی

مفهوم‌ها
تنسور
آرایه‌ای دارای شکل، dtype و دستگاه.
قانون دستگاه یکسان
همه عملیات‌ها نیاز دارند تمام تنسورها روی یک دستگاه باشند.
مشتق‌گیری خودکار
عملیات‌ها را روی یک نوار ضبط کرده، سپس معکوس بازپخش می‌کند.
تنسور برگ
فقط برگ‌های با requires_grad=True گرادیان‌ها را انباشته می‌کنند.
انباشت
گرادیان‌ها به‌طور پیش‌فرض جمع می‌شوند. در هر گام zero_grad را صدا بزنید.
ثبت
ماژول‌ها و nn.Parameter تنظیم‌شده در __init__ توسط parameters() پیدا می‌شوند.
state_dict
نگاشت نام‌ها به تنسورها. قابل انتقال با وجود تغییرات کد.
دقت ترکیبی
گذر رو به جلو و پس‌انتشار با float16، وزن‌های اصلی با float32.

عیب‌یابی

عیب‌یابی
  • RuntimeError: expected CUDA tensor

    علت
    مدل و داده روی دستگاه‌های متفاوتند
    راه‌حل
    اجرای .to(device) روی مدل و داده
  • RuntimeError: modified by in-place operation

    علت
    عملیات درجا مشتق‌گیری خودکار را مختل می‌کند
    راه‌حل
    جایگزینی x += 1 با x = x + 1
  • نوسان تابع زیان (loss)

    علت
    عدم استفاده از optimizer.zero_grad()
    راه‌حل
    صدا زدن آن قبل از loss.backward()
  • تغییر دقت تست بین اجراهای مختلف

    علت
    عدم استفاده از model.eval() در زمان تست
    راه‌حل
    افزودن model.eval() و torch.no_grad()
  • اتمام حافظه (OOM)

    علت
    آزاد نشدن گراف
    راه‌حل
    .detach() یا torch.no_grad()
  • خطای dtype در آنتروپی متقاطع

    علت
    برچسب‌ها Float هستند
    راه‌حل
    تبدیل نوع با labels.long()
  • گرادیان‌های اشتباه، بدون خطا

    علت
    ارسال خروجی سافت‌مکس به CrossEntropyLoss
    راه‌حل
    ارسال لاجیت‌های خام
  • پرش تابع زیان (loss) به NaN

    علت
    انفجار گرادیان
    راه‌حل
    torch.nn.utils.clip_grad_norm_ یا کاهش نرخ یادگیری

پروب‌های دیباگ

کار و کد
وظیفهکد
یافتن عملیاتی که باعث NaN شدwith torch.autograd.detect_anomaly():
بررسی تابع زیان (loss) برای NaNtorch.isnan(loss)
خواندن نرم گرادیانtorch.nn.utils.clip_grad_norm_(model.parameters(), float("inf"))
خواندن حافظه GPUtorch.cuda.memory_allocated() / 1e9

نکات

نکته‌ها
  • اول آزمون بیش‌برازش روی یک بچ را اجرا کن. اگر شکست بخورد، ستاپ مشکل دارد.
  • قبل از گشتن دنبال باگ‌های دیگر، 3 نرخ یادگیری با اختلاف 10 برابری را امتحان کن.
  • شکل‌ها را بعد از هر عملیات چاپ کن. برادکستینگ باگ‌های ابعاد را پنهان می‌کند.
  • ورودی‌ها را به میانگین 0 و انحراف معیار 1 نرمال کن.
  • گیر کردن تابع زیان (loss) روی -log(1/num_classes) به معنی پیش‌بینی‌های یکنواخت است.
  • برای داده‌های وابسته به دیسک از num_workers استفاده کن. می‌تواند سرعت را دوبرابر کند.
ترجمه‌ی فارسی چیت‌شیت PyTorch Essentials از دوره‌ی AI Engineering from Scratch، نوشته‌ی Rohit Ghumare، تحت مجوز MIT. کد و دستورها عیناً از متن اصلی‌اند. همه‌ی چیت‌شیت‌ها