|
import os |
|
import torch |
|
import torch.nn as nn |
|
import torch.optim as optim |
|
import torchvision.transforms as transforms |
|
import torchvision.datasets as datasets |
|
from torch.utils.data import DataLoader |
|
from torchvision import models |
|
from tqdm import tqdm |
|
|
|
|
|
train_dir = "train" |
|
test_dir = "dataset/test" |
|
|
|
|
|
transform = transforms.Compose([ |
|
transforms.Resize((128, 128)), |
|
transforms.RandomHorizontalFlip(), |
|
transforms.ToTensor(), |
|
transforms.Normalize([0.5], [0.5]) |
|
]) |
|
|
|
|
|
train_dataset = datasets.ImageFolder(root=train_dir, transform=transform) |
|
test_dataset = datasets.ImageFolder(root=test_dir, transform=transform) |
|
|
|
|
|
class_names = train_dataset.classes |
|
print(f"Class Names: {class_names}") |
|
|
|
|
|
with open("class_names.txt", "w") as f: |
|
for name in class_names: |
|
f.write(name + "\n") |
|
|
|
|
|
batch_size = 16 |
|
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True) |
|
test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False) |
|
|
|
|
|
device = torch.device("cuda" if torch.cuda.is_available() else "cpu") |
|
model = models.mobilenet_v2(pretrained=True) |
|
model.classifier[1] = nn.Linear(model.classifier[1].in_features, len(class_names)) |
|
model = model.to(device) |
|
|
|
|
|
criterion = nn.CrossEntropyLoss() |
|
optimizer = optim.Adam(model.parameters(), lr=0.001) |
|
|
|
|
|
num_epochs = 3 |
|
for epoch in range(num_epochs): |
|
model.train() |
|
running_loss = 0.0 |
|
progress_bar = tqdm(train_loader, desc=f"Epoch {epoch+1}/{num_epochs}", leave=False) |
|
|
|
for images, labels in progress_bar: |
|
images, labels = images.to(device), labels.to(device) |
|
|
|
optimizer.zero_grad() |
|
outputs = model(images) |
|
loss = criterion(outputs, labels) |
|
loss.backward() |
|
optimizer.step() |
|
|
|
running_loss += loss.item() |
|
progress_bar.set_postfix(loss=f"{running_loss/len(train_loader):.4f}") |
|
|
|
print(f"β
Epoch [{epoch+1}/{num_epochs}] - Loss: {running_loss/len(train_loader):.4f}") |
|
|
|
|
|
torch.save(model.state_dict(), "plant_disease_model.pth") |
|
print("β
Model training complete and saved as plant_disease_model.pth") |
|
|
|
|
|
|
|
print("π Running model on test dataset to save predictions...") |
|
|
|
y_true = [] |
|
y_pred = [] |
|
|
|
model.eval() |
|
with torch.no_grad(): |
|
for images, labels in tqdm(test_loader, desc="Evaluating"): |
|
images, labels = images.to(device), labels.to(device) |
|
|
|
outputs = model(images) |
|
preds = torch.argmax(outputs, dim=1) |
|
|
|
y_true.extend(labels.cpu().numpy()) |
|
y_pred.extend(preds.cpu().numpy()) |
|
|
|
|
|
torch.save(y_true, "y_true.pth") |
|
torch.save(y_pred, "y_pred.pth") |
|
print("β
Test labels (y_true.pth) and predictions (y_pred.pth) saved successfully.") |
|
|