ট্রান্সফার লার্নিং এবং প্রি-ট্রেইন্ড মডেল মেশিন লার্নিং এবং ডিপ লার্নিংয়ে দ্রুত মডেল তৈরি এবং উচ্চ কার্যকারিতা অর্জনের একটি কার্যকর উপায়। PyTorch-এ প্রি-ট্রেইন্ড মডেল ব্যবহার করে কিভাবে ট্রান্সফার লার্নিং করা যায় তা নিচে ধাপে ধাপে বর্ণনা করা হলো।
ট্রান্সফার লার্নিং এমন একটি পদ্ধতি যেখানে একটি প্রি-ট্রেইন্ড মডেল, যা বড় ডেটাসেটে প্রশিক্ষিত হয়েছে (যেমন ImageNet), একটি নতুন টাস্কের জন্য ব্যবহার করা হয়। এটি নতুন টাস্কে দ্রুত মডেল তৈরি করতে সহায়ক হয়, কারণ প্রি-ট্রেইন্ড মডেল আগে থেকেই ফিচার এক্সট্রাকশন শিখে থাকে।
PyTorch-এর torchvision
লাইব্রেরিতে অনেক প্রি-ট্রেইন্ড মডেল রয়েছে, যেমন ResNet, VGG, এবং MobileNet। নিচে ResNet-18 প্রি-ট্রেইন্ড মডেল লোড করার একটি উদাহরণ দেওয়া হল:
import torch
import torchvision.models as models
# প্রি-ট্রেইন্ড ResNet-18 মডেল লোড করা
model = models.resnet18(pretrained=True)
প্রি-ট্রেইন্ড মডেলের প্রথম দিকের লেয়ারগুলি সাধারণত জেনারেল ফিচার (যেমন এজ, টেক্সচার) এক্সট্রাক্ট করে। তাই এগুলো ফ্রিজ করে রেখে শেষে কিছু লেয়ার পরিবর্তন করা হয় যাতে মডেল নতুন টাস্কের জন্য ব্যবহারযোগ্য হয়।
# সব লেয়ার ফ্রিজ করা
for param in model.parameters():
param.requires_grad = False
প্রি-ট্রেইন্ড মডেলের শেষ লেয়ারটি সাধারণত টাস্ক-নির্দিষ্ট হয় (যেমন ImageNet-এর ক্ষেত্রে ১০০০ ক্লাস)। আমরা এটি আমাদের নতুন টাস্ক অনুযায়ী পরিবর্তন করব। উদাহরণস্বরূপ, যদি আমাদের ডেটাসেটে ২ ক্লাস থাকে:
import torch.nn as nn
# মডেলের শেষ লেয়ার পরিবর্তন করা (এখানে ২ ক্লাসের জন্য)
num_features = model.fc.in_features
model.fc = nn.Linear(num_features, 2)
এখন আমরা আমাদের মডেলের নতুন লেয়ার ট্রেনিংয়ের জন্য লস ফাংশন এবং অপটিমাইজার সেট করব। যেহেতু আমরা শুধুমাত্র শেষ লেয়ার ট্রেনিং করব, তাই আমরা সেই প্যারামিটারগুলো অপটিমাইজারের সাথে সংযুক্ত করব।
import torch.optim as optim
# লস ফাংশন এবং অপটিমাইজার সেট করা
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.fc.parameters(), lr=0.001) # শুধুমাত্র শেষ লেয়ারের প্যারামিটার
প্রি-ট্রেইন্ড মডেল ট্রেনিং প্রক্রিয়া সাধারণ PyTorch মডেল ট্রেনিংয়ের মতোই, তবে এখানে আমরা শুধুমাত্র শেষ লেয়ার আপডেট করছি।
# মডেল ট্রেনিং (একটি সাধারণ উদাহরণ)
epochs = 5
for epoch in range(epochs):
model.train() # মডেল ট্রেনিং মোডে সেট করা
running_loss = 0.0
for inputs, labels in train_loader: # ট্রেনিং ডেটা লোড করা
inputs, labels = inputs.to('cuda'), labels.to('cuda')
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):.4f}')
মডেল ভ্যালিডেশন এবং ইনফারেন্সের সময় পুরো মডেলটি ব্যবহার করা হয়। নিশ্চিত করতে হবে যে মডেলটি ইভ্যালুয়েশন মোডে আছে:
model.eval() # মডেল ইভ্যালুয়েশন মোডে
# ভ্যালিডেশন লুপ (যদি প্রয়োজন হয়)
# ইনফারেন্সের জন্য শুধু টেস্ট ইনপুট ব্যবহার করা
with torch.no_grad(): # গ্রেডিয়েন্ট ক্যালকুলেশন বন্ধ
test_input = torch.randn(1, 3, 224, 224).to('cuda') # উদাহরণ ইনপুট
output = model(test_input)
_, predicted = torch.max(output, 1)
print(f'Predicted class: {predicted.item()}')
models.resnet18(pretrained=True)
models.vgg16(pretrained=True)
models.mobilenet_v2(pretrained=True)
এভাবে ট্রান্সফার লার্নিং এবং প্রি-ট্রেইন্ড মডেল ব্যবহার করে দ্রুত এবং কার্যকরভাবে মডেল তৈরি এবং প্রশিক্ষণ করা যায়।
Transfer Learning হলো মেশিন লার্নিং এবং ডিপ লার্নিংয়ের একটি কৌশল, যেখানে একটি পূর্বে ট্রেন করা মডেলের জ্ঞান (knowledge) ব্যবহার করে নতুন কিন্তু সংশ্লিষ্ট টাস্কের জন্য মডেল ট্রেন করা হয়। এটি সময় এবং কম্পিউটেশনের খরচ কমাতে সাহায্য করে, কারণ সম্পূর্ণ নতুন মডেল শূন্য থেকে ট্রেন করার পরিবর্তে, একটি পূর্বে ট্রেন করা মডেল থেকে শেখা বৈশিষ্ট্যগুলি পুনরায় ব্যবহার করা হয়।
ডেটার অপ্রতুলতা (Data Scarcity):
কম্পিউটেশনাল ক্ষমতা এবং সময় সংরক্ষণ:
ফিচার এক্সট্রাকশন (Feature Extraction):
কনভার্জেন্স দ্রুত করা:
Pre-trained Model নির্বাচন করা:
মডেলের লেয়ার ফ্রিজ করা (Freezing Layers):
নতুন লেয়ার যোগ করা:
মডেল পুনরায় ট্রেন করা (Fine-tuning):
import torch
import torchvision.models as models
import torch.nn as nn
# Pre-trained মডেল লোড করা (ResNet18 উদাহরণ)
model = models.resnet18(pretrained=True)
# প্রথম লেয়ারগুলো ফ্রিজ করা
for param in model.parameters():
param.requires_grad = False
# ফাইনাল লেয়ার পরিবর্তন করা (নতুন আউটপুট ক্যাটেগরি অনুযায়ী)
model.fc = nn.Linear(model.fc.in_features, num_classes)
# মডেল ট্রেনিং করা
# criterion, optimizer এবং dataloader তৈরি করে ট্রেনিং লুপ চালানো হবে
এই উদাহরণে, আমরা একটি ResNet18 মডেল লোড করেছি যা ImageNet ডেটাসেটে প্রি-ট্রেন করা। আমরা মডেলের প্রথম লেয়ারগুলো ফ্রিজ করেছি এবং শুধুমাত্র নতুন ফাইনাল লেয়ারটি ট্রেন করব, যাতে নতুন টাস্কের আউটপুটের জন্য মডেল প্রস্তুত হয়।
Transfer Learning মূলত নতুন টাস্কের জন্য ডেটার অপ্রতুলতা, কম্পিউটেশনাল ক্ষমতার সীমাবদ্ধতা, এবং দ্রুত মডেল ট্রেনিংয়ের প্রয়োজনীয়তার জন্য অত্যন্ত উপযোগী। এটি মডেলের পুনঃব্যবহারযোগ্যতা বাড়ায় এবং ট্রেনিংয়ের সময় ও রিসোর্স সাশ্রয় করতে সহায়ক।
PyTorch-এ Feature Extraction এবং Fine-tuning দুটি পদ্ধতি ব্যবহার করা হয় প্রি-ট্রেইন্ড মডেলকে নতুন ডেটাসেটে পুনরায় প্রয়োগ করার জন্য। এটি সাধারণত কম্পিউটার ভিশন, NLP এবং অন্যান্য ডিপ লার্নিং কাজে ব্যবহার করা হয়। PyTorch এর torchvision
লাইব্রেরিতে বিভিন্ন প্রি-ট্রেইন্ড মডেল আছে, যেমন: ResNet, VGG, AlexNet, ইত্যাদি, যেগুলো ব্যবহার করা যায়। নিচে উদাহরণসহ এই দুটি পদ্ধতির ব্যাখ্যা দেওয়া হল।
Feature Extraction-এ প্রি-ট্রেইন্ড মডেলের ওজন (weights) ফ্রিজ করে রাখা হয় এবং নতুন ডেটাসেটের উপর শুধু ক্লাসিফিকেশন লেয়ারগুলো ট্রেনিং করা হয়। মডেলের বাকি অংশগুলো ফিচার এক্সট্রাক্টর হিসেবে কাজ করে।
import torch
import torch.nn as nn
import torchvision.models as models
# ডিভাইস সেট করা
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# প্রি-ট্রেইন্ড ResNet মডেল লোড করা
model = models.resnet18(pretrained=True)
# সমস্ত লেয়ারের গ্রেডিয়েন্ট ফ্রিজ করা
for param in model.parameters():
param.requires_grad = False
# শেষের ফুলি কানেক্টেড লেয়ার পরিবর্তন করা
num_features = model.fc.in_features
model.fc = nn.Linear(num_features, 10) # উদাহরণস্বরূপ, এখানে ১০টি ক্লাস ধরেছি
# মডেলকে ডিভাইসে মুভ করা
model = model.to(device)
# মডেল আউটপুট চেক করা
print(model)
প্রি-ট্রেইন্ড মডেল লোড করা:
models.resnet18(pretrained=True)
দিয়ে ResNet-18 মডেল লোড করা হয়েছে। pretrained=True
দ্বারা ইমেজনেট (ImageNet) ডেটাসেটে প্রি-ট্রেইন্ড ওজন লোড করা হয়েছে।ওজন ফ্রিজ করা:
param.requires_grad = False
করে মডেলের সমস্ত লেয়ারের গ্রেডিয়েন্ট ফ্রিজ করা হয়েছে। এর ফলে শুধু নতুন অ্যাডেড লেয়ার ট্রেনিং হবে।ক্লাসিফিকেশন লেয়ার পরিবর্তন:
model.fc = nn.Linear(num_features, 10)
দ্বারা ক্লাসিফিকেশন লেয়ার পরিবর্তন করা হয়েছে যাতে এটি নতুন ডেটাসেটের সাথে মিলিয়ে ফাইন-টিউন করা যায়।Fine-tuning-এ পুরো মডেল (বা কিছু অংশ) ট্রেনিংয়ে অংশ নেয়। এটি সাধারণত তখনই করা হয় যখন নতুন ডেটাসেট প্রি-ট্রেইন্ড ডেটাসেটের (যেমন ImageNet) থেকে খুব আলাদা হয় এবং মডেলের আরও স্পেসিফিক ফিচার প্রয়োজন হয়।
# সমস্ত লেয়ারের গ্রেডিয়েন্ট চালু রাখা (ডিফল্ট)
model = models.resnet18(pretrained=True)
# শেষের ফুলি কানেক্টেড লেয়ার পরিবর্তন করা
num_features = model.fc.in_features
model.fc = nn.Linear(num_features, 10)
# মডেলকে ডিভাইসে মুভ করা
model = model.to(device)
# অপ্টিমাইজার সেট করা
optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.9)
# লস ফাংশন সেট করা
criterion = nn.CrossEntropyLoss()
গ্রেডিয়েন্ট চালু রাখা:
অপ্টিমাইজার সেট করা:
torch.optim.SGD
ব্যবহার করে SGD অপ্টিমাইজার তৈরি করা হয়েছে, যা মডেলের সব লেয়ারের ওজন আপডেট করবে।num_epochs = 5
for epoch in range(num_epochs):
model.train() # ট্রেনিং মোডে সেট করা
for images, labels in train_loader:
images, labels = images.to(device), labels.to(device)
# ফরওয়ার্ড পাস
outputs = model(images)
loss = criterion(outputs, labels)
# ব্যাকওয়ার্ড পাস এবং অপ্টিমাইজেশন
optimizer.zero_grad()
loss.backward()
optimizer.step()
print(f"Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}")
এইভাবে, Feature Extraction এবং Fine-tuning এর মাধ্যমে প্রি-ট্রেইন্ড মডেলকে কাস্টম ডেটাসেটের উপর কাস্টমাইজ এবং ট্রেনিং করা যায়।
Transfer Learning হলো একটি টেকনিক যেখানে একটি প্রি-ট্রেইনড মডেল ব্যবহার করে নতুন ডেটাসেটে মডেলকে ফাইন-টিউন করা হয়। এটি বিশেষ করে সেই পরিস্থিতিতে কার্যকরী যেখানে আমাদের কাছে ডেটা সীমিত পরিমাণে থাকে। PyTorch-এ Transfer Learning সহজে প্রয়োগ করা যায় এবং এটি Image Classification-এর মতো কাজে ব্যাপকভাবে ব্যবহৃত হয়।
এখানে আমরা PyTorch-এর ResNet18 মডেল ব্যবহার করবো, যা ImageNet ডেটাসেটে প্রি-ট্রেইনড হয়েছে। এরপর আমরা আমাদের নিজস্ব ডেটাসেটে (উদাহরণস্বরূপ, Cats vs. Dogs) ফাইন-টিউন করবো।
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, models, transforms
আমরা torchvision.transforms ব্যবহার করে ডেটা ট্রান্সফর্ম করবো এবং ডেটাসেট লোড করবো:
# ট্রেনিং এবং ভ্যালিডেশন ডেটার জন্য ট্রান্সফর্ম তৈরি করা
data_transforms = {
'train': transforms.Compose([
transforms.Resize((224, 224)),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
]),
'val': transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
]),
}
# ডেটাসেট লোড করা (উদাহরণস্বরূপ, একটি লোকাল ফোল্ডার থেকে)
data_dir = 'data/cats_and_dogs'
image_datasets = {x: datasets.ImageFolder(root=f'{data_dir}/{x}', transform=data_transforms[x])
for x in ['train', 'val']}
dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=32, shuffle=True, num_workers=4)
for x in ['train', 'val']}
dataset_sizes = {x: len(image_datasets[x]) for x in ['train', 'val']}
class_names = image_datasets['train'].classes
# প্রি-ট্রেইনড ResNet18 মডেল লোড করা
model = models.resnet18(pretrained=True)
# লাস্ট লেয়ার পরিবর্তন করা যাতে এটি আমাদের ক্লাস নম্বরের সাথে মিলায় (এখানে ২টি ক্লাস: Cat এবং Dog)
num_ftrs = model.fc.in_features
model.fc = nn.Linear(num_ftrs, len(class_names))
# মডেলকে GPU তে স্থানান্তর করা
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model = model.to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)
num_epochs = 10
for epoch in range(num_epochs):
print(f'Epoch {epoch+1}/{num_epochs}')
print('-' * 10)
# প্রতিটি epoch এর জন্য ট্রেনিং এবং ভ্যালিডেশন লুপ
for phase in ['train', 'val']:
if phase == 'train':
model.train() # মডেলকে ট্রেনিং মোডে সেট করা
else:
model.eval() # মডেলকে ইভ্যালুয়েশন মোডে সেট করা
running_loss = 0.0
running_corrects = 0
for inputs, labels in dataloaders[phase]:
inputs = inputs.to(device)
labels = labels.to(device)
optimizer.zero_grad() # গ্রেডিয়েন্ট রিসেট করা
with torch.set_grad_enabled(phase == 'train'):
outputs = model(inputs)
_, preds = torch.max(outputs, 1)
loss = criterion(outputs, labels)
if phase == 'train':
loss.backward()
optimizer.step()
running_loss += loss.item() * inputs.size(0)
running_corrects += torch.sum(preds == labels.data)
epoch_loss = running_loss / dataset_sizes[phase]
epoch_acc = running_corrects.double() / dataset_sizes[phase]
print(f'{phase} Loss: {epoch_loss:.4f} Acc: {epoch_acc:.4f}')
print('Training complete')
torch.save(model.state_dict(), 'finetuned_resnet18.pth')
এভাবে Transfer Learning PyTorch-এ সহজে প্রয়োগ করা যায় এবং এটি সময় বাঁচাতে এবং মডেল পারফর্ম্যান্স উন্নত করতে সহায়ক।
Pre-trained মডেল ব্যবহার করে Custom মডেল তৈরি করা একটি জনপ্রিয় কৌশল যা Transfer Learning নামে পরিচিত। PyTorch-এ Transfer Learning করতে আমরা একটি প্রি-ট্রেইনড মডেল ব্যবহার করি এবং তার উপর ভিত্তি করে নতুন একটি মডেল তৈরি করি। এই পদ্ধতিতে মডেলটি দ্রুত ট্রেনিং হয় এবং সাধারণত ভালো পারফরমেন্স প্রদান করে। নিচে উদাহরণসহ ব্যাখ্যা করা হয়েছে কীভাবে প্রি-ট্রেইনড মডেল ব্যবহার করে Custom মডেল তৈরি করা যায়।
আমরা ResNet18 মডেল ব্যবহার করবো, যা ImageNet ডেটাসেটে প্রি-ট্রেইন করা হয়েছে। আমরা এই মডেলের শেষ লেয়ারগুলো কাস্টমাইজ করবো, যাতে এটি আমাদের ডেটাসেট অনুযায়ী কাজ করতে পারে।
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
from torchvision import models
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print(f'Using device: {device}')
আমরা একটি কাস্টম ডেটাসেট ব্যবহার করবো (এখানে উদাহরণ হিসেবে CIFAR-10 ডেটাসেট নেওয়া হয়েছে):
transform = transforms.Compose([
transforms.Resize((224, 224)), # প্রি-ট্রেইনড মডেল অনুযায়ী ইমেজ রিসাইজ করা
transforms.ToTensor(),
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])
train_dataset = torchvision.datasets.CIFAR10(root='./data', train=True, transform=transform, download=True)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True)
test_dataset = torchvision.datasets.CIFAR10(root='./data', train=False, transform=transform, download=True)
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=64, shuffle=False)
# ResNet18 প্রি-ট্রেইনড মডেল লোড করা
model = models.resnet18(pretrained=True)
# ফিচার লেয়ারগুলো ফ্রিজ করা (যাতে তারা ট্রেনিং না হয়)
for param in model.parameters():
param.requires_grad = False
# মডেলের শেষ লেয়ার কাস্টমাইজ করা
num_features = model.fc.in_features
model.fc = nn.Linear(num_features, 10) # CIFAR-10 এর জন্য ১০টি আউটপুট ক্লাস
# মডেলকে GPU তে স্থানান্তর করা
model = model.to(device)
criterion = nn.CrossEntropyLoss()
# শুধুমাত্র শেষ লেয়ার (classifier) ট্রেনিং হবে
optimizer = optim.Adam(model.fc.parameters(), lr=0.001)
def train_model(model, train_loader, criterion, optimizer, device, num_epochs=5):
model.train()
for epoch in range(num_epochs):
running_loss = 0.0
for images, labels in train_loader:
images, labels = images.to(device), labels.to(device)
outputs = model(images)
loss = criterion(outputs, labels)
optimizer.zero_grad()
loss.backward()
optimizer.step()
running_loss += loss.item()
print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {running_loss / len(train_loader):.4f}')
# মডেল ট্রেনিং চালানো
train_model(model, train_loader, criterion, optimizer, device)
def validate_model(model, test_loader, criterion, device):
model.eval()
correct = 0
total = 0
val_loss = 0.0
with torch.no_grad():
for images, labels in test_loader:
images, labels = images.to(device), labels.to(device)
outputs = model(images)
loss = criterion(outputs, labels)
val_loss += loss.item()
_, predicted = torch.max(outputs, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
accuracy = 100 * correct / total
print(f'Validation Loss: {val_loss / len(test_loader):.4f}, Accuracy: {accuracy:.2f}%')
# মডেল ভ্যালিডেশন চালানো
validate_model(model, test_loader, criterion, device)
torch.save(model.state_dict(), 'custom_resnet18_cifar10.pth')
# মডেলের নতুন ইনস্ট্যান্স তৈরি এবং GPU তে স্থানান্তর করা
loaded_model = models.resnet18(pretrained=False)
loaded_model.fc = nn.Linear(num_features, 10)
loaded_model.load_state_dict(torch.load('custom_resnet18_cifar10.pth'))
loaded_model = loaded_model.to(device)
loaded_model.eval()
models.resnet18(pretrained=True)
ব্যবহার করে ResNet18 লোড করা হয়েছে।Pre-trained মডেল ব্যবহার করে Custom মডেল তৈরি করলে মডেল দ্রুত ট্রেনিং হয় এবং কম ডেটাসেটেও ভালো পারফরমেন্স পাওয়া যায়। Transfer Learning ব্যবহার করে আপনি সহজেই Image Classification, Object Detection, বা অন্যান্য কাজের জন্য কাস্টম মডেল তৈরি করতে পারেন।
Read more