Pytorch-Tutorial (Code Zeile für Zeile erklärt)

0. Tutorial zur Registrierungsumgebung

1. Beginnen Sie mit dem Import der entsprechenden Pakete

import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets
from torchvision.transforms import ToTensor

Torch ist die Abkürzung für Pytorch.
Torch.utils.data import DataLoader ist ein Iterator zum Lesen von Daten.
Torchvision ist ein visuelles Verarbeitungspaket. Datasets importiert visionbezogene Datensätze.
Transforms wird für die Bildtransformation verwendet.

2. Laden Sie den Datensatz herunter (bereiten Sie den Datensatz vor)

# Download training data from open datasets.
training_data = datasets.FashionMNIST(
    root="data",
    train=True,
    download=True,
    transform=ToTensor(),
)

# Download test data from open datasets.
test_data = datasets.FashionMNIST(
    root="data",
    train=False,
    download=True,
    transform=ToTensor(),
)

datasets.FashionMNIST bezieht sich auf einen Datensatz, der zur Kleidungserkennung verwendet wird. FashionMNIST ist ein sehr beliebter Bildklassifizierungsdatensatz, der 70.000 28x28-Graustufenbilder in 10 Kategorien enthält.
Natürlich verfügt Pytorch über viele andere Datensatzformate. Zum Beispiel der folgende Datensatz. Für andere Datensätze klicken Sie bitte auf diesen LinkFügen Sie hier eine Bildbeschreibung ein

3. Laden Sie den Datensatz

batch_size = 64

# Create data loaders.
train_dataloader = DataLoader(training_data, batch_size=batch_size)
test_dataloader = DataLoader(test_data, batch_size=batch_size)

for X, y in test_dataloader:
    print(f"Shape of X [N, C, H, W]: {
      
      X.shape}")
    print(f"Shape of y: {
      
      y.shape} {
      
      y.dtype}")
    break

DataLoader ist ein sehr nützliches Modul in PyTorch. Es wird hauptsächlich zum stapelweisen Laden von Daten verwendet. Insbesondere wenn der Datensatz sehr groß ist, kann DataLoader die Datenladegeschwindigkeit erheblich verbessern und die Speichernutzung reduzieren.
Zu den Hauptfunktionen von DataLoader gehören:
Stapelverarbeitung von Daten: DataLoader kann Daten in mehrere Stapel aufteilen, wobei jeder Stapel eine bestimmte Anzahl von Datenproben enthält, und dann jeweils einen Datenstapel verarbeiten, wodurch die Speichernutzung erheblich reduziert werden kann.
Datenmischen: Durch Festlegen des Parameters shuffle=True kann DataLoader die Reihenfolge des Datensatzes zu Beginn jeder Epoche zufällig ändern, was die Generalisierungsfähigkeit des Modells erhöhen kann.
„batch_size“ bezieht sich auf die Größe der jedes Mal gelesenen Daten. Hier ist es so eingestellt, dass 64 Bilder gleichzeitig gelesen werden.

4. Erstellen Sie ein trainiertes Modell

# Get cpu, gpu or mps device for training.
device = (
    "cuda"
    if torch.cuda.is_available()
    else "mps"
    if torch.backends.mps.is_available()
    else "cpu"
)
print(f"Using {
      
      device} device")

# Define model
class NeuralNetwork(nn.Module):
    def __init__(self):
        super().__init__()
        self.flatten = nn.Flatten()
        self.linear_relu_stack = nn.Sequential(
            nn.Linear(28*28, 512),
            nn.ReLU(),
            nn.Linear(512, 512),
            nn.ReLU(),
            nn.Linear(512, 10)
        )

    def forward(self, x):
        x = self.flatten(x)
        logits = self.linear_relu_stack(x)
        return logits

model = NeuralNetwork().to(device)
print(model)

super(). init () bedeutet, die init ()-Methode self.flatten = nn.Flatten() der übergeordneten Klasse (nn.Module) aufzurufen
. Die Hauptfunktion dieser Codezeile besteht darin, das neuronale Netzwerkmodell zu konvertieren Eingabedaten aus mehrdimensionalen (z. B. zwei oder drei Dimensionen) werden in eine Dimension konvertiert. Dieser Vorgang wird oft als „Flatten“ bezeichnet.
In diesem Beispiel ist die erwartete Eingabe in das Modell ein Tensor der Form [batch_size, 28, 28], also ein Datensatz, der mehrere (hier 28*28=784) Merkmalswerte enthält. Die nn.Flatten()-Schicht wandelt diese dreidimensionalen Daten in ein eindimensionales Array um, sodass nachfolgende lineare Schichten (nn.Linear) effizienter arbeiten können.

nn.Sequential ist ein Modul in PyTorch zum Erstellen sequentieller neuronaler Netzwerkmodelle. Es handelt sich um einen geordneten Container, der beliebig viele weitere Module enthalten kann. Wenn Sie Daten in das nn.Sequential-Modell eingeben, durchlaufen die Daten jedes Modul in der Reihenfolge, die Sie im Container definieren.

5. Stellen Sie den Optimierer und die Verlustfunktion ein

loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=1e-3)

Es gibt viele Arten von Verlustfunktionen. Für weitere Referenzen klicken Sie auf diesen Link.
Es gibt auch viele Arten von Optimierern wie ASGD, ADAM usw. Für andere Referenzen klicken Sie bitte auf diesen Link.

6. Modelltraining

Definieren Sie den Trainingsprozess

def train(dataloader, model, loss_fn, optimizer):
    size = len(dataloader.dataset)
    model.train()
    for batch, (X, y) in enumerate(dataloader):
        X, y = X.to(device), y.to(device)

        # Compute prediction error
        pred = model(X)
        loss = loss_fn(pred, y)

        # Backpropagation
        loss.backward()
        optimizer.step()
        optimizer.zero_grad()

        if batch % 100 == 0:
            loss, current = loss.item(), (batch + 1) * len(X)
            print(f"loss: {
      
      loss:>7f}  [{
      
      current:>5d}/{
      
      size:>5d}]")

Aus dem Datensatz werden jeweils ein Bild und eine Beschriftung für das Training entnommen und anschließend eine Rückausbreitung und Gradientenoptimierung durchgeführt, um das Training abzuschließen.
item(): .item() ist eine Methode zum Extrahieren eines Skalarwerts aus einem Tensor. Wenn Sie die Methode .item() aufrufen und nur ein Element im Tensor vorhanden ist, wird dieses Element zurückgegeben. Wenn der Tensor mehrere Elemente enthält, wird ein Fehler ausgegeben.

def test(dataloader, model, loss_fn):
    size = len(dataloader.dataset)
    num_batches = len(dataloader)
    model.eval()
    test_loss, correct = 0, 0
    with torch.no_grad():
        for X, y in dataloader:
            X, y = X.to(device), y.to(device)
            pred = model(X)
            test_loss += loss_fn(pred, y).item()
            correct += (pred.argmax(1) == y).type(torch.float).sum().item()
    test_loss /= num_batches
    correct /= size
    print(f"Test Error: \n Accuracy: {
      
      (100*correct):>0.1f}%, Avg loss: {
      
      test_loss:>8f} \n")

richtig += (pred.argmax(1) == y).type(torch.float).sum().item(): Erläuterung:
(pred.argmax(1) == y): Zuerst diese Codezeile Übergibt argmax(1) und erhält die vorhergesagte Kategorie jeder Stichprobe. Dann vergleicht es die vorhergesagte Klasse mit der wahren Klasse (==). Dies gibt einen booleschen Tensor zurück, der angibt, ob die Vorhersage für jede Stichprobe korrekt war.
(pred.argmax(1) == y).type(torch.float): Als nächstes konvertiert diese Codezeile den booleschen Tensor in Float. In PyTorch werden boolesche Tensoren automatisch in Gleitkommatypen konvertiert.
(pred.argmax(1) == y).type(torch.float).sum(): Diese Codezeile zählt dann die Gesamtzahl der korrekten Vorhersagen über alle Stichproben hinweg. Dies wird durch den Aufruf der Funktion sum() erreicht, die die Summe aller Elemente in einem Tensor zurückgibt.
richtig += …: Schließlich addiert diese Codezeile die Gesamtzahl der richtigen Vorhersagen zur Variablen richtig. += ist ein Akkumulationsoperator, der die Variable links zum Ausdrucksergebnis rechts hinzufügt.

7. Definieren Sie Trainingsrunden

epochs = 5
for t in range(epochs):
    print(f"Epoch {
      
      t+1}\n-------------------------------")
    train(train_dataloader, model, loss_fn, optimizer)
    test(test_dataloader, model, loss_fn)
print("Done!")

8. Speichern Sie das Modell

torch.save(model.state_dict(), "model.pth")
print("Saved PyTorch Model State to model.pth")

model.state_dict(): Erläuterung:
Die Funktion model.state_dict() gibt ein Wörterbuch zurück, das alle Parameter des Modells enthält, und die Funktion Torch.save() speichert dieses Wörterbuch in einer Datei auf der Festplatte.

9. Laden Sie das Modell

model = NeuralNetwork().to(device)
model.load_state_dict(torch.load("model.pth"))

10. Modelltests

classes = [
    "T-shirt/top",
    "Trouser",
    "Pullover",
    "Dress",
    "Coat",
    "Sandal",
    "Shirt",
    "Sneaker",
    "Bag",
    "Ankle boot",
]

model.eval()
x, y = test_data[0][0], test_data[0][1]
with torch.no_grad():
    x = x.to(device)
    pred = model(x)
    predicted, actual = classes[pred[0].argmax(0)], classes[y]
    print(f'Predicted: "{
      
      predicted}", Actual: "{
      
      actual}"')

Kompletter Code:

import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets
from torchvision.transforms import ToTensor

# Download training data from open datasets.
training_data = datasets.FashionMNIST(
    root="data",
    train=True,
    download=True,
    transform=ToTensor(),
)

# Download test data from open datasets.
test_data = datasets.FashionMNIST(
    root="data",
    train=False,
    download=True,
    transform=ToTensor(),
)

batch_size = 64

# Create data loaders.
train_dataloader = DataLoader(training_data, batch_size=batch_size)
test_dataloader = DataLoader(test_data, batch_size=batch_size)

for X, y in test_dataloader:
    print(f"Shape of X [N, C, H, W]: {
      
      X.shape}")
    print(f"Shape of y: {
      
      y.shape} {
      
      y.dtype}")
    break

# Get cpu, gpu or mps device for training.
device = (
    "cuda"
    if torch.cuda.is_available()
    else "mps"
    if torch.backends.mps.is_available()
    else "cpu"
)
print(f"Using {
      
      device} device")

# Define model
class NeuralNetwork(nn.Module):
    def __init__(self):
        super().__init__()
        self.flatten = nn.Flatten()
        self.linear_relu_stack = nn.Sequential(
            nn.Linear(28*28, 512),
            nn.ReLU(),
            nn.Linear(512, 512),
            nn.ReLU(),
            nn.Linear(512, 10)
        )

    def forward(self, x):
        x = self.flatten(x)
        logits = self.linear_relu_stack(x)
        return logits

model = NeuralNetwork().to(device)
print(model)

loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=1e-3)

def train(dataloader, model, loss_fn, optimizer):
    size = len(dataloader.dataset)
    model.train()
    for batch, (X, y) in enumerate(dataloader):
        X, y = X.to(device), y.to(device)

        # Compute prediction error
        pred = model(X)
        loss = loss_fn(pred, y)

        # Backpropagation
        loss.backward()
        optimizer.step()
        optimizer.zero_grad()

        if batch % 100 == 0:
            loss, current = loss.item(), (batch + 1) * len(X)
            print(f"loss: {
      
      loss:>7f}  [{
      
      current:>5d}/{
      
      size:>5d}]")

def test(dataloader, model, loss_fn):
    size = len(dataloader.dataset)
    num_batches = len(dataloader)
    model.eval()
    test_loss, correct = 0, 0
    with torch.no_grad():
        for X, y in dataloader:
            X, y = X.to(device), y.to(device)
            pred = model(X)
            test_loss += loss_fn(pred, y).item()
            correct += (pred.argmax(1) == y).type(torch.float).sum().item()
    test_loss /= num_batches
    correct /= size
    print(f"Test Error: \n Accuracy: {
      
      (100*correct):>0.1f}%, Avg loss: {
      
      test_loss:>8f} \n")

epochs = 5
for t in range(epochs):
    print(f"Epoch {
      
      t+1}\n-------------------------------")
    train(train_dataloader, model, loss_fn, optimizer)
    test(test_dataloader, model, loss_fn)
print("Done!")

Supongo que te gusta

Origin blog.csdn.net/weixin_49321128/article/details/134407907
Recomendado
Clasificación