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).
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" ..
Sehen wir uns den Lernfluss mit CIFAR-10 an. Das Erlernen der Klassifizierung von Bildern umfasst die folgenden Schritte nacheinander:
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
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()
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)
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
Ü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
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.
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.
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.
29.04.2020 Erstausgabe veröffentlicht
Recommended Posts