[PYTHON] J'ai essayé un réseau de neurones Π-Net qui ne nécessite pas de fonction d'activation

introduction

PyTorch a implémenté un nouveau réseau neuronal, $ \ Pi $ -Net, proposé dans l'article suivant adopté pour CVPR2020.

Chrysos, Grigorios G., et al. "\Pi- nets: Deep Polynomial Neural Networks." arXiv preprint arXiv:2003.03828 (2020).

Le code complet utilisé pour l'apprentissage se trouve sur GitHub.

Qu'est-ce que Π-Net?

Dans $ \ Pi $ -Net, le réseau est ramifié au milieu, et ** la multiplication est effectuée à l'endroit où il se joint à nouveau **. Cela représente la sortie comme un polynôme d'entrée.

Dans un réseau neuronal ordinaire, la sortie de chaque couche est rendue non linéaire en appliquant des fonctions d'activation telles que ReLU et Sigmoid. Sans la fonction d'activation, quel que soit le nombre de couches que vous augmentez le réseau, vous ne pouvez sortir que de manière linéaire vers l'entrée, ce qui n'a aucun sens.

Cependant, dans $ \ Pi $ -Net, la sortie de la couche intermédiaire est multipliée pour donner au réseau une non-linéarité, donc même si vous n'utilisez pas la fonction d'activation **, vous pouvez l'exprimer fortement en la rendant multicouche. Vous pouvez acquérir des capacités.

Plusieurs structures de réseau ont été proposées dans le document, mais cette fois nous les avons implémentées sur la base de l'une d'elles, la structure suivante.

image.png
(Extrait du journal)

Il y a Skip-connection et il a une structure comme ResNet, mais la partie où il se joint n'est pas l'addition mais la multiplication (produit adamar). Puisque la sortie du bloc précédent est au carré dans chaque bloc, en empilant des blocs $ N $, il devient un polypole de l'ordre de $ 2 ^ N $, et la puissance expressive du réseau augmente de façon exponentielle.

la mise en oeuvre

J'ai créé le modèle suivant en empilant 5 blocs dans la figure ci-dessus. Par conséquent, la sortie du réseau est représentée par un ordre polymorphe de $ 2 ^ 5 = 32 $. Notez que nous n'utilisons aucune fonction d'activation.

model


class PolyNet(nn.Module):
    def __init__(self, in_channels=1, n_classes=10):
        super().__init__()
        N = 16
        kwds1 = {"kernel_size": 4, "stride": 2, "padding": 1}
        kwds2 = {"kernel_size": 2, "stride": 1, "padding": 0}
        kwds3 = {"kernel_size": 3, "stride": 1, "padding": 1}
        self.conv11 = nn.Conv2d(in_channels, N, **kwds3)
        self.conv12 = nn.Conv2d(in_channels, N, **kwds3)
        self.conv21 = nn.Conv2d(N, N * 2, **kwds1)
        self.conv22 = nn.Conv2d(N, N * 2, **kwds1)
        self.conv31 = nn.Conv2d(N * 2, N * 4, **kwds1)
        self.conv32 = nn.Conv2d(N * 2, N * 4, **kwds1)
        self.conv41 = nn.Conv2d(N * 4, N * 8, **kwds2)
        self.conv42 = nn.Conv2d(N * 4, N * 8, **kwds2)
        self.conv51 = nn.Conv2d(N * 8, N * 16, **kwds1)
        self.conv52 = nn.Conv2d(N * 8, N * 16, **kwds1)

        self.fc = nn.Linear(N * 16 * 3 * 3, n_classes)

    def forward(self, x):
        h = self.conv11(x) * self.conv12(x)
        h = self.conv21(h) * self.conv22(h)
        h = self.conv31(h) * self.conv32(h)
        h = self.conv41(h) * self.conv42(h)
        h = self.conv51(h) * self.conv52(h)
        h = self.fc(h.flatten(start_dim=1))

        return h

résultat

J'ai appris la classification du MNIST et du CIFAR-10.

MNIST Accuracy Screenshot from 2020-03-31 23-22-56.png

Loss Screenshot from 2020-03-31 23-22-44.png

Exactitude du test d'environ 99%!

CIFAR-10 Accuracy Screenshot from 2020-03-31 23-19-35.png

Loss Screenshot from 2020-03-31 23-20-46.png

Le test est précis à environ 70%, mais vous surapprenez ...

en conclusion

Puisque la sortie est une entrée polymorphe, nous avons pu apprendre sans utiliser la fonction d'activation.

Comme mentionné ci-dessus, l'expressivité s'améliore de façon exponentielle en empilant des blocs, On sait que même les réseaux de neurones ordinaires améliorent leur expressivité de manière exponentielle par rapport au nombre de couches [^ 1], donc honnêtement, je n'ai pas vraiment compris les avantages de $ \ Pi $ -Net ...

Recommended Posts

J'ai essayé un réseau de neurones Π-Net qui ne nécessite pas de fonction d'activation
J'ai essayé de créer une fonction de dictionnaire insensible à la casse
J'ai essayé de mettre en œuvre le modèle de base du réseau neuronal récurrent
J'ai fait un générateur de réseau neuronal qui fonctionne sur FPGA
Présentation de JustPy, un framework Web de haut niveau qui ne nécessite pas de programmation frontale
Création d'un modèle de discrimination d'image (cifar10) à l'aide d'un réseau neuronal convolutif
J'ai essayé d'installer un pilote pour une carte réseau qui n'est pas reconnue par Linux
Enroulement de tigre qui ne provoque pas d'accident
J'ai essayé de résumer quatre méthodes d'optimisation de réseau neuronal
Python: j'ai essayé menteur et honnête
[Linux] Comment installer un package sur un serveur qui n’a pas d’environnement Internet (autonome)
Jetons un coup d'œil à CornerNet, un détecteur d'objets qui n'utilise pas d'ancres.
J'ai essayé un réseau de neurones convolutifs (CNN) avec un tutoriel TensorFlow sur Cloud9-Classification des images manuscrites-
Créez une application Web qui reconnaît les nombres avec un réseau neuronal
J'ai essayé "un programme qui supprime les déclarations en double en Python"
J'ai essayé un peu le comportement de la fonction zip
J'ai essayé de classer la musique en majeur / mineur sur Neural Network
Construction d'un réseau neuronal qui reproduit XOR par Z3
J'ai essayé d'implémenter une méthode pour calculer l'indice d'évaluation (spécificité, NPV) que scikit-learn n'a pas
Décorateur qui notifie sur AWS-SNS si la fonction ne se termine pas dans le délai spécifié