[PYTHON] Ich habe den MNIST-Code von Chainer mit PyTorch + Ignite neu geschrieben

TL;DR Der Eindruck, Chainers MNIST-Code in PyTorch umzuschreiben, war fast der gleiche. Der Unterschied war die Ebene über Updater in Chainer und die Ebene Ignite in PyTorch. Wenn Sie [Chainer-Pytorch-Migration] 3 verwenden, können Sie außerdem Erweiterungen verwenden, die in Chainer in Ignite verwendet werden, und Sie können PyTorch + Ignite ganz wie Chainer verwenden. Ich denke, dass diejenigen, die Chainer verwendet haben, sich auf natürliche Weise an PyTorch + Ignite gewöhnen können.

Kettenentwicklung durch PFN gestoppt und PyTorch übernommen

Es wurde angekündigt, dass PFN die Chainer-Entwicklung beenden und zu PyTorch wechseln wird, wie hier beschrieben [\ [1 ]] 1.

Preferred Networks Co., Ltd. (Hauptsitz: Chiyoda-ku, Tokio, Präsident: Toru Nishikawa, Preferred Networks, im Folgenden: PFN) hat aus seinem eigens entwickelten Chainer ™ ein Deep-Learning-Framework entwickelt, das die grundlegende Technologie für Forschung und Entwicklung darstellt. Migrieren Sie nacheinander zu PyTorch. Gleichzeitig werden wir mit Facebook, das PyTorch entwickelt, und der Entwickler-Community von PyTorch zusammenarbeiten und an der Entwicklung von PyTorch teilnehmen. Darüber hinaus wird Chainer mit der neuesten Version v7 in die Wartungsphase übergehen, bei der es sich um ein heute veröffentlichtes Hauptversions-Upgrade handelt. Für Chainer-Benutzer stellen wir Dokumentation und Bibliotheken zur Verfügung, um Sie bei der Migration zu PyTorch zu unterstützen.

Es ist nicht so, dass Sie Chainer nicht sofort verwenden können, aber Chainer-Benutzer werden nach und nach gezwungen, zu anderen Frameworks zu wechseln.

Unterstützung für die Migration von Chainer zu PyTorch mit PFN

Viele Benutzer sind möglicherweise verwirrt über die plötzliche Ankündigung des Endes der Chainer-Entwicklung, aber PFN unterstützt auch den Übergang zu PyTorch in Erwartung dieser Situation [Dokument \ [2 ]] 2 und [Bibliothek \ [ 3 ]] 3 wird bereitgestellt.

In Bezug auf das obige Dokument ist die Entsprechung zwischen Chainer und PyTorch + Ignite wie folgt.

スクリーンショット 2019-12-17 15.32.28.png cited from [2]

Was Sie von oben sehen können

--PyTorch unterstützt die Rolle des Chainers bis zum Optimierer --Ignite unterstützt die Rolle des Updaters / Trainers of Chainer.

Wenn Sie also die Lernschritte selbst schreiben möchten, können Sie nur mit PyTorch schreiben. Wenn Sie jedoch möchten, dass die Lernschritte vom Framework wie Chainers Trainer ausgeführt werden, müssen Sie PyTorch + Ignite verwenden.

Ich bin sofort von Chainer zu PyTorch + Ignite gewechselt

Zu migrierender Code

Unter dem folgenden Link finden Sie ein Notizbuch zum Trainieren und Ableiten von MNIST mit Chainer's Trainer.

Dieses Mal möchte ich den obigen Code mit PyTorch + Ignite neu schreiben.

So migrieren Sie jeden Schritt

Teil des Beispieldatensatzes lesen

from chainer.datasets import mnist

train, test = mnist.get_mnist()

from torchvision.datasets import MNIST
from torchvision.transforms import ToTensor

data_transform = ToTensor()

train = MNIST(download=True, root=".", transform=data_transform, train=True)
test = MNIST(download=False, root=".", transform=data_transform, train=False)

Iterator -> DataLoader

from chainer import iterators

batchsize = 128

train_iter = iterators.SerialIterator(train, batchsize)
test_iter = iterators.SerialIterator(test, batchsize, False, False)

from torch.utils.data import DataLoader

batch_size = 128

train_loader = DataLoader(train, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(test, batch_size=batch_size, shuffle=False)

Modellvorbereitung


import chainer
import chainer.links as L
import chainer.functions as F

class MLP(chainer.Chain):

    def __init__(self, n_mid_units=100, n_out=10):
        super(MLP, self).__init__()
        with self.init_scope():
            self.l1=L.Linear(None, n_mid_units)
            self.l2=L.Linear(None, n_mid_units)
            self.l3=L.Linear(None, n_out)


    def forward(self, x):
        h1 = F.relu(self.l1(x))
        h2 = F.relu(self.l2(h1))
        return self.l3(h2)

gpu_id = 0  # Set to -1 if you don't have a GPU

model = L.Classifier(model)
if gpu_id >= 0:
    model.to_gpu(gpu_id)

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

class MLP(nn.Module):

    def __init__(self, n_mid_units=100, n_out=10):
        super(MLP, self).__init__()
        self.l1 = nn.Linear(784, n_mid_units)
        self.l2 = nn.Linear(n_mid_units, n_mid_units)
        self.l3 = nn.Linear(n_mid_units, n_out)

    def forward(self, x):
        x = torch.flatten(x, start_dim=1)
        h1 = F.relu(self.l1(x))
        h2 = F.relu(self.l2(h1))
        h3 = self.l3(h2)
        return F.log_softmax(h3, dim=1)

device = 'cuda:0'

model = MLP()

Vorbereitung für Optimizer

from chainer import optimizers

lr = 0.01

optimizer = optimizers.SGD(lr=lr)
optimizer.setup(model)

from torch import optim

lr = 0.01

#Auswahl der Optimierungsmethode
optimizer = optim.SGD(model.parameters(), lr=lr)

Updater -> Ignite

from chainer import training

updater = training.StandardUpdater(train_iter, optimizer, device=gpu_id)

from ignite.engine import create_supervised_trainer

trainer = create_supervised_trainer(model, optimizer, F.nll_loss, device=device)

Hinzufügung der Verlängerung

from chainer.training import extensions

trainer = training.Trainer(
    updater, (max_epoch, 'epoch'), out='mnist_result'
)

trainer.extend(extensions.LogReport())
.
.
.
trainer.extend(extensions.Evaluator(test_iter, model, device=gpu_id))

from ignite.engine import create_supervised_evaluator
from ignite.metrics import Accuracy, Loss
from ignite.engine import Events

evaluator = create_supervised_evaluator(
    model,
    metrics={
      'accuracy': Accuracy(),
      'nll': Loss(F.nll_loss),
    },
    device=device,
)

training_history = {'accuracy':[],'loss':[]}
validation_history = {'accuracy':[],'loss':[]}

@trainer.on(Events.EPOCH_COMPLETED)
def log_training_results(engine):
    evaluator.run(train_loader)
    metrics = evaluator.state.metrics
    avg_accuracy = metrics['accuracy']
    avg_nll = metrics['nll']
    training_history['accuracy'].append(avg_accuracy)
    training_history['loss'].append(avg_nll)
    print(
        "Training Results - Epoch: {}  Avg accuracy: {:.2f} Avg loss: {:.2f}"
        .format(engine.state.epoch, avg_accuracy, avg_nll)
    )

@trainer.on(Events.EPOCH_COMPLETED)
def log_validation_results(engine):
    evaluator.run(test_loader)
    metrics = evaluator.state.metrics
    avg_accuracy = metrics['accuracy']
    avg_nll = metrics['nll']
    validation_history['accuracy'].append(avg_accuracy)
    validation_history['loss'].append(avg_nll)
    print(
        "Validation Results - Epoch: {}  Avg accuracy: {:.2f} Avg loss: {:.2f}"
        .format(engine.state.epoch, avg_accuracy, avg_nll))

# Create snapshot
from ignite.handlers import ModelCheckpoint

checkpointer = ModelCheckpoint(
    './models',
    'MNIST',
    save_interval=1,
    n_saved=2, 
    create_dir=True, 
    save_as_state_dict=True,
    require_empty=False,
)
trainer.add_event_handler(Events.EPOCH_COMPLETED, checkpointer, {'MNIST': model})

Durchführung von Schulungen

trainer.run()

max_epochs = 10
trainer.run(train_loader, max_epochs=max_epochs)

Code nach der Migration

Unten finden Sie ein Notizbuch, das tatsächlich migriert und auf Colaboratory ausgeführt wird. Zusätzlich zu dem oben beschriebenen Code ist auch Folgendes enthalten. Versuchen Sie daher, ihn zur Hand zu haben, wenn Sie möchten.

https://drive.google.com/open?id=1NqHYJjFz-dl1tWP8kMO0y0kCZ9-ZWLxi

Bonus

Wenn Sie [chainer-pytorch-migration] 3 verwenden, können Sie die in Chainer in Ignite! Wenn Sie Chainer-Erweiterungen vermissen, versuchen Sie, die Chainer-Pytorch-Migration zu verwenden.

import chainer_pytorch_migration as cpm
import chainer_pytorch_migration.ignite
from chainer.training import extensions

optimizer.target = model
trainer.out = 'result'

cpm.ignite.add_trainer_extension(trainer, optimizer, extensions.LogReport())
cpm.ignite.add_trainer_extension(trainer, optimizer, extensions.ExponentialShift('lr', 0.9, 1.0, 0.1))
cpm.ignite.add_trainer_extension(trainer, optimizer, extensions.PrintReport(
    ['epoch', 'iteration', 'loss', 'lr']))

max_epochs = 10
trainer.run(train_loader, max_epochs=max_epochs)

Reference

Recommended Posts

Ich habe den MNIST-Code von Chainer mit PyTorch + Ignite neu geschrieben
Ich habe Word2Vec mit Pytorch gemacht
Ich habe versucht, MNIST nach GNN zu klassifizieren (mit PyTorch-Geometrie).
Ich habe versucht, Attention Seq2Seq mit PyTorch zu implementieren
Ich habe versucht, DeepPose mit PyTorch zu implementieren
Ich habe versucht, Shake-Shake Regularization (ShakeNet) mit PyTorch zu implementieren
[Einführung in Pytorch] Ich habe mit sinGAN ♬ gespielt
Ich habe versucht, DeepPose mit PyTorch PartⅡ zu implementieren
Ich habe versucht, CVAE mit PyTorch zu implementieren
Ich habe versucht, das Lesen von Dataset mit PyTorch zu implementieren
Ich habe versucht, GAN (mnist) mit Keras zu bewegen
Ich habe Flask mit Remote-Containern von VS Code ausprobiert
Spiele mit PyTorch
Kreuzvalidierung mit PyTorch
Beginnend mit PyTorch
Code für TensorFlow MNIST Anfänger / Experte mit japanischen Kommentaren
Ich habe versucht, Faster R-CNN mit Pytorch auszuführen
Trainieren Sie MNIST-Daten mit PyTorch mithilfe eines neuronalen Netzwerks
Ich habe versucht, DCGAN mit PyTorch zu implementieren und zu lernen
[Einführung in Pytorch] Ich habe versucht, Cifar10 mit VGG16 ♬ zu kategorisieren
Ich habe versucht, SSD jetzt mit PyTorch zu implementieren (Dataset)
Bei der Verwendung von Tensorboard mit Pytorch ist ein Fehler aufgetreten