[PYTHON] [Details (?)] Einführung in Pytorch ~ CNN von CIFAR10 ~

1. Zuallererst

pytorch Eine Einführung in pytorch durch Anfänger.

Wenn Sie ein solches neues Framework verwenden, ist es meiner Meinung nach die beste Abkürzung, sich das Beispiel anzusehen und die dort verwendeten Funktionen zu googeln, das Dokument zu lesen oder damit zu spielen. Dies ist also ein Memo.

Wenn Sie versuchen, auf ähnliche Weise mit Pytorch zu beginnen, sparen Sie in diesem Artikel Zeit. (Ich bin froh, wenn du wirst.)

Im Code von cifar10-tutorial wird CNN mit CIFAR10 ausgeführt Dekodierung oder Google-Arbeit ist erledigt.

2. Vorbereitung der Umgebung

2.1. Umwelt

2.2 Installation

Die Installation von pytorch ist sehr einfach. Wenn Sie auf der offiziellen Website auf Ihre Umgebung klicken, wird der Installationscode angezeigt. In meiner Umgebung war es wie folgt.

http://pytorch.org/ Screen Shot 2017-09-06 at 22.59.46.png

pip install http://download.pytorch.org/whl/cu80/torch-0.2.0.post3-cp36-cp36m-manylinux1_x86_64.whl 
pip install torchvision

3. Laden und Aufbereiten von Daten

Schauen wir uns zunächst diesen Code an, der die Daten lädt und vorbereitet.

import torch
import torchvision
import torchvision.transforms as transforms

transform = transforms.Compose(
    [transforms.ToTensor(),
     transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])

trainset = torchvision.datasets.CIFAR10(root='./data', train=True,
                                        download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=4, shuffle=True, num_workers=2)

testset = torchvision.datasets.CIFAR10(root='./data', train=False,download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=4,shuffle=False, num_workers=2)

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

3.1 Was ist Fackelvision?

torchvision ist ein Paket für die Computer Vision von pytorch und scheint Funktionen zum Laden von Daten und zur Vorverarbeitung zu enthalten. ..

3.2 Datenaufbereitung

Verwenden Sie transforms.Compose, um die Vorverarbeitungsfunktion zu konfigurieren, die nach dem Laden der Daten ausgeführt werden soll.

Wie der Name schon sagt, ändert "ToTensor ()" den Datentyp in einen Tensor namens "torch.Tensor", der von pytorch definiert wird.

Da das Argument von "transforms.Normalize" "torch.Tensor" ist, werden die Funktionen in der Reihenfolge vom Anfang der Liste ausgeführt.

[`` transforms.Normalize ((0.5, 0.5, 0.5), (0.5, 0.5, 0.5) `](http://pytorch.org/docs/master/torchvision/transforms.html#torchvision.transforms. In Normalize) repräsentiert das erste Taple des Arguments den Durchschnitt jedes RGB-Kanals und das zweite Taple die Standardabweichung. Normalisieren Sie gemäß diesen Durchschnittswerten und Standardabweichungen.

Mit anderen Worten

transform = transforms.Compose(
    [transforms.ToTensor(),
     transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])

Jetzt haben Sie eine Funktion, die die Daten in einen Tensortyp für Pytorch umwandelt und eine Normalisierung durchführt.

3.3. Torchvision.datasets. Was ist CIFAR10?

`` `Torchvision.datasets.CIFAR10``` ist eine Klasse zum Laden von CIFAR10-Daten, wie der Name schon sagt.

Wenn download = True, speichern Sie die Daten im Stammverzeichnis.

Für MNIST und CIFAR10 sind die Datensätze bereits in Training und Test unterteilt. (Ich denke, Sie können es mischen und selbst teilen)

In CIFAR10 gibt es 60000 Bilder, von denen 50000 zum Training und 10000 zum Testen dienen. Wenn "Zug = Wahr" eingestellt ist, werden 50000 geladen, die für das Training im Voraus verwendet werden sollen, und wenn "Zug = Falsch", werden 10000 Testdaten geladen.

Wenn Sie eine Reihe von Vorverarbeitungsabläufen übergeben, die mit transforms.Compose mit dem Argument transform erstellt wurden, wird die nach dem Laden übergebene Vorverarbeitung ausgeführt.

3.4. Was ist Data Loader?

DataLoader fügt sampler in den geladenen Datensatz ein. /_modules/torch/utils/data/sampler.html) Dies ist eine Klasse, die ein Objekt zum Abtasten von Daten ist. Wenn Sie es überprüfen, ist der Sampler sicherlich angeschlossen.

trainloader.sampler
# <torch.utils.data.sampler.RandomSampler at 0x7f9099e13ef0>

Sampler hatte offenbar Zufallsstichproben, sequentielle Stichproben, gewichtete Stichproben usw. ..

Das Argument von [DataLoader] enthält einen Sampler (http://pytorch.org/docs/master/data.html#torch.utils.data.DataLoader). Wenn Sie also den hier definierten Sampler übergeben Ich habe ein gutes Gefühl, also lass es uns versuchen.

Um das Ergebnis verständlich zu machen, werden wir hier nur ein Datenelement gewichten und abtasten. Da die Anzahl der Daten gering und einfach ist, werde ich es mit Testdaten versuchen.

import numpy as np

#Erstellen Sie einen Gewichtsvektor von 1 für nur ein Bild.
weights = np.zeros(10000) #Die Anzahl der Testdaten beträgt 10000
weights[300] = 1. #300 ist geeignet
num_samples = 4 #Anzahl der Probenahmen

#Versuchen Sie WeightedRandomSampler.
my_sampler = torch.utils.data.sampler.WeightedRandomSampler(weights, num_samples, replacement=True)
my_testloader = torch.utils.data.DataLoader(testset, batch_size=4,shuffle=False, num_workers=2, sampler=my_sampler)

my_testiter = iter(my_testloader)
images, labels = my_testiter.next()

#Die imshow-Funktion wird als nächstes erklärt, aber ich werde sie etwas früher verwenden.
def imshow(img):
    img = img / 2 + 0.5     # unnormalize
    npimg = img.numpy()
    plt.imshow(np.transpose(npimg, (1, 2, 0)))

imshow(torchvision.utils.make_grid(images))

fig2.png

Oh, es ist nur ein Frosch.

3.5 Bilddarstellung

import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline

# functions to show an image
def imshow(img):
    img = img / 2 + 0.5     # unnormalize
    npimg = img.numpy()
    plt.imshow(np.transpose(npimg, (1, 2, 0)))

# get some random training images
dataiter = iter(trainloader)
images, labels = dataiter.next()

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

fig1.png

3.6. Was ist nicht normalisieren?

img = img / 2 + 0.Der Kommentar im 5. Teil enthält eine Unnormalisierung, aber ich halte die Unnormalisierung für etwas irreführend. Es wird gesagt, dass es normalisiert ist.



 Da die Eingabe von [plt.imshow](https://matplotlib.org/devdocs/api/_as_gen/matplotlib.pyplot.imshow.html) [0,1] ist, wird sie entsprechend verschoben.

## 3.7. Was ist img.numpy ()?

```python
type(img) # torch.FloatTensor

torch.Tensor ist der von Pytorch behandelte Tensortyp und wird als "Elementdatentyp + Tensor" bezeichnet. .. In diesem Fall handelt es sich, da es sich um einen Float-Tensor handelt, um einen Float, dh einen 32-Bit-Gleitkomma.

Entweder der in `` `Document``` zurückgegebene ndarray und der ursprüngliche Tensor teilen sich den gleichen Bereich. Wenn Sie es ändern, wird auch das andere geändert.

Lass es uns überprüfen.

a = torch.FloatTensor([1])
b = a.numpy()

#Ändern Sie ndarray
b[0] = 2

#Der ursprüngliche Tensor ist ebenfalls 2.
print("original tensor: ", a) # original tensor: 2
print("ndarray : ", b) # ndarray :  [ 2.]

#Es bezieht sich auf einen anderen Speicherbereich.
print(id(a)) # 140024484781832
print(id(b)) # 140024044621056

Oh, die Änderungen in ndarray spiegeln sich auch im ursprünglichen Tensor wider. Da die reservierten Speicherbereiche unterschiedlich sind, scheinen sie so zu funktionieren, als würden sie praktisch denselben Bereich gemeinsam nutzen, indem die Werte gleich bleiben.

3.8. Was ist plt.imshow (np.transpose (npimg, (1, 2, 0)))?

npimg = img.numpy()
npimg2 = np.transpose(npimg, (1, 2, 0))

print(npimg.shape) # (3, 36, 138)
print(npimg2.shape) # (36, 138, 3)

In der Dokumentation sind die Argumente für plt.imshow wie (n, m, RGB) angeordnet. Muss sein. Da npimg ursprünglich mit (RGB, vertikal, horizontal) ausgerichtet ist, wird es in der Reihenfolge des zweiten Arguments von `` `np.transpose``` sortiert.

3.9. Was ist dataiter = iter (Trainloader)?

dataiter = iter(trainloader)

print(type(trainloader))
# <class 'torch.utils.data.dataloader.DataLoader'>

print(type(dataiter))
# <class 'torch.utils.data.dataloader.DataLoaderIter'>

Der in DataLoader definierte __iter__ wird von iter () aufgerufen und gibt DataLoaderIter zurück.

Im Gegensatz zu einem normalen Iterator müssen Sie Daten in Schritten von batch_size übergeben, sodass sie anscheinend einen dedizierten Iterator definiert haben. (Code)

Infolgedessen werden jedes Mal, wenn Sie "dataiter.next ()" aufrufen, der n-te Stapel, der n + 1-Stapel und wiederholte Daten erfasst.

3.10 Was ist make_grid?

img = torchvision.utils.make_grid(images)
print(type(images)) # <class 'torch.FloatTensor'>
print(images.size) # torch.Size([4, 3, 32, 32])
print(type(img)) # <class 'torch.FloatTensor'>
print(img.size) # torch.Size([3, 36, 138])

Die Dokumentation lautet torchvision.utils.make_grid.

Die Funktion make_grid ordnet mehrere Bilder nebeneinander an. Das Argument von make_grid ist ein 4-dimensionaler Tensor, während der Rückgabewert ein 3-dimensionaler Tensor ist. Das Argument Tensor war ein 4-dimensionaler Tensor von [Anzahl der Bilder, RGB, vertikal, horizontal], aber die Dimension der Anzahl der Bilder ist verschwunden.

Und wie in der Dokumentation angegeben, werden standardmäßig `` `padding = 2``` verwendet, sodass 2 über und unter 36 hinzugefügt werden und 2 zwischen jedem Bild und an beiden Enden 32 * n + 2 * hinzugefügt werden. (n + 1) = 138 (n = 4) Mit anderen Worten ist 32 138 für die Horizontale.

4. Modelldefinition

Werfen wir einen Blick auf diesen Code.

from torch.autograd import Variable
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()

4.1 Was ist variabel?

Variable umschließt torch.Tensor so, dass es Gradientendaten usw. aufnehmen kann. ..

Variable umschließt einen Tensor, sodass ein Schritt erforderlich ist, wenn Sie die in Variable enthaltenen Daten anzeigen möchten.

a = torch.FloatTensor([1.])
a2 = Variable(a)

print(type(a)) # <class 'torch.FloatTensor'>
print(type(a2)) # <class 'torch.autograd.variable.Variable'>
print(type(a2.data)) # <class 'torch.FloatTensor'>

print(a.numpy()) # [ 1.]
print(a2.data.numpy()) # [ 1.]

Wie oben gezeigt, wird der Tensor in ".data" gespeichert. (Referenz)

Die Gradienteninformation ist übrigens

print(a2.grad) # None

Es wird hier gespeichert. Momentan gibt es nichts, daher ist keines enthalten. Es scheint, dass nur "Keine" oder "Variable" akzeptiert wird.

a2.grad = Variable(torch.FloatTensor([100]))
print(a2.grad) # Variable containing: 100

Es scheint, dass Sie es auf der Rückseite so ersetzen können. Und die Tatsache, dass nur Variable akzeptiert wird, bedeutet, dass dort auch Gradienteninformationen gespeichert werden.

a2.grad.grad =  Variable(torch.FloatTensor([200]))
print(a2.grad.grad) # Variable containing: 200

Wird die höhere Ableitung auf diese Weise manipuliert? Es ist interessant.

4.2. Was ist nn.Module?

class Net(nn.Module):

nn.Module Die Klasse ist eine Basisklasse, und Forward usw. werden in dieser und beim Erstellen eines Modells definiert. Es erbt dies. (Tatsächlich ist etwas Konkretes nicht vorwärts definiert, und es scheint anzunehmen, dass es nach der Vererbung zugewiesen wird.)

4.3. Was ist nn.Conv2d?

Das Argument von nn.Conv2d lautet Von links die Anzahl der Eingangskanäle, die Anzahl der Ausgangskanäle und die Kernelgröße.

Zum Zeitpunkt dieser Modelldefinition wird ein Zufallswert nahe 0 in den Filter eingegeben, der ein Parameter der Faltungsschicht ist, und er wird vorbereitet. Dies kann wie folgt bestätigt werden.

conv1 = nn.Conv2d(3, 6, 5)
print(conv1.weight)

Parameter containing:
(0 ,0 ,.,.) = 
 -0.0011 -0.1120  0.0351 -0.0488  0.0323
 -0.0529 -0.0126  0.1139 -0.0234 -0.0729
  0.0384 -0.0263 -0.0903  0.1065  0.0702
  0.0087 -0.0492  0.0519  0.0254 -0.0941
  0.0351 -0.0556 -0.0279 -0.0641 -0.0790

(0 ,1 ,.,.) = 
 -0.0738  0.0853  0.0817 -0.1121  0.0463
 -0.0266  0.0360  0.0215 -0.0997 -0.0559
  0.0441 -0.0151  0.0309 -0.0026  0.0167
 -0.0534  0.0699 -0.0295 -0.1043 -0.0614
 -0.0820 -0.0549 -0.0654 -0.1144  0.0049
 ...
 [torch.FloatTensor of size 6x3x5x5]

Da die Kernelgröße auf 5 eingestellt ist, wird der Tensor (Anzahl der Ausgangskanäle, RGB, Kernelgröße, Kernelgröße) vorbereitet. Apropos,

conv1 = nn.Conv2d(3, 6, (5,1))
print(conv1.weight)

Parameter containing:
(0 ,0 ,.,.) = 
  0.2339
 -0.0756
  0.0604
 -0.0185
 -0.0975
 ...

Es scheint, dass Sie etwas anderes als Quadrat tun können.

Auch dieser Parameter ist

type(conv1.weight)
# torch.nn.parameter.Parameter

Es wird durch das Parameter-Objekt wie folgt definiert und ist eine Unterklasse von Variable. Es sieht aus wie ein kurzer Blick. , Die Anzeigefunktion ist definiert. Wenn es sich um eine Variable handelt, wird sie als Variable mit angezeigt. In Parameter wird sie jedoch als Parameter mit: angezeigt.

4.4. Was ist nn.MaxPool2d?

nn.MaxPool2d ist die MAX-Pooling-Schicht. Die Hauptargumente sind kernel_size, stride und padding.

Lassen Sie uns also das adaptive Bild falten und MAX bündeln und sehen, wie es konvertiert wird.

images, labels = dataiter.next()
print(images.size())
print(type(images))
image_plot = images[0][1].numpy()
plt.imshow(image_plot, cmap='Greys', interpolation='nearest')
plt.show()

#Modelldefinition
img_input = Variable(images)
conv = nn.Conv2d(3, 1, 3, padding=1)
pool = nn.MaxPool2d(3, padding=1, stride=1)

#nach vorne
conv_output = conv(img_input)
pool_output = pool(conv_output)
print(pool_output.size())

#Handlung
conv_plot = conv_output[0][0].data.numpy()
conv_plot 
plt.imshow(conv_plot, cmap='Greys', interpolation='nearest')
plt.show()

pool_plot = pool_output[0][0].data.numpy()
plt.imshow(pool_plot, cmap='Greys', interpolation='nearest')
plt.show()

--Original Bild fig3.png Es ist ein Pferd.

4.5 Definition der Zielfunktion und Definition der Optimierungsmethode

Schauen wir uns als nächstes [diesen Code] an (http://pytorch.org/tutorials/beginner/blitz/cifar10_tutorial.html#define-a-loss-function-and-optimizer).

import torch.optim as optim

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

4.6. Was ist nn.CrossEntropyLoss ()?

nn.CrossEntropyLoss () definiert ein Objekt als Zielfunktion.

4.7. Was ist optim.SGD?

`` `torch.optim``` definiert verschiedene Optimierungsalgorithmen. SGD, Adam usw.

Unter den in torch.optim definierten Optimierungsalgorithmen verwenden wir hier optim.SGD. Ich werde.

Wir übergeben "net.parameters ()" als Argument an "optim.SGD". net.parameters () scheint die im Modell (torch.nn.parameter.Parameter) definierten Parameter als Generator zurückzugeben.

type(net.parameters())
# generator

type(net.parameters().__next__())
# torch.nn.parameter.Parameter

print(net.parameters().__next__())

Parameter containing:
(0 ,0 ,.,.) = 
 -0.0998  0.0035 -0.0438 -0.1150 -0.0435
  0.0310 -0.0750 -0.0405 -0.0745 -0.1095
 -0.0355  0.0065 -0.0225  0.0729 -0.1114
  0.0708 -0.0170 -0.0253  0.1060  0.0557
  0.1057  0.0873  0.0793 -0.0309 -0.0861
  ...

Wenn Sie das vom Optimierer gehaltene Objekt überprüfen,

optimizer.__dict__

{'param_groups': [{'dampening': 0,
   'lr': 0.001,
   'momentum': 0.9,
   'nesterov': False,
   'params': [Parameter containing:
    (0 ,0 ,.,.) = 
      0.0380 -0.1152  0.0761  0.0964 -0.0555
     -0.0325 -0.0455 -0.0755  0.0413 -0.0589
      0.0116  0.1136 -0.0992 -0.1149 -0.0414
     -0.0611  0.0827 -0.0906  0.0631  0.0170
      0.0903 -0.0816 -0.0690  0.0470 -0.0578
  ...

net.parameters () behält alle im Modell enthaltenen Parameter bei, einschließlich meiner Parameter.

5. Modelltraining

Werfen wir einen Blick auf den [Code] für das Training (http://pytorch.org/tutorials/beginner/blitz/cifar10_tutorial.html#train-the-network).

for epoch in range(2):  # loop over the dataset multiple times

    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):
        #Das zweite Argument ist die Startposition, die 0 ist(trainloader)Gleich wie
        # https://docs.python.org/3/library/functions.html#enumerate
        
        # get the inputs
        inputs, labels = data

        # wrap them in Variable
        inputs, labels = Variable(inputs), Variable(labels)

        # zero the parameter gradients
        optimizer.zero_grad()

        # forward + backward + optimize
        outputs = net(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        # print statistics
        running_loss += loss.data[0]
        if i % 2000 == 1999:    # print every 2000 mini-batches
            print('[%d, %5d] loss: %.3f' %
                  (epoch + 1, i + 1, running_loss / 2000))
            running_loss = 0.0

print('Finished Training')

5.1. Was ist optimizer.zero_grad ()?

Wie wir zuvor bestätigt haben, enthält `` `Optimizer``` alle Parameter.

optimizer.zero_grad () initialisiert den Grad dieser gehaltenen Variablen. Es scheint. Ich denke es ist alles keine.

5.2 Was ist Outputs = net (Inputs)?

outputs = net(inputs)

print(type(outputs))
# <class 'torch.autograd.variable.Variable'>

print(outputs.size())
# torch.Size([4, 10])

outputs
Variable containing:
-2.4825 -4.4286  2.2041  3.4353  2.0734  2.8198  1.9374  0.7751 -2.6798 -3.1932
-1.7512 -4.6657  2.7911  3.9570  0.7931  5.9005 -0.8023  2.9664 -4.3328 -3.2921
 2.4015  2.8962  0.9330 -1.2107 -0.0525 -2.2119 -1.2474 -2.6026 -0.1120  0.4869
-1.3042 -2.7538  1.0985 -0.2462  3.7435  1.1724 -1.4233  6.6892 -3.8201 -2.3132
[torch.FloatTensor of size 4x10]

Wenn Sie es an "net" übergeben, können Sie sehen, dass die endgültige Ausgabe über die Zielfunktion zurückgegeben wird.

5.3 Was ist Verlust = Kriterium (Ausgaben, Etiketten)?

Der Kommentar sagt vorwärts + rückwärts + optimieren, aber ich kann die Vorwärtsmethode nicht sehen.

Dies liegt tatsächlich daran, dass CrossEntropyLoss mit call weiterleitet, was bedeutet

loss = criterion(outputs, labels)
loss = criterion.forward(outputs, labels)

Die beiden machen das Gleiche. "Verlust = Kriterium (Ausgaben, Beschriftungen)" ist also vorwärts.

5.4. Was ist loss.backward ()?

loss ist ein variables Objekt.

type(loss)
# torch.autograd.variable.Variable

Variable.backward () befindet sich in diesem [torch.autograd.backward ()](http: / /pytorch.org/docs/master/autograd.html#torch.autograd.backward) wird aufgerufen.

Dann ermittelt dieses ".backward ()" den Differentialkoeffizienten des in der Zielfunktion enthaltenen Parameters. Versuchen wir es mit einem einfachen Beispiel.

x = torch.autograd.Variable(torch.Tensor([3,4]), requires_grad=True)
# requires_grad=True sagt Ihnen, dass diese Variable differenziert

print("x.grad : ", x.grad)
# None
#Zu diesem Zeitpunkt ist noch nichts drin.

#Erstellen Sie eine Zielfunktion entsprechend.
y = x[0]**2 + 5*x[1]  + x[0]*x[1]
# x[0]Derivat von: 2*x[0] + x[1]
# x[0]Differenzkoeffizient von: 2*3 + 4 = 10
# x[1]Derivat von: 5 + x[0]
# x[1]Differenzkoeffizient von: 5 + 3 = 8

y.backward()
# torch.autograd.backward(y)Aber es ist okay.

print("x.grad : ", x.grad)
# 10
# 8

# .zero_grad()anstatt
x.grad = None

Es ist der Differentialkoeffizient der Zielfunktion "y" am Eingangsdatenpunkt. Hierbei ist zu beachten, dass es bei Rückwärts um die Verlustfunktion geht, also muss Rückwärts y ein Skalar sein.

Zum Beispiel

y = x
y.backward()

# RuntimeError: grad can be implicitly created only for scalar outputs

Dann werde ich wütend, es zu einem Skalar zu machen.

5.5 Was ist optimizer.step ()?

.step () aktualisiert die Parameter basierend auf dem von .backward () berechneten Gradienten Werde es tun. Lass es uns überprüfen.

optimizer.zero_grad()
outputs = net(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()

print(net.parameters().__next__())
Parameter containing:
(0 ,0 ,.,.) = 
 -0.0839  0.1434 -0.0371 -0.1394 -0.0277

Nach mehrmaliger Ausführung (obwohl es mit denselben Daten optimiert wurde)

print(net.parameters().__next__())
Parameter containing:
(0 ,0 ,.,.) = 
 -0.0834  0.1436 -0.0371 -0.1389 -0.0276

Und so werden die Parameter nach und nach aktualisiert.

6. Validieren

Sagen Sie das Modell für die Testdaten voraus. Dieser Code.

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

print('Accuracy of the network on the 10000 test images: %d %%' % (
    100 * correct / total))
class_correct = list(0. for i in range(10))
class_total = list(0. for i in range(10))
for data in testloader:
    images, labels = data
    #print("images type : ", type(images))
    #print("images.shape : ", images.shape)
    outputs = net(Variable(images))
    _, predicted = torch.max(outputs.data, 1)
    c = (predicted == labels).squeeze()
    for i in range(4):
        label = labels[i]
        class_correct[label] += c[i]
        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 : 51 %
# Accuracy of   car : 54 %
# Accuracy of  bird : 53 %
# Accuracy of   cat : 33 %
# Accuracy of  deer : 41 %
# Accuracy of   dog : 50 %
# Accuracy of  frog : 54 %
# Accuracy of horse : 65 %
# Accuracy of  ship : 70 %
# Accuracy of truck : 67 %

6.1. Was ist .squeeze ()?

Ist dies der einzige, mit dem ich nicht vertraut bin? torch.squeeze Löschen Sie in der Dimension des Tensors die von 1. Es scheint, dass Quetschen Quetschen bedeutet.

7. Am Ende

7.1. Etwas Nützliches

Sie können herausfinden, um welche Art von Modell es sich handelt, indem Sie auf ~~ net.parameters schauen. ~~ (Korrigiert am 27. Oktober 2017)

Da das __repr__ von nn.Module so definiert ist, dass das Modell leicht lesbar angezeigt wird, können Sie grob verstehen, um welche Art von Modell es sich handelt.

In [22]: net
Out[22]:
Net (
  (conv1): Conv2d(3, 6, kernel_size=(5, 5), stride=(1, 1))
  (pool): MaxPool2d (size=(2, 2), stride=(2, 2), dilation=(1, 1))
  (conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))
  (fc1): Linear (400 -> 120)
  (fc2): Linear (120 -> 84)
  (fc3): Linear (84 -> 10)
)

7.2 Impressionen

Recommended Posts

[Details (?)] Einführung in Pytorch ~ CNN von CIFAR10 ~
Einführung in Lightning Pytorch
Einführung in PyTorch (1) Automatische Differenzierung
[Einführung in Pytorch] Ich habe versucht, Cifar10 mit VGG16 ♬ zu kategorisieren
Einführung in Deep Learning ~ CNN Experiment ~
[PyTorch] Einführung in die Dokumentklassifizierung mit BERT
[Einführung in Pytorch] Ich habe mit sinGAN ♬ gespielt
Einführung in MQTT (Einführung)
Einführung in Scrapy (1)
Einführung in Scrapy (3)
Erste Schritte mit Supervisor
Einführung in Tkinter 1: Einführung
Pytorch super Einführung
Einführung in PyQt
Einführung in Scrapy (2)
[Linux] Einführung in Linux
Einführung in Scrapy (4)
Einführung in discord.py (2)
[Super Einführung in das maschinelle Lernen] Lernen Sie Pytorch-Tutorials
[PyTorch] Einführung in die Klassifizierung japanischer Dokumente mit BERT
[Super Einführung in das maschinelle Lernen] Lernen Sie Pytorch-Tutorials
Erste Schritte mit Web Scraping
Einführung in nichtparametrische Felder
Einführung in EV3 / MicroPython
Einführung in die Python-Sprache
Einführung in die TensorFlow-Bilderkennung
Einführung in OpenCV (Python) - (2)
[Pytorch] numpy bis Tensor
Einführung in PyQt4 Teil 1
Einführung in die Abhängigkeitsinjektion
Einführung in Private Chainer
PyTorch-Einführung (virtuelle Umgebung)
PyTorch Super Einführung PyTorch-Grundlagen
Einführung in das maschinelle Lernen
[Einführung in Pytorch] Ich möchte Sätze in Nachrichtenartikeln generieren
AOJ Einführung in die Programmierung Thema Nr. 1, Thema Nr. 2, Thema Nr. 3, Thema Nr. 4
Einführung in das elektronische Papiermodul
Einführung in den Wörterbuch-Suchalgorithmus
Einführung in die Monte-Carlo-Methode
[PyTorch] Bildklassifizierung von CIFAR-10
[Lernmemorandum] Einführung in vim
opencv-python Einführung in die Bildverarbeitung
Einführung in Python Django (2) Win
Einführung in das Schreiben von Cython [Notizen]
Einführung in Private TensorFlow
Eine Einführung in das maschinelle Lernen
[Einführung in cx_Oracle] Übersicht über cx_Oracle
Eine super Einführung in Linux
AOJ Einführung in die Programmierung Thema Nr. 7, Thema Nr. 8
Einführung in die Anomalieerkennung 1 Grundlagen
Einführung in RDB mit sqlalchemy Ⅰ
[Einführung in Systre] Fibonacci Retracement ♬
Einführung in die nichtlineare Optimierung (I)
Einführung in die serielle Kommunikation [Python]
AOJ Einführung in die Programmierung Thema Nr. 5, Thema Nr. 6