CONV1D processus de fonctionnement du réseau neuronal convolutif unidimensionnel (par exemple : n lignes et 3 colonnes ➡ n lignes et 6 colonnes)

Auteur : CSDN @ _Yakult_


arrière-plan

Le processus de fonctionnement de la convolution unidimensionnelle n'est pas clair pour de nombreuses personnes sur Internet, et le schéma de principe n'est pas clair. Par conséquent, j'ai dessiné le processus de calcul pour le processus de convolution unidimensionnel et expliqué le mécanisme de la fonction Conv1d() dans pytorch avec mes connaissances.


Processus de calcul Conv1d()

Supposons que nous ayons maintenant n lignes et 3 colonnes de données. n lignes peuvent être n points ou n données d'échantillon. Les 3 colonnes peuvent être considérées comme 3 colonnes de caractéristiques, c'est-à-dire des vecteurs de caractéristiques. Si nous voulons le mettre à niveau de 3 colonnes à 6 dimensions via MLP, nous devons utiliser la fonction Conv1d(). Le processus spécifique consiste à multiplier chaque ligne de points de données par un noyau de convolution pour obtenir un nombre, et 6 noyaux de convolution sont 6 nombres, changeant ainsi 3 colonnes d'un point en 6 colonnes. Ensuite, parcourez chaque point ligne par ligne pour obtenir une nouvelle matrice de score.

Remarques : Pour passer de 6 colonnes à 12 colonnes, il suffit de multiplier 12 noyaux de convolution. De 12 colonnes à 6 colonnes, il suffit de multiplier 6 noyaux de convolution.


Diagramme du processus de calcul Conv1d()

①. La première ligne de données participe à la convolution (ici a est l'échantillon de données , W est le noyau de convolution et f est le résultat ).

②, la deuxième ligne de données participe à la convolution

③. La nième ligne de données participe à la convolution


Exemple de code Conv1d()

Prenons comme exemple le modèle backbone (perceptron multicouche, MLP) classé dans PointNet. Conv1d(64, 128, 1) utilise en fait 128 noyaux de convolution avec 64 lignes et 1 colonne et la matrice avec n lignes et 64 colonnes ligne par ligne Produit scalaire, mise à l'échelle jusqu'à 128 colonnes.

class STNkd(nn.Module):
    def __init__(self, k=64):
        super(STNkd, self).__init__()
        self.conv1 = torch.nn.Conv1d(k, 64, 1)
        self.conv2 = torch.nn.Conv1d(64, 128, 1)
        self.conv3 = torch.nn.Conv1d(128, 1024, 1)
        self.fc1 = nn.Linear(1024, 512)
        self.fc2 = nn.Linear(512, 256)
        self.fc3 = nn.Linear(256, k*k)
        self.relu = nn.ReLU()

        self.bn1 = nn.BatchNorm1d(64)
        self.bn2 = nn.BatchNorm1d(128)
        self.bn3 = nn.BatchNorm1d(1024)
        self.bn4 = nn.BatchNorm1d(512)
        self.bn5 = nn.BatchNorm1d(256)

        self.k = k

    def forward(self, x):
        batchsize = x.size()[0]
        x = F.relu(self.bn1(self.conv1(x)))
        x = F.relu(self.bn2(self.conv2(x)))
        x = F.relu(self.bn3(self.conv3(x)))
        x = torch.max(x, 2, keepdim=True)[0]
        x = x.view(-1, 1024)

        x = F.relu(self.bn4(self.fc1(x)))
        x = F.relu(self.bn5(self.fc2(x)))
        x = self.fc3(x)

        iden = Variable(torch.from_numpy(np.eye(self.k).flatten().astype(np.float32))).view(1,self.k*self.k).repeat(batchsize,1)
        if x.is_cuda:
            iden = iden.cuda()
        x = x + iden
        x = x.view(-1, self.k, self.k)
        return x

Principe de Linéaire()

C'est la solution Y = X · AT + b. où AT est la matrice de transposition de la matrice de pondération et b est la matrice de biais. nn.Linear(1024, 512) consiste à réduire la matrice X à n lignes et 1024 colonnes à une matrice à n lignes et 512 colonnes. Tant que AT est une matrice avec 1024 lignes et 512 colonnes, multipliez-la par X, vous pouvez obtenir une matrice avec n lignes et 512 colonnes pour atteindre l'objectif de réduction de la dimensionnalité.
①, calcul Linear() (ignorer la matrice de biais)
insérez la description de l'image ici

Animation linéaire()

insérez la description de l'image ici


La différence entre Conv1d() et Linear()

Quelqu'un a comparé la différence entre les deux sous les mêmes données d'entrée : (1) Linear() est plus rapide que conv1d() ; (2) Conv1d() est plus précis que Linear(); (3 ) Lors de la rétropropagation pour mettre à jour le gradient , les valeurs sont différentes.
Alors pourquoi est-il conçu de cette façon ? Après avoir vérifié de nombreuses informations, je pense que cette réponse est la plus fiable. Conv1d() est utilisé lorsque vous devez conserver des informations spatiales dans la segmentation sémantique. Lorsque vous n'avez rien à faire concernant les informations spatiales, comme dans la classification de base (classificateur mnist, chat et chien), utilisez la couche linéaire Linear().

Conv1d Linéaire
Connaissance préalable ont aucun
paramètres partagés ont aucun
vitesse de course lent rapide
informations spatiales ont aucun
effet ingénierie des fonctionnalités Classificateur

noyau de convolution

Prenez PointNet comme exemple, imprimez le noyau de convolution pour vérifier la forme du noyau de convolution, veuillez consulter mon autre article. Le lien est le suivant,
https://blog.csdn.net/qq_35591253/article/details/127671790

Je suppose que tu aimes

Origine blog.csdn.net/qq_35591253/article/details/126668130
conseillé
Classement