[PYTHON] Résumé de l'implémentation de scratch 1D-CNN, 2D-CNN par Pytorch

introduction

Cela fait environ six mois que je suis passé de TensorFlow à Pytorch, je vais donc résumer les bases. Cette fois, je voudrais me concentrer sur les trois points suivants.

  1. Utilisation du modèle de préapprentissage 2.1 Mise en œuvre de DCNN 3.2 Mise en œuvre de DCNN

1. Utilisation du modèle de préapprentissage

Les modèles pré-formés actuellement disponibles sont:

Cliquez ici pour plus de détails

Lorsque vous utilisez le modèle entraîné dans ImageNet, procédez comme suit.

import torchvision
model = torchvision.models.alexnet(pretrained=True)

--Si vous souhaitez vérifier la structure du modèle, vous pouvez le vérifier avec print (model). Voici le résultat de l'exécution.

AlexNet(
  (features): Sequential(
    (0): Conv2d(3, 64, kernel_size=(11, 11), stride=(4, 4), padding=(2, 2))
    (1): ReLU(inplace=True)
    (2): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
    (3): Conv2d(64, 192, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
    (4): ReLU(inplace=True)
    (5): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
    (6): Conv2d(192, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (7): ReLU(inplace=True)
    (8): Conv2d(384, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (9): ReLU(inplace=True)
    (10): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (11): ReLU(inplace=True)
    (12): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
  )
  (avgpool): AdaptiveAvgPool2d(output_size=(6, 6))
  (classifier): Sequential(
    (0): Dropout(p=0.5, inplace=False)
    (1): Linear(in_features=9216, out_features=4096, bias=True)
    (2): ReLU(inplace=True)
    (3): Dropout(p=0.5, inplace=False)
    (4): Linear(in_features=4096, out_features=4096, bias=True)
    (5): ReLU(inplace=True)
    (6): Linear(in_features=4096, out_features=1000, bias=True)
  )
)

Si vous souhaitez classer par vos propres données, modifiez comme suit. Prenons l'exemple de la classification à deux classes.

model.classifier[6].out_features = 2

Si vous exécutez à nouveau print (model), vous pouvez voir qu'il a changé.

AlexNet(
  (features): Sequential(
    (0): Conv2d(3, 64, kernel_size=(11, 11), stride=(4, 4), padding=(2, 2))
    (1): ReLU(inplace=True)
    (2): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
    (3): Conv2d(64, 192, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
    (4): ReLU(inplace=True)
    (5): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
    (6): Conv2d(192, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (7): ReLU(inplace=True)
    (8): Conv2d(384, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (9): ReLU(inplace=True)
    (10): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (11): ReLU(inplace=True)
    (12): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
  )
  (avgpool): AdaptiveAvgPool2d(output_size=(6, 6))
  (classifier): Sequential(
    (0): Dropout(p=0.5, inplace=False)
    (1): Linear(in_features=9216, out_features=4096, bias=True)
    (2): ReLU(inplace=True)
    (3): Dropout(p=0.5, inplace=False)
    (4): Linear(in_features=4096, out_features=4096, bias=True)
    (5): ReLU(inplace=True)
    (6): Linear(in_features=4096, out_features=2, bias=True)
  )
)

2.1 Mise en œuvre de DCNN

Passons maintenant au sujet principal. Cette fois, nous allons implémenter 1D CNN avec scratch. Voici un exemple simple.

import torch
import torch.nn as nn


class Net1D(nn.Module):
    def __init__(self):
        super(SimpleNet,self).__init__()

        self.conv1 = nn.Conv1d(1, 8,kernel_size=3, stride=1)
        self.bn1 = nn.BatchNorm1d(8)
        self.relu = nn.ReLU()
        self.maxpool = nn.MaxPool1d(kernel_size=3, stride=2)

        self.conv2 = nn.Conv1d(8, 16,kernel_size=3, stride=1)
        self.bn2 = nn.BatchNorm1d(16)
        self.conv3 = nn.Conv1d(16,64,kernel_size=3, stride=1)
        self.gap = nn.AdaptiveAvgPool1d(1)
        self.fc = nn.Linear(64,2)


    def forward(self,x):

        x = self.conv1(x)
        x = self.bn1(x)
        x = self.relu(x)
        x = self.maxpool(x)

        x = self.conv2(x)
        x = self.bn2(x)
        x = self.relu(x)
        x = self.maxpool(x)

        x = self.conv3(x)
        x = self.gap(x)
        x = x.view(x.size(0),-1)
        x = self.fc(x)
 
        return x


Si vous voulez voir si ce modèle fonctionne, essayez ce qui suit:


model = SimpleNet()
in_data = torch.randn(8,1,50)
out_data = model(data)
print(out_size.size()) #torch.Size([8, 2])

--Préparez les données d'entrée appropriées avec torch.randn (). ← Cette méthode est pratique! Il peut également être appliqué en 2D!

===============================================================

À propos du fait que le résumé de la torche peut être utilisé sérieusement lors de la construction d'un modèle avec Pytorch

===============================================================

【nn.Conv1d】

nn.Conv1d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode='zeros')
parameters Aperçu
in_channels Nombre de canaux d'entrée.
out_channels Nombre de canaux après convolution. Nombre de filtres.
kernel_size La taille du noyau.
stride De combien déplacer le noyau.
padding La taille du rembourrage. Si 1 est spécifié, il sera inséré aux deux extrémités, donc il sera augmenté de 2. La valeur par défaut est 0.
dilation Modifiez l'espace entre les filtres. Utilisé dans atrous conv, etc.
groups La valeur par défaut est 1. L'augmentation du nombre réduit le coût du calcul.
bias S'il faut inclure les préjugés. La valeur par défaut est True
padding_mode Mode de remplissage. La valeur par défaut est 0.

【nn.BatchNorm1d】

nn.BatchNorm1d(num_features, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)

Il est possible de saisir le même nombre de «num_features» que la valeur de «out_channels» de la couche précédente.

3. CNN 2D

J'ai écrit un simple échantillon CNN. Cette fois, le nombre de filtres et la taille du noyau sont décidés de manière appropriée. Si vous créez votre propre réseau, tenez compte des valeurs au moment de décider.


import torch
import torch.nn as nn

class Net2D(nn.Module):
    def __init__(self):
        super(Net,self).__init__()

        self.conv1 = nn.Conv2d(3,16,kernel_size=3,stride=2)
        self.bn1 = nn.BatchNorm2d(16)
        self.relu = nn.ReLU()
        self.maxpool = nn.MaxPool2d(2)
        self.conv2 = nn.Conv2d(16,32,kernel_size=3,stride=2)
        self.bn2 = nn.BatchNorm2d(32)
        self.conv3 = nn.Conv2d(32,64,kernel_size=3,stride=2)
        self.gap = nn.AdaptiveAvgPool2d(1)
        self.fc1 = nn.Linear(64,32)
        self.fc2 = nn.Linear(32,2)


    def forward(self,x):

        x = self.conv1(x)
        x = self.bn1(x)
        x = self.relu(x)
        x = self.maxpool(x)

        x = self.conv2(x)
        x = self.bn2(x)
        x = self.relu(x)
        x = self.maxpool(x)

        x = self.conv3(x)
        x = self.gap(x)
        x = x.view(x.size(0),-1)
        x = self.fc1(x)
        x = self.fc2(x)
        return x

--forward détermine la structure du modèle.

【nn.Conv2d】


nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode='zeros')
parameters Aperçu
in_channels Nombre de canaux d'entrée. Il devient 3 dans l'image RVB.
out_channels Nombre de canaux après convolution. Nombre de filtres.
kernel_size La taille du noyau.
stride De combien déplacer le noyau.
padding La taille du rembourrage. Si 1 est spécifié, il sera inséré aux deux extrémités, donc il sera augmenté de 2. La valeur par défaut est 0.
dilation Modifiez l'espace entre les filtres. Utilisé dans atrous conv, etc.
groups La valeur par défaut est 1. L'augmentation du nombre réduit le coût du calcul.
bias S'il faut inclure les préjugés. La valeur par défaut est True
padding_mode Mode de remplissage. La valeur par défaut est 0.

【nn.BatchNorm2d】

nn.BatchNorm2d(num_features, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)

--Il y a aussi Layer Norm, ʻInstance Norm, Group Norm`, etc.

【nn.ReLU】

nn.ReLU(inplace=False)

【nn.MaxPool2d】

nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)

Utilisez une couche de regroupement pour mettre en valeur les caractéristiques.

――Il y a environ deux modèles, alors vérifiez ci-dessous.

① Lorsque la taille de la piscine est carrée

m = nn.MaxPool2d(3, stride=2)  #(pool of square window of size=3, stride=2)

② Lorsque vous souhaitez personnaliser la taille de la piscine

m = nn.MaxPool2d((3, 2), stride=(2, 1)) #(pool of non-square window)

【nn.AdaptiveMaxPool2d】

nn.AdaptiveMaxPool2d(output_size, return_indices=False)

Souvent appelé «Global Max Pooling». Il est souvent utilisé avant de se connecter à une couche entièrement connectée, car il fait de chaque canal une valeur unique. Mettez la taille de sortie d'un canal dans ʻoutput_size. Je pense que ʻoutput_size = 1 est souvent utilisé.

【nn.Linear】


nn.Linear(in_features, out_features, bias=True)

Spécifiez les fonctionnalités in_features et out_features à utiliser. Utilisez-le lors de la mise en œuvre d'une couche entièrement connectée.

À la fin

Cela fait environ six mois que j'ai déménagé à Pytorch et c'est très facile à utiliser. J'espère que cet article vous sera utile.

Les références

Recommended Posts

Résumé de l'implémentation de scratch 1D-CNN, 2D-CNN par Pytorch
Résumé de l'implémentation de base par PyTorch
Résumé Faker par langue
Résumé de l'implémentation de la coroutine empilée
Résumé de l'implémentation de l'interpréteur 7 lignes
Sauvegardez la sortie de GAN une par une ~ Avec l'implémentation de GAN par PyTorch ~
pandas Matplotlib Résumé par utilisation
Résumé de la méthode d'implémentation Unity IAP