[PYTHON] Deep Kernel Learning mit Pyro

Deep Kernel Learning ist eine Kombination aus Deep Learning und Gaußschen Prozessen und gehört zum Bayes'schen Deep Learning. Als Methode wird ein tiefer Kernel erstellt, indem die vom tiefen neuronalen Netz (DNN) ausgegebenen Merkmale als Eingabe des Kernels im Gaußschen Prozess verwendet werden. Die Formel lautet wie folgt.

k_{deep}(x,x') = k(f(x),f(x'))

Da der Gaußsche Prozess einem neuronalen Netz mit unendlichen Einheiten entspricht, scheint er am Ende von DNN hinzugefügt worden zu sein. Wie ich im vorherigen Artikel (https://qiita.com/takeajioka/items/f24d58d2b13017ab2b18) versucht habe, ist es wichtig, die Kernel-Hyperparameter während des Gaußschen Prozesses zu optimieren. Deep Kernel Learning scheint DNN-Parameter und Kernel-Hyper-Parameter gleichzeitig zu optimieren und zu lernen.

Weitere Informationen finden Sie im folgenden Dokument. [1] Deep Kernel Learning, 2015, Andrew G. Wilson et al.,https://arxiv.org/abs/1511.02222 [2] Stochastic Variational Deep Kernel Learning, 2016, Andrew G. Wilson et al., https://arxiv.org/abs/1611.00336

Versuchen Sie, MNIST mit Deep Kernel Learning zu lernen

In Pyro können Sie mithilfe der Klasse gp.kernels.Warping auf einfache Weise einen tiefen Kernel erstellen. In Pyros offiziellem Tutorial gibt es einen Code für Deep Kernel Learning. Lassen Sie uns also anhand dieses Codes lernen.

import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
import torchvision
from torchvision import transforms
import pyro
import pyro.contrib.gp as gp
import pyro.infer as infer

Da MNIST über eine große Datenmenge verfügt, werden wir diese in einem Mini-Batch lernen. Stellen Sie den Datensatz ein.

batch_size = 100
transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5, ), (0.5, ))])
trainset = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=batch_size, shuffle=True)
testset = torchvision.datasets.MNIST(root='./data', train=False, download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=batch_size, shuffle=False)

Bereiten Sie zunächst ein normales DNN-Modell vor.

class CNN(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(1, 10, kernel_size=5)
        self.conv2 = nn.Conv2d(10, 20, kernel_size=5)
        self.fc1 = nn.Linear(320, 50)
        self.fc2 = nn.Linear(50, 10)
    def forward(self, x):
        x = F.relu(F.max_pool2d(self.conv1(x), 2))
        x = F.relu(F.max_pool2d(self.conv2(x), 2))
        x = x.view(-1, 320)
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return x

Wickeln Sie den Kernel darin ein, um einen tiefen Kernel zu erstellen.

rbf = gp.kernels.RBF(input_dim=10, lengthscale=torch.ones(10))
deep_kernel = gp.kernels.Warping(rbf, iwarping_fn=CNN())

Eine spärliche Näherung wird verwendet, um die Berechnungskosten des Gaußschen Prozesses zu reduzieren. In der spärlichen Näherung wird der Induktionspunkt verwendet, aber dieses Mal werden wir die Trainingsdaten für eine Chargengröße verwenden.

Xu, _ = next(iter(trainloader))
likelihood = gp.likelihoods.MultiClass(num_classes=10)
gpmodule = gp.models.VariationalSparseGP(X=None, y=None, kernel=deep_kernel, Xu=Xu, likelihood=likelihood, latent_shape=torch.Size([10]), num_data=60000)
optimizer = torch.optim.Adam(gpmodule.parameters(), lr=0.01)
elbo = infer.TraceMeanField_ELBO()
loss_fn = elbo.differentiable_loss

Definiert eine Funktion für das Mini-Batch-Lernen.

def train(train_loader, gpmodule, optimizer, loss_fn, epoch):
    total_loss = 0
    for data, target in train_loader:
        gpmodule.set_data(data, target)
        optimizer.zero_grad()
        loss = loss_fn(gpmodule.model, gpmodule.guide)
        loss.backward()
        optimizer.step()
        total_loss += loss
    return total_loss / len(train_loader)

def test(test_loader, gpmodule):
    correct = 0
    for data, target in test_loader:
        f_loc, f_var = gpmodule(data)
        pred = gpmodule.likelihood(f_loc, f_var)
        correct += pred.eq(target).long().sum().item()
    return 100. * correct / len(test_loader.dataset)

Lerne.

import time
losses = []
accuracy = []
epochs = 10
for epoch in range(epochs):
    start_time = time.time()
    loss = train(trainloader, gpmodule, optimizer, loss_fn, epoch)
    losses.append(loss)
    with torch.no_grad():
        acc = test(testloader, gpmodule)
    accuracy.append(acc)
    print("Amount of time spent for epoch {}: {}s\n".format(epoch+1, int(time.time() - start_time)))
print("loss:{:.2f}, accuracy:{}".format(losses[-1],accuracy[-1]))

Ich konnte eine Epoche in ungefähr 30 Sekunden lernen. Die endgültige Genauigkeit betrug 96,23%. (Es scheint, dass es im offiziellen Tutorial bis zu 99,41% sein kann.) Zeigen Sie die Lernkurve an.

import matplotlib.pyplot as plt
plt.subplot(2,1,1)
plt.plot(losses)
plt.xlabel("epoch")
plt.ylabel("loss")
plt.subplot(2,1,2)
plt.plot(accuracy)
plt.xlabel("epoch")
plt.ylabel("accuracy")

image.png

Schauen wir uns das Testbild und die vorhergesagte Ausgabe nebeneinander an.

data, target = next(iter(testloader))
f_loc, f_var = gpmodule(data)
pred = gpmodule.likelihood(f_loc, f_var)
for i in range(len(data)):
    plt.subplot(1,2,1)
    plt.imshow(data[i].reshape(28, 28))
    plt.subplot(1,2,2)
    plt.bar(range(10), f_loc[:,i].detach(), yerr= f_var[:,i].detach())
    ax = plt.gca()
    ax.set_xticks(range(10))
    plt.xlabel("class")
    plt.savefig('image/figure'+ str(i) +'.png')
    plt.clf()

figure0.png figure12.png figure15.png

Der blaue Balken ist der Durchschnittswert und der Fehlerbalken ist die Verteilung. Es wurde festgestellt, dass jede der 10 Klassen eine Ausgabe hatte und die richtige Klassenausgabe einen hohen Wert.

Schauen wir uns auch Bilder an, die schwer zu unterscheiden sind. figure36.png figure43.png figure92.png Die Ausgabe ist in mehreren Klassen hoch. In Anbetracht der Fehlerleiste scheint es keinen signifikanten Unterschied zu geben.

Am Ende

Ich konnte wie normales Deep Learning lernen. Ich denke, dass es ein Vorteil ist, dass normales Deep Learnig nicht hat, dass es den Durchschnittswert und die Varianz als Ausgabe ausgeben kann. Es gibt auch einen tiefen Gaußschen Prozess (DGP), der ein Stapel von Gaußschen Prozessen ist, daher möchte ich das auch untersuchen.

Recommended Posts

Deep Kernel Learning mit Pyro
Versuchen Sie es mit TensorFlow
Versuchen Sie Deep Learning mit FPGA
Generiere Pokemon mit Deep Learning
Tiefes Lernen
Probieren Sie Deep Learning mit FPGA-Select-Gurken aus
Identifikation der Katzenrasse mit Deep Learning
Machen Sie ASCII-Kunst mit tiefem Lernen
Versuchen Sie es mit TensorFlow Part 2
Überprüfen Sie die Kniebeugenform mit tiefem Lernen
Kategorisieren Sie Nachrichtenartikel mit Deep Learning
Snack-Umsatzprognose mit Deep Learning
Bringen Sie Menschen mit Deep Learning zum Lächeln
Klassifizieren Sie Anime-Gesichter mit tiefem Lernen mit Chainer
Deep Learning Memorandum
Probieren Sie die Bitcoin-Preisprognose mit Deep Learning aus
Versuchen Sie es mit Chainer Deep Q Learning - Launch
Starten Sie Deep Learning
Versuchen Sie mit Kipoi tiefes Erlernen der Genomik
Emotionale Analyse von Tweets mit Deep Learning
Python Deep Learning
Deep Learning × Python
Die Geschichte des tiefen Lernens mit TPU
99,78% Genauigkeit bei tiefem Lernen durch Erkennen von handgeschriebenem Hiragana
Erstes tiefes Lernen ~ Kampf ~
Python lernen mit ChemTHEATER 03
"Objektorientiert" mit Python gelernt
Python lernen mit ChemTHEATER 05-1
Nicht parametrische Buchten mit Pyro
Deep Learning von Grund auf neu
Kernel-Methode mit Python
Deep Learning 1 Übung des Deep Learning
Deep Learning / Cross Entropy
Erstes tiefes Lernen ~ Vorbereitung ~
Erstes tiefes Lernen ~ Lösung ~
[AI] Deep Metric Learning
Python lernen mit ChemTHEATER 02
Ich habe versucht, tief zu lernen
Python lernen mit ChemTHEATER 01
Python: Deep Learning Tuning
Deep Learning Großtechnologie
Deep Learning / Softmax-Funktion
Eine Geschichte über die Vorhersage des Wechselkurses mit Deep Learning
Deep Learning Bildanalyse beginnend mit Kaggle und Keras
Vorhersagen von Tags durch Extrahieren von Musikfunktionen mit Deep Learning
Klassifizieren Sie Anime-Gesichter durch Fortsetzung / Deep Learning mit Keras
Kernel-Regression nur mit Numpy
Deep Learning von Grund auf 1-3 Kapitel
Versuchen Sie, ein Deep Learning / Neuronales Netzwerk mit Scratch aufzubauen
[Evangelion] Versuchen Sie, mit Deep Learning automatisch Asuka-ähnliche Linien zu erzeugen
<Kurs> Tiefes Lernen: Day2 CNN
Selbst erstellter Linux-Kernel mit Clang
Deep Learning Bilderkennung 1 Theorie
Deep Running 2 Tuning von Deep Learning
Erstellen Sie mit Docker eine Umgebung für "Deep Learning von Grund auf neu"
Verbessertes Lernen ab Python
Über das Lernen mit Google Colab
Deep Learning / LSTM Scratch Code
Maschinelles Lernen mit Python! Vorbereitung