در این فصل چه یاد میگیری#
دو ترم با جدول و بردار کار کردی. این ترم با تصویر کار میکند — و اولین چیزی که باید بفهمی این است که برای کامپیوتر هیچ تفاوتی نیست: تصویر هم یک tensor است، فقط با چیدمانِ خاصِ خودش.
در این فصل آن چیدمان را میبینی، قراردادِ C×H×W را که در کلِ PyTorch ثابت است یاد میگیری، و تصویر را برای دو مقصدِ متفاوت آماده میکنی: شبکهٔ خودت و مدلِ آمادهٔ فصلِ ۴.

آخر این فصل میتوانی:
tensorیک تصویر را بخوانی و ابعادش را توضیح بدهی- قراردادِ
C×H×Wو جایbatchرا بگویی - تصویر را درست نرمال کنی
- تصویرِ خاکستری را برای یک مدلِ آماده آماده کنی
قبل از شروع#
از ترمِ ۱ فصل ۱: tensor، shape، dtype.
از ترمِ ۲ فصل ۳: نرمالسازی و اینکه آمار را فقط از دادهٔ آموزش میگیری.
دادهٔ این ترم: FashionMNIST — ۷۰ هزار تصویرِ ۲۸×۲۸ خاکستری در ده دستهٔ پوشاک. اولین اجرا چند دقیقه دانلود میخواهد، بعدش چند ثانیه.
📓 نوتبوک: نوتبوک این فصل را در Colab باز کن — همهٔ کدهای این فصل آماده و بهترتیب داخلش هست.
💡 نکته: هر فصلِ این ترم روی CPU قابلِ اجراست. GPU سریعترش میکند ولی هیچ فصلی بدونش نمیشکند — همان قاعدهٔ سختِ این دوره.
۱. یک تصویر، بهصورتِ عدد#
import torch
import torch.nn as nn
image = Xtr[0]
print("شکل یک تصویر:", tuple(image.shape))
print("نوع:", image.dtype, "| کمینه:", float(image.min()), "| بیشینه:", float(image.max()))
print("برچسب:", int(ytr[0]), "->", CLASSES[int(ytr[0])])
شکل یک تصویر: (1, 28, 28)
نوع: torch.float32 | کمینه: 0.0 | بیشینه: 1.0
برچسب: 9 -> Ankle boot
(1, 28, 28) یعنی یک کانال، بیستوهشت سطر، بیستوهشت ستون. آن 1 تعدادِ کانالِ رنگ است — تصویرِ خاکستری یک کانال دارد و تصویرِ رنگی سهتا.
این ترتیب — C×H×W — قراردادِ ثابتِ PyTorch است و در کلِ ترم تکرار میشود. کتابخانههای دیگر (مثلاً PIL و matplotlib) ترتیبِ H×W×C را بهکار میبرند و همین یکی از رایجترین خطاهای شکل در کارِ با تصویر است.
۲. batch هم یک بُعدِ دیگر#
print("شکل batch:", tuple(Xtr[:8].shape))
print("C×H×W یعنی:", "کانال =", image.shape[0], "| ارتفاع =", image.shape[1], "| عرض =", image.shape[2])
print("سطر میانی (خام ۰..۲۵۵):", (image[0, 14] * 255).round().int().tolist())
شکل batch: (8, 1, 28, 28)
C×H×W یعنی: کانال = 1 | ارتفاع = 28 | عرض = 28
سطر میانی (خام ۰..۲۵۵): [0, 0, 1, 4, 6, 7, 2, 0, 0, 0, 0, 0, 237, 226, 217, 223, 222, 219, 222, 221, 216, 223, 229, 215, 218, 255, 77, 0]
آن سطر همان تصویر است. دوازده خانهٔ اول همه زیر ۱۰ هستند — زمینهٔ سیاه، که چند خانهاش دقیقاً صفر نیست بلکه ۱ و ۴ و ۶ است. بعد یک رشتهٔ طولانی از عددهای بالای ۲۰۰ (بدنهٔ روشنِ چکمه)، و در انتها ۷۷ و صفر.
همان چند خانهٔ «تقریباً سیاه» خودش یک درس است: زمینهٔ یک تصویرِ واقعی بهندرت عددِ گردِ صفر است. پس هیچوقت با == 0 دنبالِ زمینه نگرد؛ آستانه بگذار.
هیچ چیزِ اسرارآمیزی در تصویر نیست. یک جدولِ عدد است، و شبکهای که در ترمِ ۱ ساختی میتواند همین را بگیرد — که در فصلِ ۲ میبینیم چرا این کارِ درستی نیست.
پس شکلِ کاملِ ورودی N×C×H×W است: batch، کانال، ارتفاع، عرض. این چهار حرف را حفظ کن؛ هر خطای شکلی که در این ترم میگیری، با نوشتنِ همین چهارتا حل میشود.
۳. نرمالسازی#
mean, std = Xtr.mean(), Xtr.std()
normed = (Xtr - mean) / std
print("میانگین کل:", round(float(mean), 4), "| انحراف معیار:", round(float(std), 4))
print("بعد از استانداردسازی -> میانگین:", round(float(normed.mean()), 4), "| انحراف:", round(float(normed.std()), 4))
میانگین کل: 0.2855 | انحراف معیار: 0.3541
بعد از استانداردسازی -> میانگین: -0.0 | انحراف: 1.0
پیکسلها از قبل در بازهٔ ۰ تا ۱ بودند (تقسیم بر ۲۵۵)، ولی میانگینشان ۰٫۲۸ است — چون بیشترِ تصویر زمینهٔ سیاه است. استانداردسازی مرکز را به صفر میبرد.
⚠️ مواظب باش: میانگین و انحراف را از دادهٔ آموزش بگیر و همان را روی اعتبارسنجی و آزمون هم بهکار ببر — نه اینکه هر مجموعه آمارِ خودش را داشته باشد. این دقیقاً همان نشتیِ سرنخ ترمِ ۳ فصلِ ۴ است، و در کارِ با تصویر چون آمار «بیضرر» بهنظر میرسد، بیشتر پیش میآید.
برای تصویرِ رنگی، آمار را برای هر کانال جدا حساب میکنی — چون کانالِ آبی و قرمز توزیعِ متفاوتی دارند. و اگر از یک مدلِ آماده استفاده میکنی، باید دقیقاً همان آماری را بهکار ببری که آن مدل با آن آموزش دیده (فصلِ ۴).
۴. آماده کردن برای یک مدلِ آماده#
gray = Xtr[:2]
rgb = gray.repeat(1, 3, 1, 1)
big = torch.nn.functional.interpolate(rgb, size=(224, 224), mode="bilinear", align_corners=False)
print("خاکستری:", tuple(gray.shape), "-> سهکاناله:", tuple(rgb.shape), "-> بزرگشده:", tuple(big.shape))
خاکستری: (2, 1, 28, 28) -> سهکاناله: (2, 3, 28, 28) -> بزرگشده: (2, 3, 224, 224)
دو تبدیل، و هر دو در فصلِ ۴ لازم میشوند:
repeat(1, 3, 1, 1)همان کانالِ خاکستری را سه بار تکرار میکند. مدلهای آمادهٔ بینایی روی تصویرِ رنگی آموزش دیدهاند و سه کانال میخواهند. این کپیِ ساده اطلاعاتِ تازهای اضافه نمیکند — فقط شکل را با انتظارِ مدل جور میکند.interpolateبه ۲۲۴×۲۲۴ چون همان مدلها روی این اندازه آموزش دیدهاند.
📏 اندازه بگیر: بزرگ کردنِ ۲۸ به ۲۲۴ هیچ جزئیاتی اضافه نمیکند — همان اطلاعات را روی شبکهٔ درشتتری پخش میکند. پس انتظار نداشته باش مدلِ آماده معجزه کند؛ در فصلِ ۴ دقیقاً میسنجیم که با این محدودیت چقدر خوب کار میکند، و جوابش شاید غافلگیرت کند.
✅ چک کن: بعد از هر تبدیلِ تصویر، شکل را چاپ کن. اگر عددِ دوم ۳ نشد، مدلهای آماده خطای کانال میدهند؛ اگر دو عددِ آخر ۲۲۴ نشد، خطای اندازه. دو ثانیه وقت میگیرد و بیشترِ خطاهای این ترم را حذف میکند.
۵. جدولِ خطاهای شکل#
| پیامِ خطا | معنی | راهِ حل |
|---|---|---|
expected input[…] to have 3 channels but got 1 |
تصویرِ خاکستری به مدلِ رنگی | repeat(1, 3, 1, 1) |
Expected 4-dimensional input |
بُعدِ batch جا مانده |
unsqueeze(0) |
Given groups=1, weight of size […] |
تعدادِ کانالِ ورودی با لایه نمیخواند | in_channels را چک کن |
mat1 and mat2 shapes cannot be multiplied |
بعد از Flatten، اندازه با Linear نمیخواند |
خروجیِ لایهٔ آخرِ کانولوشن را حساب کن (فصلِ ۳) |
🔧 اگر کار نکرد: تصویر وارونه یا عجیب نمایش داده میشود — احتمالاً
H×W×Cرا بهmatplotlibندادهای؛image.permute(1, 2, 0)لازم است. دانلود گیر کرده — سلولِ راهاندازی را دوباره اجرا کن؛ فایلهای ناقص با اجرای دوباره تکمیل میشوند. همهچیز کند است — این ترم زیرمجموعهٔ ۴۰۰۰تایی میگیرد، نه کلِ ۶۰ هزار؛ اگر کدت را عوض کردهای، همان را برگردان.
🤖 از دستیارت بپرس: «چرا PyTorch از
C×H×Wاستفاده میکند در حالی که کتابخانههای تصویری معمولاًH×W×Cدارند؟» جوابش به نحوهٔ چیده شدنِ داده در حافظه و سرعتِ کانولوشن برمیگردد — و فهمیدنش کمکت میکند یادت بماند کدام کدام است. بعد بپرسpermuteوreshapeچه فرقی دارند؛ این دو را اشتباه گرفتن، تصویرت را بیصدا خراب میکند.
واژههای تازهٔ این فصل#
| کلمه | تلفظ به حروف فارسی | یعنی چه |
|---|---|---|
| channel | چنل | یکی از لایههای رنگیِ تصویر |
| C×H×W | — | ترتیبِ ابعادِ تصویر در PyTorch |
| interpolation | اینترپولیشن | تغییرِ اندازهٔ تصویر با محاسبهٔ پیکسلهای میانی |
| permute | پرمیوت | جابهجا کردنِ ترتیبِ ابعاد |
تمرینها
اول خودت فکر کن یا امتحان کن — بعد اینجا را باز کن.
در فصل بعد#
تصویر را به شکلِ tensor داری. حالا سؤالِ اصلی: چرا لایهٔ Linear که دو ترم بهکار بردی، برای تصویر ابزارِ اشتباهی است؟ فصلِ بعد جوابش را با شمردنِ پارامترها میدهد و بعد convolution را از پایه میسازد — با کرنلی که خودت مقدارش را میگذاری و میبینی دقیقاً چه چیزی پیدا میکند.
به آخر این فصل رسیدی!
اگر ساختی و جواب داد، این دکمه مال توست.