[PYTHON] Introduction à Lightning Pytorch

pytorch J'ai essayé d'apprendre par moi-même, mais je suis tombé sur diverses choses, alors je l'ai résumé. Plus précisément, tutoriel pytorchの一部をGW中に翻訳・若干改良しました。この通りになめて行けば短時間で基本的なことはできるようになると思います。躓いた人、自分で書きながら勉強したい人向けに各章末にまとめのコードのリンクがあるのでよしなにご活用ください。

Caractéristiques de pytorch

--Syntaxe structure proche du chainer --defined by run: le graphe de rétropropagation est créé en fonction de la propagation avant lors de l'exécution du code

importer des modules

import torch #Module de base
from torch.autograd import Variable #Pour une différenciation automatique
import torch.nn as nn #Pour la construction de réseaux
import torch.optim as optim #Fonction d'optimisation
import torch.nn.functional as F #Diverses fonctions pour le réseau
import torch.utils.data #Lié à la lecture de l'ensemble de données
import torchvision #Lié à l'image
from torchvision import datasets, models, transforms #Différents ensembles de données pour les images

À peu près pytorch

Les bases du pytorch

--pytorch effectue des opérations avec un type appelé Tensor

x = torch.Tensor(5, 3) #Définition de 5x3 Tensor
y = torch.rand(5, 3) #Définition de Tensor initialisé avec des nombres aléatoires 5x3
z = x + y #Le calcul normal est également possible

--Toutes les variables doivent être converties en Tensor pour utiliser pytorch --Tensor-> numpy: (variable Tensor) .numpy () --numpy-> Tensor: torch.from_numpy (variable Numpy)

x = np.random.rand(5, 3)
y = torch.from_numpy(x)
z = y.numpy()
x = torch.rand(5, 3)
y = Variable(x)
z = torch.pow(y,2) + 2 #y_i**2 + 2

Obtenez des données

Les données fournies par pytorch doivent être Tensor (train), Tensor (target). TensorDataset est une fonction qui convertit les étiquettes de données en même temps. Le DataLoader de pytorch ne prend en charge que le traitement par lots.

train = torch.utils.data.TensorDataset(torch.from_numpy(X_train), torch.from_numpy(y_train))
train_loader = torch.utils.data.DataLoader(train, batch_size=100, shuffle=True)
test = torch.utils.data.TensorDataset(torch.from_numpy(X_test), torch.from_numpy(y_test))
test_loader = torch.utils.data.DataLoader(test, batch_size=100, shuffle=True)

Il est également possible de mélanger à l'avance en définissant shuffle = True etc.

De plus, vous pouvez utiliser torchvision pour le traitement lié au traitement d'image (la transformation peut être utilisée pour exécuter uniformément des traitements tels que la tensorisation, la normalisation et le recadrage), et des ensembles de données tels que CIFAR-10 peuvent être lus.

#Traitement de transformation d'image
transform = transforms.Compose(
    [transforms.ToTensor(),
     transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])

#CIFAR-Chargement de la rame avant transformation en 10 Tensors
rawtrainset = torchvision.datasets.CIFAR10(root='./data', train=True,
                                        download=True)

#CIFAR-10 trains,Test de charge
#Transformer applique la transformation
trainset = torchvision.datasets.CIFAR10(root='./data', train=True,
                                        download=True, transform=transform)
testset = torchvision.datasets.CIFAR10(root='./data', train=False,
                                       download=True, transform=transform)

#Appliquer le chargeur de données->Cela permet d'allouer et de mélanger les lots à la fois.
#batch_Spécifiez la taille du lot avec la taille
#num_Spécifiez le nombre de cœurs sur lesquels les travailleurs chargeront les données(La valeur par défaut est principale uniquement)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=4,
                                          shuffle=True, num_workers=2)
testloader = torch.utils.data.DataLoader(testset, batch_size=4,
                                         shuffle=False, num_workers=2)

Définition du modèle

Vous devez classer définir le modèle comme dans l'exemple ci-dessous --OK si vous définissez init et forward

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(784,500)
        self.fc2 = nn.Linear(500, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = F.log_softmax(self.fc3(x))
        return x

#Définition du modèle
model = Net()

Apprentissage

Réglez la fonction de perte et l'optimiseur comme suit

#Spécification de la fonction de perte
criterion = nn.CrossEntropyLoss()

#Spécification de l'optimiseur
optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)

La formation se fait dans ce cadre. Je pense que le flux sera assez similaire, donc je le posterai pour référence

#entraînement
#Spécifier le nombre d'époques
for epoch in range(2):  # loop over the dataset multiple times
    
    #Perte totale de toutes les données
    running_loss = 0.0 
    
    
    for i, data in enumerate(trainloader):
        
        #Diviser en étiquettes de données d'entrée
        # get the inputs
        inputs, labels = data
        
        #Transformé en variable
        # wrap them in Variable
        inputs, labels = Variable(inputs), Variable(labels)

        #Initialiser l'optimiseur
        # zero the parameter gradients
        optimizer.zero_grad()

        #Une série de flux
        # forward + backward + optimize
        outputs = net(inputs)
        
        #Ici Cross pour les données d'étiquette-L'entropie est prise
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        #Affichage de la perte
        # 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')

Jusqu'à ce point, le code est également placé ci-dessous, veuillez donc vous y référer. Tutoriel Pytorch

Transfert et conservation de modèles

Modèle de charge

Puisque resnet etc. sont inclus par défaut, il peut être lu

#Chargement d'un modèle depuis resnet
model_ft = models.resnet18(pretrained=True)

Fine Tuning Vous pouvez également figer le modèle et réécrire la couche finale

#Gel du modèle pré-entraîné
for param in model_conv.parameters():
    param.requires_grad = False

#Réécrire les paramètres uniquement dans la dernière couche du modèle
num_ftrs = model_conv.fc.in_features
model_conv.fc = nn.Linear(num_ftrs, 2)

Enregistrer et charger le modèle

Sauvegarder le modèle

torch.save(model.state_dict(), 'model.pth')

Chargement du modèle

param = torch.load('model.pth')
model = Net() #Nécessite une déclaration de classe avant le chargement
model.load_state_dict(param)

L'exemple de code lié à l'apprentissage par transfert est le suivant Apprentissage du transfert Pytorch

Personnaliser

Fonction d'activation personnalisée

Vous pouvez définir la classe comme ci-dessous et écrire sur l'avant et l'arrière.

class MyReLU(torch.autograd.Function):
    
    #Seules la fonction d'activation avant et le calcul arrière doivent être décrits.
    def forward(self, input):
        
        #Mémoire de valeur
        self.save_for_backward(input)
        
        #Définition d'une partie de ReLU
        #x.clamp(min=0) <=> max(x, 0)
        return input.clamp(min=0)

    #Description de la rétropropagation
    #Renvoyez simplement les informations de gradient
    def backward(self, grad_output):

        #Rappel de l'appel Tensor
        input, = self.saved_tensors
        
        #Copier pour qu'il ne soit pas passé par référence
        grad_input = grad_output.clone()
        
        #input<0 => 0  else input
        grad_input[input < 0] = 0
        return grad_input

Fonction de perte auto-fabriquée

Si vous définissez une classe pour la fonction Loss et écrivez init et forward, cela fonctionnera.

class TripletMarginLoss(nn.Module):

def __init__(self, margin):
    super(TripletMarginLoss, self).__init__()
    self.margin = margin

def forward(self, anchor, positive, negative):
    dist = torch.sum(
        torch.pow((anchor - positive),2) - torch.pow((anchor - negative),2),
        dim=1) + self.margin
    dist_hinge = torch.clamp(dist, min=0.0)  #max(dist, 0.0)Équivalent à
    loss = torch.mean(dist_hinge)
    return loss

Réseau dynamique

Puisqu'il s'agit d'un format défini par exécution, vous pouvez réorganiser les couches par branchement conditionnel dans la partie avant.

class DynamicNet(torch.nn.Module):
    
    #Définition de la couche
    def __init__(self, D_in, H, D_out):
        super(DynamicNet, self).__init__()
        self.input_linear = torch.nn.Linear(D_in, H)
        self.middle_linear = torch.nn.Linear(H, H)
        self.output_linear = torch.nn.Linear(H, D_out)

    #Aléatoire 0 couche intermédiaire~Changer en 3
    def forward(self, x):
        h_relu = self.input_linear(x).clamp(min=0)
        for _ in range(random.randint(0, 3)):
            h_relu = self.middle_linear(h_relu).clamp(min=0)
        y_pred = self.output_linear(h_relu)
        return y_pred

Le code approprié est ci-dessous Personnaliser pytorch


pytorch C'est vraiment facile à utiliser. Au Japon, il semble qu'il n'y ait que des chainers, mais je pense que c'est très facile à écrire, rapide et pratique. Tout le monde devrait essayer.

Sites référencés

--Pytorch super introduction http://qiita.com/miyamotok0105/items/1fd1d5c3532b174720cd Diverses choses sont écrites du fond du pytorch à la base

--PyTorch: Tutoriel de traduction en japonais http://caffe.classcat.com/2017/04/14/pytorch-tutorial-tensor/ Traduction japonaise du tutoriel pytorch. Est-ce une traduction automatique? C'est difficile à lire

--tripletLoss, fonction http://docs.chainer.org/en/stable/_modules/chainer/functions/loss/triplet.html Perte du tripet de Chainer. Peut être écrit dans presque la même notation avec pytorch

Recommended Posts

Introduction à Lightning Pytorch
Introduction à PyTorch (1) Différenciation automatique
[Détails (?)] Introduction au pytorch ~ CNN de CIFAR10 ~
Introduction à MQTT (Introduction)
Introduction à Scrapy (1)
Introduction à Scrapy (3)
Premiers pas avec Supervisor
Introduction à Tkinter 1: Introduction
pytorch super introduction
Introduction à PyQt
Introduction à Scrapy (2)
[Linux] Introduction à Linux
Introduction à Scrapy (4)
Introduction à discord.py (2)
[PyTorch] Introduction à la classification de documents à l'aide de BERT
[Introduction à Pytorch] J'ai joué avec sinGAN ♬
[Super introduction à l'apprentissage automatique] Découvrez les didacticiels Pytorch
Premiers pas avec le Web Scraping
[PyTorch] Introduction à la classification des documents japonais à l'aide de BERT
Introduction aux baies non paramétriques
Introduction à EV3 / MicroPython
Introduction au langage Python
Introduction à la reconnaissance d'image TensorFlow
Introduction à OpenCV (python) - (2)
[Pytorch] numpy à tenseur
Introduction à PyQt4 Partie 1
[Super introduction à l'apprentissage automatique] Découvrez les didacticiels Pytorch
Introduction à l'injection de dépendances
Introduction à Private Chainer
Introduction à PyTorch (environnement virtuel)
PyTorch Super Introduction Principes de base de PyTorch
Introduction à l'apprentissage automatique
[Introduction à Pytorch] J'ai essayé de catégoriser Cifar10 avec VGG16 ♬
AOJ Introduction à la programmation Sujet 1, Sujet 2, Sujet 3, Sujet 4
Introduction au module de papier électronique
Introduction à l'algorithme de recherche de dictionnaire
[Mémorandum d'apprentissage] Introduction à vim
opencv-python Introduction au traitement d'image
Introduction à Python Django (2) Win
Une introduction à l'apprentissage automatique
[Introduction à cx_Oracle] Présentation de cx_Oracle
Introduction à la détection des anomalies 1 principes de base
Introduction à RDB avec sqlalchemy Ⅰ
[Introduction au système] Retracement de Fibonacci ♬
Introduction à l'optimisation non linéaire (I)
Introduction à la communication série [Python]
AOJ Introduction à la programmation Sujet n ° 5, Sujet n ° 6
Introduction au Deep Learning ~ Règles d'apprentissage ~
[Introduction à Python] <liste> [modifier le 22/02/2020]
Introduction à Python (version Python APG4b)
Une introduction à la programmation Python
PyTorch Sangokushi (Ignite / Catalyst / Lightning)
[Introduction à cx_Oracle] (8e) version de cx_Oracle 8.0
Introduction à discord.py (3) Utilisation de la voix
Introduction à l'optimisation bayésienne
Apprentissage par renforcement profond 1 Introduction au renforcement de l'apprentissage