[PYTHON] [PyTorch Tutorial ④] AUSBILDUNG EINES KLASSIFIERERS

Einführung

Dies ist die vierte Ausgabe von PyTorch Official Tutorial nach Last time. Dieses Mal fahren wir mit [TRAINING A CLASSIFIER] fort (https://pytorch.org/tutorials/beginner/blitz/cifar10_tutorial.html).

Klassifizierung der Lernklasse

Letztes Mal hat gezeigt, wie ein neuronales Netzwerk definiert wird, um Verluste zu berechnen und Netzwerkgewichte zu aktualisieren. Dieses Mal werden wir das Klassifizierungsproblem anhand von Bilddaten untersuchen. PyTorch bietet eine Bibliotheks-Taschenlampe für den Umgang mit Bilddaten. torchvision ist auch mit grundlegenden Bilddatensätzen wie Imagenet, CIFAR-10 und MNIST vorinstalliert. In diesem Lernprogramm wird der CIFAR-10-Datensatz verwendet.

CIFAR-10

Der CIFAR-10 ist ein 32 x 32 Pixel großes Farbbild mit 3 RGB-Kanälen in der Form (3,32,32). Die Klassen sind in 10 Kategorien unterteilt: "Flugzeug", "Auto", "Vogel", "Katze", "Hirsch", "Hund", "Frosch", "Pferd", "Schiff", "LKW" ..

cifar10.png

Bildklassifizierung lernen

Sehen wir uns den Lernfluss mit CIFAR-10 an. Das Erlernen der Klassifizierung von Bildern umfasst die folgenden Schritte nacheinander:

  1. Verwenden Sie Torchvision, um den CIFAR10-Trainings- und Testdatensatz zu laden und zu normalisieren
  2. Definition des Faltungsnetzwerks
  3. Definieren Sie die Verlustfunktion und den Optimierungsalgorithmus
  4. Lernen Sie mit Trainingsdaten
  5. Überprüfen Sie das mit den Testdaten erlernte Ergebnis

1. Laden und Normalisieren von CIFAR-10

Es ist praktisch, ** Dataset ** und ** DataLoader ** zu verwenden, um Daten mit PyTorch zu laden. Der Datensatz enthält das Bild und das richtige Antwortetikett (eine Trainingsdaten). DataLoader Ein Dienstprogramm zum wiederholten Erfassen von Trainingsdaten (Testdaten).

import torch
import torchvision
import torchvision.transforms as transforms

#Definition der Transformation
#Mit ToTensor in Tensor konvertieren
#Standardisierung( X - 0.5) / 0.5 
transform = transforms.Compose([
     transforms.ToTensor(),
     transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])

#Trainingsdatensatz
trainset = torchvision.datasets.CIFAR10(root='./data', train=True,
                                        download=True, transform=transform)

#Trainingsdatenlader
trainloader = torch.utils.data.DataLoader(trainset, batch_size=4,
                                          shuffle=False, num_workers=2)

#Datensatz testen
testset = torchvision.datasets.CIFAR10(root='./data', train=False,
                                       download=True, transform=transform)

#Testen Sie den Datenlader
testloader = torch.utils.data.DataLoader(testset, batch_size=4,
                                         shuffle=False, num_workers=2)

#Liste der Klassifikationen
classes = ('plane', 'car', 'bird', 'cat',
           'deer', 'dog', 'frog', 'horse', 'ship', 'truck')

Zunächst legt transform die Konvertierungsmethode des Datasets fest. Compose verbindet mehrere Transformationen nacheinander. Hier führen wir ToTensor und Normalize aus. ToTensor konvertiert die Bilddaten in Tensor. In ToTensor werden RGB-Werte durch den Fload-Typ [0, 1] dargestellt. Normalize berechnet (X - 0,5) / 0,5 und konvertiert den RGB-Bereich in [-1, 1].

Einige Bilder werden mit dem folgenden Code angezeigt. Da die Batch-Größe des Trainloaders 4 beträgt, werden 4 Bilder zusammen verarbeitet.

import matplotlib.pyplot as plt
import numpy as np

#Funktion zum Anzeigen eines Bildes
def imshow(img):
    img = img / 2 + 0.5     #Standardisierung rückgängig machen
    npimg = img.numpy()
    plt.imshow(np.transpose(npimg, (1, 2, 0)))


#Holen Sie sich Bilder aus Trainingsdaten (zufällig)
dataiter = iter(trainloader)
images, labels = dataiter.next()

#Bild anzeigen
imshow(torchvision.utils.make_grid(images))
#Etikett anzeigen
print(' '.join('%5s' % classes[labels[j]] for j in range(4)))

frog truck truck deer imshow.png

2. Definition des Faltungsnetzwerks

Kopieren Sie das neuronale Netzwerk aus dem vorherigen Lernprogramm für neuronale Netzwerke und ändern Sie es, um ein 3-Kanal-Bild (anstelle des definierten 1-Kanal-Bildes) zu erhalten.

import torch.nn as nn
import torch.nn.functional as F


class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(3, 6, 5)
        self.pool = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.fc1 = nn.Linear(16 * 5 * 5, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = x.view(-1, 16 * 5 * 5)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

net = Net()

3. Definieren Sie die Verlustfunktion und den Optimierungsalgorithmus

Bei Klassifizierungsproblemen verwendet die Verlustfunktion hauptsächlich die Kreuzentropiefehlerfunktion. Bei Problemen mit der binären Klassifizierung torch.nn.BCEWithLogitsLoss Bei Problemen mit der Klassifizierung mehrerer Klassen torch.nn.CrossEntropyLoss Wird oft verwendet. Dieses Mal gibt es 10 Etikettenklassifizierungen (Mehrklassenklassifizierung), daher verwenden wir CrossEntropyLoss. Der Optimierungsalgorithmus sollte die grundlegendste "probabilistische Gradientenabstiegsmethode" (SGD) sein.

import torch.optim as optim

criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)

4. Lernen Sie mit Trainingsdaten

Durchlaufen Sie den Datenlader und streamen Sie Trainingsdaten über das Netzwerk, um die Parameter zu optimieren.

for epoch in range(2):  #Epoche mehrmals Schleife

    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):
        #Trainingsdaten abrufen
        inputs, labels = data

        #Initialisieren Sie den Farbverlauf
        optimizer.zero_grad()

        #Leiten Sie Daten durch ein neuronales Netzwerk und berechnen Sie die Vorwärtsausbreitung
        outputs = net(inputs)
        #Fehlerberechnung
        loss = criterion(outputs, labels)
        #Backpropagation-Berechnung
        loss.backward()
        #Gewichtsberechnung
        optimizer.step()

        #Status anzeigen
        running_loss += loss.item()
        if i % 2000 == 1999:    # 2,Jeweils 000 Daten
            print('[%d, %5d] loss: %.3f' %
                  (epoch + 1, i + 1, running_loss / 2000))
            running_loss = 0.0

print('Finished Training')

Das Lernen wird in ca. 2 Minuten abgeschlossen sein.

[1,  2000] loss: 2.153
[1,  4000] loss: 1.830
[1,  6000] loss: 1.654
[1,  8000] loss: 1.556
[1, 10000] loss: 1.524
[1, 12000] loss: 1.511
[2,  2000] loss: 1.441
[2,  4000] loss: 1.380
[2,  6000] loss: 1.384
[2,  8000] loss: 1.358
[2, 10000] loss: 1.335
[2, 12000] loss: 1.320
Finished Training

5. Überprüfen Sie die aus den Testdaten gewonnenen Ergebnisse

Überprüfen Sie das gelernte Ergebnis mit den Testdaten. Schauen wir uns einige der Testdaten an.

dataiter = iter(testloader)
images, labels = dataiter.next()

# print images
imshow(torchvision.utils.make_grid(images))
print('Lehrerdaten: ', ' '.join('%5s' % classes[labels[j]] for j in range(4)))

Lehrerdaten: Katzenschiff Schiffsflugzeug imshow.png

Mal sehen, wie das Modell (Klassifikator), das diese vier Bilder trainiert hat, beurteilt. Übergeben Sie die Testdaten an das trainierte Netzwerk und Sie erhalten die Ergebnisse.

outputs = net(images)
print(outputs[0,:])
tensor([-1.0291, -3.1352,  0.5837,  3.7728, -1.3638,  3.4090,  0.4094,  0.3352,
        -0.6388, -1.4808], grad_fn=<SliceBackward>)

Das Gewicht jedes Etiketts (10 Stück) wird in der Ausgabe zurückgegeben.

_, predicted = torch.max(outputs, 1)

print('Predicted: ', ' '.join('%5s' % classes[predicted[j]]
                              for j in range(4)))

Holen Sie sich den maximalen Index mit max. Wenn Sie zwei Rückgabewerte für max angeben, wird zuerst der Index mit dem Maximalwert und dann der Index mit dem Maximalwert zurückgegeben.

Predicted:    cat  ship  ship plane

Es wurde bestätigt, dass es mit den Lehrerdaten übereinstimmt.

Lassen Sie uns das Ergebnis mit den gesamten Testdaten überprüfen.

correct = 0
total = 0
with torch.no_grad():
    for data in testloader:
        images, labels = data
        outputs = net(images)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

print('Accuracy of the network on the 10000 test images: %d %%' % (
    100 * correct / total))
Accuracy of the network on the 10000 test images: 52 %

Bei 10.000 Testdaten lag die korrekte Antwortrate bei 52%. Wenn Sie nicht gelernt haben, ist es 1/10 (10%), so dass Sie etwas lernen können, aber es ist nicht sehr genau. Schauen wir uns die richtige Antwortrate für jedes Etikett an.

class_correct = list(0. for i in range(10))
class_total = list(0. for i in range(10))
with torch.no_grad():
    for data in testloader:
        images, labels = data
        outputs = net(images)
        _, predicted = torch.max(outputs, 1)
        c = (predicted == labels).squeeze()
        for i in range(4):
            label = labels[i]
            class_correct[label] += c[i].item()
            class_total[label] += 1


for i in range(10):
    print('Accuracy of %5s : %2d %%' % (
        classes[i], 100 * class_correct[i] / class_total[i]))
Accuracy of plane : 65 %
Accuracy of   car : 51 %
Accuracy of  bird : 33 %
Accuracy of   cat : 22 %
Accuracy of  deer : 39 %
Accuracy of   dog : 64 %
Accuracy of  frog : 66 %
Accuracy of horse : 70 %
Accuracy of  ship : 53 %
Accuracy of truck : 61 %

Es scheint, dass es Fälle wie Katze gibt, bei denen ich nicht viel gelernt habe.

Lernen auf der GPU

Schauen wir uns zum Schluss das Lernen auf der GPU an. Wenn Sie eine GPU-fähige Umgebung haben, können Sie damit Ihr neuronales Netzwerk trainieren. Wenn Sie Google Colaboratory verwenden, können Sie die GPU verwenden, indem Sie "Laufzeit" ⇒ "Laufzeittyp ändern" ⇒ "GPU" auswählen.

Sie können die GPU-Nutzung mit dem folgenden Code überprüfen.

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
# Assume that we are on a CUDA machine, then this should print a CUDA device:
print(device)

Wenn das Gerät "cuda" ist, können Sie die GPU verwenden. Wenn Sie eine GPU verwenden, müssen Sie Code schreiben, um das Modell auf die GPU zu übertragen.

net.to(device)

Ebenso müssen die Trainingsdaten an die GPU übertragen werden.

inputs, labels = inputs.to(device), labels.to(device)

Ich habe die Zeit überprüft, die zum Studium dieses Tutorials in Google Colaboratory benötigt wurde Wenn Sie keine GPU verwenden: 2 Minuten 10 Sekunden Bei Verwendung der GPU: 1 Minute 40 Sekunden war. Wenn die Dimensionen der Trainingsdaten nicht so komplex sind, scheint der Effekt schwach zu sein.

Am Ende

Das ist der Inhalt von PyTorchs viertem Tutorial "TRAINING A CLASSIFIER". Ich konnte den grundlegenden Lernfluss verstehen.

Das nächste Mal möchte ich mit dem fünften Tutorial "[PYTORCH MIT LERNEN MIT genau] fortfahren (https://pytorch.org/tutorials/beginner/pytorch_with_examples.html)" fortfahren.

Geschichte

29.04.2020 Erstausgabe veröffentlicht

Recommended Posts

[PyTorch Tutorial ④] AUSBILDUNG EINES KLASSIFIERERS
[PyTorch] Tutorial (japanische Version) ④ ~ TRAINING A CLASSIFIER (Bildklassifizierung) ~
[PyTorch Tutorial ①] Was ist PyTorch?
[PyTorch Tutorial ③] NEURALE NETZWERKE
[PyTorch Tutorial ⑦] Visualisieren von Modellen, Daten und Training mit Tensorboard
Lernen Sie Librosa mit einem Tutorial 1
[PyTorch] Tutorial (japanische Version) ② ~ AUTOGRAD ~
Pfeffer-Tutorial (5): Verwenden eines Tablets
[PyTorch] Tutorial (japanische Version) ① ~ Tensol ~
[PyTorch Tutorial ②] Autograd: Automatische Differenzierung
Tutorial zum neuronalen Netz von Pytorch (CNN) 1.3.1.
Machen Sie eine Santa-Kennung aus einem Santa-Bild
[PyTorch Tutorial ⑤] PyTorch anhand von Beispielen lernen (Teil 2)
[PyTorch Tutorial ⑤] PyTorch anhand von Beispielen lernen (Teil 1)
Gesichtserkennung mit einem Kaskadenklassifikator
[PyTorch Tutorial ⑥] Was ist torch.nn wirklich?