مقدمه
پردازش تصویر چیست و چرا اهمیت دارد؟
روشهای پیشرفته در پردازش تصویر
-
شبکههای عصبی کانولوشنی پیشرفته (Advanced CNNs)
import torch
import torch.nn as nn
import torchvision
import torchvision.transforms as transforms
from torchvision.models import efficientnet_b0, EfficientNet_B0_Weights
# تنظیم دستگاه
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# بارگذاری مدل از پیش آموزشدیده
model = efficientnet_b0(weights=EfficientNet_B0_Weights.IMAGENET1K_V1)
model.classifier[1] = nn.Linear(model.classifier[1].in_features, 10) # فرضاً 10 کلاس
model = model.to(device)
# پیشپردازش تصاویر
transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])
# داده نمونه (مثل CIFAR-10)
train_dataset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=32, shuffle=True)
# تعریف تابع loss و بهینهساز
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
# آموزش مدل
model.train()
for epoch in range(3): # 3 epoch برای مثال
running_loss = 0.0
for inputs, labels in train_loader:
inputs, labels = inputs.to(device), labels.to(device)
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
print(f"Epoch {epoch+1}, Loss: {running_loss/len(train_loader)}")
print("آموزش کامل شد!")
- تقسیمبندی تصویر (Image Segmentation)
تقسیمبندی تصویر به معنای تقسیم یک تصویر به بخشهای معنادار (مانند اشیا یا پسزمینه) است. مدلهای پیشرفته مانند U-Net، DeepLabV3+ و Mask R-CNN در این حوزه پیشرو هستند. این تکنیک در کاربردهایی مانند تشخیص تومور در تصاویر پزشکی یا جداسازی اشیا در تصاویر ماهوارهای بسیار مهم است.
چرا تقسیمبندی تصویر؟
دقت بالا: امکان شناسایی دقیق مرزهای اشیا.
کاربردهای عملی: از تحلیل تصاویر پزشکی تا خودروهای خودران.
ادغام با یادگیری عمیق: استفاده از معماریهای پیشرفته برای نتایج بهتر.
پیادهسازی: تقسیمبندی با U-Net (U-Net به دلیل معماری متقارن و اتصالات skip برای تقسیمبندی تصاویر پزشکی بسیار مناسب است.)
کد زیر یک نمونه از تقسیمبندی تصویر را آموزش میدهد.
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.utils.data import DataLoader
import torchvision.transforms as transforms
# تعریف مدل U-Net
class UNet(nn.Module):
def __init__(self, in_channels=3, out_channels=1):
super(UNet, self).__init__()
def conv_block(in_ch, out_ch):
return nn.Sequential(
nn.Conv2d(in_ch, out_ch, 3, padding=1),
nn.BatchNorm2d(out_ch),
nn.ReLU(inplace=True),
nn.Conv2d(out_ch, out_ch, 3, padding=1),
nn.BatchNorm2d(out_ch),
nn.ReLU(inplace=True)
)
self.enc1 = conv_block(in_channels, 64)
self.enc2 = conv_block(64, 128)
self.enc3 = conv_block(128, 256)
self.pool = nn.MaxPool2d(2, 2)
self.up2 = nn.ConvTranspose2d(256, 128, 2, stride=2)
self.dec2 = conv_block(256, 128)
self.up1 = nn.ConvTranspose2d(128, 64, 2, stride=2)
self.dec1 = conv_block(128, 64)
self.conv_out = nn.Conv2d(64, out_channels, 1)
def forward(self, x):
e1 = self.enc1(x)
e2 = self.enc2(self.pool(e1))
e3 = self.enc3(self.pool(e2))
d2 = self.up2(e3)
d2 = self.dec2(torch.cat([d2, e2], dim=1)) # اتصال skip
d1 = self.up1(d2)
d1 = self.dec1(torch.cat([d1, e1], dim=1))
out = self.conv_out(d1)
return torch.sigmoid(out)
# تنظیم دستگاه
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = UNet().to(device)
criterion = nn.BCELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
# فرض کنید train_loader برای دادههای پزشکی تعریف شده
model.train()
for epoch in range(5):
running_loss = 0.0
for inputs, masks in train_loader:
inputs, masks = inputs.to(device), masks.to(device)
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, masks)
loss.backward()
optimizer.step()
running_loss += loss.item()
print(f"Epoch {epoch+1}, Loss: {running_loss/len(train_loader):.4f}")
print("آموزش تقسیمبندی کامل شد!")
اتصالات Skip: این اتصالات اطلاعات فضایی را از لایههای رمزگذار (Encoder) به رمزگشا (Decoder)منتقل میکنند و برای حفظ جزئیات مهم هستند.
Loss Functions: برای دادههای نامتوازن، از Dice Loss یا ترکیب BCE و Dice استفاده کنید.
دادههای پزشکی: از مجموعه دادههای عمومی مانند ISIC 2018 یا Kaggle’s Chest X-Ray استفاده کنید.
- Vision Transformers (ViT)
ویژن ترنسفورمر یا ترنسفورمر بینایی یا Vision Transformers در سال ۲۰۲۵ جایگزین بسیاری از CNNها شدهاند. این مدلها تصاویر را به تکههای کوچک (Patches) تقسیم کرده و با معماری ترانسفورمر پردازش میکنند، که برای وظایفی مانند طبقهبندی و تشخیص اشیا بسیار موثر است.
چرا ViT؟
مکانیسم توجه سراسری (Global Attention): برخلاف CNNها که محلی عمل میکنند، ViTها کل تصویر را بهصورت یکپارچه تحلیل میکنند.
عملکرد برتر: در مجموعه دادههای بزرگ مانند ImageNet، ViTها دقت بالاتری دارند.
انعطافپذیری: برای وظایف مختلف از طبقهبندی تا تقسیمبندی قابل استفاده است.
پیادهسازی: طبقهبندی با ViT
از کتابخانه timm برای بارگذاری ViT استفاده میکنیم.import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.utils.data import DataLoader
import torchvision.transforms as transforms
# تعریف مدل U-Net
class UNet(nn.Module):
def __init__(self, in_channels=3, out_channels=1):
super(UNet, self).__init__()
def conv_block(in_ch, out_ch):
return nn.Sequential(
nn.Conv2d(in_ch, out_ch, 3, padding=1),
nn.BatchNorm2d(out_ch),
nn.ReLU(inplace=True),
nn.Conv2d(out_ch, out_ch, 3, padding=1),
nn.BatchNorm2d(out_ch),
nn.ReLU(inplace=True)
)
self.enc1 = conv_block(in_channels, 64)
self.enc2 = conv_block(64, 128)
self.enc3 = conv_block(128, 256)
self.pool = nn.MaxPool2d(2, 2)
self.up2 = nn.ConvTranspose2d(256, 128, 2, stride=2)
self.dec2 = conv_block(256, 128)
self.up1 = nn.ConvTranspose2d(128, 64, 2, stride=2)
self.dec1 = conv_block(128, 64)
self.conv_out = nn.Conv2d(64, out_channels, 1)
def forward(self, x):
e1 = self.enc1(x)
e2 = self.enc2(self.pool(e1))
e3 = self.enc3(self.pool(e2))
d2 = self.up2(e3)
d2 = self.dec2(torch.cat([d2, e2], dim=1)) # اتصال skip
d1 = self.up1(d2)
d1 = self.dec1(torch.cat([d1, e1], dim=1))
out = self.conv_out(d1)
return torch.sigmoid(out)
# تنظیم دستگاه
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = UNet().to(device)
criterion = nn.BCELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
# فرض کنید train_loader برای دادههای پزشکی تعریف شده
model.train()
for epoch in range(5):
running_loss = 0.0
for inputs, masks in train_loader:
inputs, masks = inputs.to(device), masks.to(device)
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, masks)
loss.backward()
optimizer.step()
running_loss += loss.item()
print(f"Epoch {epoch+1}, Loss: {running_loss/len(train_loader):.4f}")
print("آموزش تقسیمبندی کامل شد!")
- یادگیری خودنظارتی
import torch
import torchvision
import timm
from torch.utils.data import DataLoader
# تنظیم دستگاه
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# بارگذاری مدل DINO
model = timm.create_model('vit_small_patch16_224_dino', pretrained=True)
model = model.to(device)
# پیشپردازش تصاویر
transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.RandomResizedCrop(224),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])
])
# دادههای بدون برچسب (مثلاً STL-10)
train_dataset = torchvision.datasets.STL10(root='./data', split='unlabeled', download=True, transform=transform)
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
# تعریف تابع loss (سادهسازی شده)
criterion = torch.nn.MSELoss()
# آموزش مدل (سادهسازی شده برای مثال)
model.train()
for epoch in range(3):
running_loss = 0.0
for images, _ in train_loader:
images = images.to(device)
# ایجاد دو نمای مختلف از تصویر
view1 = transform(images)
view2 = transform(images)
# پیشبینی ویژگیها
out1 = model(view1)
out2 = model(view2)
loss = criterion(out1, out2)
loss.backward()
optimizer = torch.optim.Adam(model.parameters(), lr=0.0001)
optimizer.step()
optimizer.zero_grad()
running_loss += loss.item()
print(f"Epoch {epoch+1}, Loss: {running_loss/len(train_loader):.4f}")
print("آموزش DINO کامل شد!")
- تشخیص اشیا با YOLOv8
from ultralytics import YOLO
# بارگذاری مدل YOLOv8
model = YOLO('yolov8n.pt') # مدل از پیش آموزشدیده
# تشخیص اشیا در یک تصویر
results = model('path/to/image.jpg')
# نمایش و ذخیره نتایج
results.show()
results.save()
# آموزش روی دادههای سفارشی
model.train(data='path/to/custom_dataset.yaml', epochs=10, imgsz=640)
print("تشخیص و آموزش YOLOv8 کامل شد!")
جمعبندی
بینایی کامپیوتر به نقطهای رسیده که نهتنها ماشینها را قادر به دیدن کرده، بلکه آنها را به ابزارهایی هوشمند برای حل مسائل پیچیده در پزشکی، خودرو، امنیت و کشاورزی تبدیل کرده است. با تسلط بر روشهای پیشرفته مانند Vision Transformers، YOLOv8 و یادگیری خودنظارتی، میتوانید پروژههایی بسازید که دنیا را تغییر میدهند. کدهای ارائهشده در این مقاله، از EfficientNet تا U-Net، نقطه شروع شما برای ورود به این حوزه هیجانانگیز هستند. حالا زمان آن است که دست به کار شوید: یک مدل را روی دادههای خود آموزش دهید، نتایج را با TensorBoard تحلیل کنید و پروژهای واقعی مانند تشخیص اشیا در ویدئو یا تحلیل تصاویر پزشکی را پیادهسازی کنید.
سوالات متداول
-
تفاوت بین CNN و Vision Transformer چیست؟
- چگونه مدلها را برای دستگاههای Edge بهینه کنیم؟
- چرا TensorBoard برای آموزش مدلها مفید است؟
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
ثبت نظر