چیتشیت
ترنسفورمرهای بینایی و توکنهای وصلهای
Vision Transformers and Patch Tokens
تکهتکه کردن، امبد، افزودن CLS و موقعیت، اجرای بلوکهای پیشنرمالسازی لایهای. شمارش توکن، ریاضیات پارامتر و بستهبندی در هر وضوح دلخواه.
فهرست مطالب
پایپلاین ViT
معماریریاضیات ابعاد و هزینه محاسباتی
مفهومها- شبکه
- $(H/P) \times (W/P)$ پچ. 224 با پچ 16 میدهد 14x14 = 196 توکن.
- بردار پچ
- $3P^2$ مقدار. در P = 16 برابر است با 768.
- تصویر
nn.Conv2d(3, D, kernel_size=P, stride=P)معادل unfold و سپس linear است.- توالی
- پچها + 1 CLS + رجیسترها. ViT-B/16 در 224 برابر 197 است.
- هزینه اتنشن
- $n^2$. 196 توکن 38,416 امتیاز میدهد. 150,528 پیکسل 22.6 میلیارد میدهد.
- بعد هد
head_dim = hidden / num_heads. 768 / 12 = 64.- پارامترهای بلوک
- $12 D^2$ + 3k. حدود 7.1M در D = 768. 12 بلوک برابر 85M است.
- پارامترهای امبد تکه
3 * P * P * hidden + hidden. برابر 590,592 برای ViT-Base/16.
فوروارد Tiny ViT
کدpython
vit = ViT(image_size=64, patch_size=16, num_classes=10, dim=192, depth=6, num_heads=3)
x = self.patch(x) # (N, 16, 192)
cls = self.cls_token.expand(x.size(0), -1, -1)
x = torch.cat([cls, x], dim=1) # (N, 17, 192)
x = x + self.pos_embed # یادگرفتهشده، trunc_normal std=0.02
for blk in self.blocks:
x = blk(x) # اتنشن با پیشنرمالسازی لایهای، سپس MLP
return self.head(self.ln(x[:, 0])) # طبقهبندی فقط از روی [CLS]
بلوک پیشنرمالسازی لایهای در مقیاس ViT-B
کدpython
cfg = ViTConfig() # 224، 16، وضعیت پنهان 768، عمق 12، 12 هد
qkv = self.qkv(x).reshape(b, n, 3, h, hd).permute(2, 0, 3, 1, 4)
q, k, v = qkv[0], qkv[1], qkv[2]
scores = (q @ k.transpose(-2, -1)) * self.scale # scale = 1 / sqrt(head_dim)
attn = F.softmax(scores, dim=-1) # بدون ماسک. انکودر دوطرفه است
x = x + self.attn(self.ln1(x), store_attn=store_attn)
x = x + self.ffn(self.ln2(x)) # hidden به 4 * hidden و سپس به hidden
tokens, cls = encoder(img) # (1, 197, 768) و (1, 768)
وظایف در کد
کار و کد| وظیفه | کد |
|---|---|
| مدل پیشآموزشدیده ViT-B/16 | timm.create_model("vit_base_patch16_224") |
| پچهای تخت، stdlib | patchify(image, patch_size) |
| جدول موقعیت 2D ثابت | sinusoidal_2d(grid_h, grid_w, dim) |
| بررسی محاسبات Conv2d | unfold_then_linear(x, weight, bias, patch_size) |
| طول توالی | seq_length(cfg) |
| FLOPs به ازای هر فوروارد | flops_per_forward(cfg) |
| بستهبندی ابعاد مختلف | pack_batch(images, patch) |
| ماسک قطری-بلوکی | build_dense_mask(pack) |
دستورها
دستورها| دستور | کاربرد |
|---|---|
`python3 code/main.py` (19.58) | بخش جلویی خروجی (1, 197, 768) میدهد |
`python3 code/main.py` (19.59) | انکودر کامل. حدود 86M پارامتر |
python3 -m unittest code/test_main.py | اجرای تستهای ابعاد و همارزی |
`code/main.py` (12.01) | توکنایزر پچ و محاسبهگر هندسه |
اندازههای مدل
پیشفرضها| تنظیم | پیشفرض | نکته |
|---|---|---|
ViT-B/16 | 86M | dim=768، عمق=12، هدها=12 |
ViT-Large | ~307M | hidden=1024، عمق=24، هدها=16 |
ViT-Huge | ~632M | بعد ویژگی 1280 |
SigLIP So400M | 400M | hidden=1152، عمق=27، هدها=16 |
Tiny ViT (lesson 4.14) | 2.8M | dim=192، عمق=6، CPU |
MLP expansion | 4x | 2x آندرفیت میشود، 8x اورفیت میشود |
Register tokens | 4 | DINOv2 و SigLIP 2 |
MAE mask | 75% | انکودر فقط 25% قابلمشاهده را میبیند |
اندازه پچ و تعداد توکن
پیشفرضها| تنظیم | پیشفرض | نکته |
|---|---|---|
224, patch 16 | 196 tokens | استاندارد |
224, patch 32 | 49 tokens | سریعتر، وضوح پایینتر |
224, patch 8 | 784 tokens | دقیقتر، هزینه درجه دو |
SigLIP 2 SO400m/14 at 384 | 729 patch tokens | برج پیشفرض VLM در 2026 |
NaFlex budgets | 256, 729, 1024 | یک چکپوینت، انتخاب در زمان استنتاج |
AnyRes 672x672, 2x2 + thumbnail | 2880 | 4 * 576 + 576 |
OCR and documents | 1024-4096 tokens | عکسهای طبیعی به 256-576 نیاز دارند |
بستهبندی پچها برای یک دسته با ابعاد مختلف
گامبهگام- شبکهمحاسبه شبکه پچ بومی هر تصویر با اندازه پچ 14.
- تخت کردنهر تصویر به توالی متغیر خود تبدیل میشود.
- الحاقپیوند همه توالیها در یک توالی. آفستها
cu_seqlensرا میدهند. - ماسکساخت ماسک قطری-بلوکی. پچها فقط درون تصویر خود اتنشن دارند.
- موقعیتاختصاص RoPE دوبعدی یا موقعیت کسری به هر پچ.
- نتیجه576 + 256 + 768 توکن یک توالی 1600 توکنی میدهد. بدون پدینگ.
گزینههای پولینگ و موقعیت
مفهومها- توکن [CLS]
- وضعیت پنهان نهایی آن معرف تصویر است. ViT اولیه و CLIP از آن استفاده میکنند.
- پولینگ میانگین
- میانگین خروجیهای پچ. SigLIP و DINOv2 از آن استفاده میکنند.
- توکنهای رجیستر
- 4 تا 16 توکن اضافی برای جذب دستسازههای با نرم بالا. قبل از LLM حذف شوند.
- موقعیت 1D یادگرفتهشده
- مدل را به وضوح آموزش مقید میکند.
- سینوسی 2D
- ثابت، 0 پارامتر. نیمی از بعد برای سطر و نیمی برای ستون است.
- 2D-RoPE و M-RoPE
- دوران q و k با (سطر، ستون). بدون جدول موقعیت.
- تحویل وظیفه به VLM
- رد کردن پولینگ. هر پچ یک توکن ورودی LLM میشود.
عیبیابی
عیبیابیViT در ImageNet-1k به ResNet میبازد
- علت
- نبود پیشینهای CNN، داده بسیار کم
- راهحل
- دستورالعمل DeiT یا پیشآموزش MAE
مدلهای عمیق آموزش نمیبینند
- علت
- پسنرمالسازی لایهای بعد از 6-8 لایه
- راهحل
- استفاده از پیشنرمالسازی لایهای
وضوح جدید موقعیتها را به هم میریزد
- علت
- جدول 1D یادگرفتهشده
- راهحل
- درونیابی، یا استفاده از 2D-RoPE
متن لهشده، از دست رفتن برچسبهای نمودار
- علت
- تغییر اندازه مربعی
- راهحل
- انکود در وضوح تصویر اصلی
بیش از 50% توکنها پدینگ هستند
- علت
- پدینگ به اندازه بلندترین ضلع
- راهحل
- بستهبندی پچها با ماسک
دستسازههای پچ با نرم بالا
- علت
- نبود توکن جاذب (sink)
- راهحل
- افزودن توکنهای رجیستر
ValueError در ساخت شبکه
- علت
patch_sizeبرimage_sizeبخشپذیر نیست- راهحل
- انتخاب اندازه پچ مقسومعلیه
خطای تابع
sinusoidal_2d- علت
- dim بر 4 بخشپذیر نیست
- راهحل
- استفاده از بعد مضرب 4
پرسشها
پرسش و پاسخ- چرا پچ به جای پیکسل؟
- یک تصویر 224x224 برابر 150,528 توکن پیکسلی است. هزینه اتنشن درجه دو است.
- چرا پیشنرمالسازی لایهای؟
- لایههای عمیق را پایدار و بدون گرمکردن آموزش میدهد.
- پچ 14 یا 16؟
- پچ 14 توکنهای بیشتری میدهد. برای OCR و وظایف متراکم بهتر، اما کندتر است.
- کدام بکبون برای ویژگیهای متراکم؟
- DINOv2. برای تطبیق با متن از CLIP یا SigLIP استفاده کنید.
- موقعیت یادگرفتهشده یا سینوسی؟
- در وضوح ثابت یادگرفتهشده برنده است. هنگام تغییر وضوح، سینوسی بهتر است.