Newer
Older
import torch
from torch import nn, optim
from torchvision import datasets, transforms, models
from torch.utils.data import DataLoader, random_split
import sklearn
from sklearn.metrics import accuracy_score
from sklearn.metrics import confusion_matrix, classification_report
import numpy as np
if __name__ == '__main__':
# Pfad zu den Daten
data_dir = 'data1' # Passe den Pfad zu deinem Datensatz an
# Definition von Daten-Transformationen
data_transform = transforms.Compose([
transforms.RandomResizedCrop(224),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])
# Laden der Daten
image_dataset = datasets.ImageFolder(root=data_dir, transform=data_transform)
# Aufteilung der Daten in Trainings-, Validierungs- und Testdaten
train_size = int(0.8 * len(image_dataset))
val_size = test_size = (len(image_dataset) - train_size) // 2
train_dataset, val_dataset, labels = random_split(image_dataset, [train_size, val_size, test_size])
# Definition der DataLoaders
train_loader = DataLoader(train_dataset, batch_size=4, shuffle=True, num_workers=4)
val_loader = DataLoader(val_dataset, batch_size=4, shuffle=False, num_workers=4)
test_loader = DataLoader(labels, batch_size=4, shuffle=False, num_workers=4)
# Verwendung eines vortrainierten ResNet-Modells
model = models.resnet18(weights=models.ResNet18_Weights.IMAGENET1K_V1)
# Anpassung des Klassifikationslayers für die Anzahl der Klassen in deinem Datensatz
num_classes = len(image_dataset.classes)
model.fc = nn.Linear(model.fc.in_features, num_classes)
# Definition der Verlustfunktion und des Optimierers
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)
# Überprüfe, ob CUDA verfügbar ist, und weise das entsprechende Gerät zu
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model.to(device)
# Training des Modells
num_epochs = 3 # Anpassen der Anzahl der Epochen nach Bedarf
for epoch in range(num_epochs):
for phase in ['train', 'val']:
if phase == 'train':
model.train()
data_loader = train_loader
else:
model.eval()
data_loader = val_loader if phase == 'val' else test_loader
for inputs, labels in data_loader:
inputs, labels = inputs.to(device), labels.to(device)
optimizer.zero_grad()
with torch.set_grad_enabled(phase == 'train'):
outputs = model(inputs)
loss = criterion(outputs, labels)
if phase == 'train':
loss.backward()
optimizer.step()
_, predictions = torch.max(outputs, 1)
running_loss += loss.item() * inputs.size(0)
running_corrects += torch.sum(predictions == labels.data)
epoch_loss = running_loss / len(data_loader.dataset)
epoch_acc = running_corrects.double() / len(data_loader.dataset)
print(f'{phase} Loss: {epoch_loss:.4f} Acc: {epoch_acc:.4f}')
def get_predictions(model, data_loader, device):
model.eval()
all_predictions = []
all_labels = []
with torch.no_grad():
for inputs, labels in data_loader:
inputs = inputs.to(device)
labels = labels.to(device)
_, predictions = torch.max(outputs, 1)
all_predictions.extend(predictions.cpu().numpy())
all_labels.extend(labels.cpu().numpy())
return np.array(all_predictions), np.array(all_labels)
predictions, labels = get_predictions(model, test_loader, device)
cm = sklearn.metrics.confusion_matrix(labels, predictions)
ps = sklearn.metrics.precision_score(labels, predictions, average=None)
f1 = sklearn.metrics.f1_score(labels, predictions, average=None)
rc = sklearn.metrics.recall_score(labels, predictions, average=None)
print('confusion matrix:', cm , "\n \n",
'precision:', ps ,"\n \n",
'f1:', f1 , "\n \n",
'recall:', rc , "\n \n")
cmd = sklearn.metrics.ConfusionMatrixDisplay(cm, display_labels=["Apple_scab",
"Apple_Black_rot",
])