Skip to content
Snippets Groups Projects
NN.py 4.56 KiB
Newer Older
s87425's avatar
s87425 committed
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
s87425's avatar
s87425 committed

s87425's avatar
s87425 committed
import matplotlib.pyplot as plt
s87425's avatar
s87425 committed


s87425's avatar
s87425 committed
if __name__ == '__main__':  
# Pfad zu den Daten
    data_dir = 'data1'  # Passe den Pfad zu deinem Datensatz an
s87425's avatar
s87425 committed

s87425's avatar
s87425 committed
# 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])
    ])
s87425's avatar
s87425 committed

s87425's avatar
s87425 committed
    # Laden der Daten
    image_dataset = datasets.ImageFolder(root=data_dir, transform=data_transform)
s87425's avatar
s87425 committed

s87425's avatar
s87425 committed
    # 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])
s87425's avatar
s87425 committed

s87425's avatar
s87425 committed
    # 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)
s87425's avatar
s87425 committed

s87425's avatar
s87425 committed
    # Verwendung eines vortrainierten ResNet-Modells
    model = models.resnet18(weights=models.ResNet18_Weights.IMAGENET1K_V1)
s87425's avatar
s87425 committed

s87425's avatar
s87425 committed
    # 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)
s87425's avatar
s87425 committed

s87425's avatar
s87425 committed
    # Definition der Verlustfunktion und des Optimierers
    criterion = nn.CrossEntropyLoss()
    optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)
s87425's avatar
s87425 committed

s87425's avatar
s87425 committed
    # Ü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)
s87425's avatar
s87425 committed

s87425's avatar
s87425 committed
    # Training des Modells
    num_epochs = 3  # Anpassen der Anzahl der Epochen nach Bedarf
s87425's avatar
s87425 committed

s87425's avatar
s87425 committed
    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
s87425's avatar
s87425 committed

s87425's avatar
s87425 committed
            running_loss = 0.0
            running_corrects = 0
s87425's avatar
s87425 committed

s87425's avatar
s87425 committed
            for inputs, labels in data_loader:
                inputs, labels = inputs.to(device), labels.to(device)
                optimizer.zero_grad()
s87425's avatar
s87425 committed

s87425's avatar
s87425 committed
                with torch.set_grad_enabled(phase == 'train'):
                    outputs = model(inputs)
                    loss = criterion(outputs, labels)
s87425's avatar
s87425 committed

s87425's avatar
s87425 committed
                    if phase == 'train':
                        loss.backward()
                        optimizer.step()
s87425's avatar
s87425 committed

s87425's avatar
s87425 committed
                _, predictions = torch.max(outputs, 1)
                running_loss += loss.item() * inputs.size(0)
                running_corrects += torch.sum(predictions == labels.data)
s87425's avatar
s87425 committed

s87425's avatar
s87425 committed
            epoch_loss = running_loss / len(data_loader.dataset)
            epoch_acc = running_corrects.double() / len(data_loader.dataset)
s87425's avatar
s87425 committed

s87425's avatar
s87425 committed
            print(f'{phase} Loss: {epoch_loss:.4f} Acc: {epoch_acc:.4f}')
s87425's avatar
s87425 committed


s87425's avatar
s87425 committed
    print("Training abgeschlossen.")
s87425's avatar
s87425 committed

s87425's avatar
s87425 committed
    def get_predictions(model, data_loader, device):
        model.eval()
        all_predictions = []
        all_labels = []
s87425's avatar
s87425 committed

s87425's avatar
s87425 committed
        with torch.no_grad():
            for inputs, labels in data_loader:
                inputs = inputs.to(device)
                labels = labels.to(device)
s87425's avatar
s87425 committed
                outputs = model(inputs)
s87425's avatar
s87425 committed
                _, 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)
s87425's avatar
s87425 committed

s87425's avatar
s87425 committed
    f1 = sklearn.metrics.f1_score(labels, predictions, average=None)
s87425's avatar
s87425 committed

s87425's avatar
s87425 committed
    rc = sklearn.metrics.recall_score(labels, predictions, average=None)
s87425's avatar
s87425 committed

s87425's avatar
s87425 committed
    print('confusion matrix:', cm , "\n \n", 
        'precision:', ps ,"\n \n",
            'f1:', f1 , "\n \n",
            'recall:', rc , "\n \n")
s87425's avatar
s87425 committed
    cmd = sklearn.metrics.ConfusionMatrixDisplay(cm, display_labels=["Apple_scab",
        "Apple_Black_rot",
               ])
s87425's avatar
s87425 committed
    cmd.plot()
    plt.show()