Une seule couche
Pour initialiser les poids d'une seule couche, utilisez une fonction de torch.nn.init
. Par exemple:
conv1 = torch.nn.Conv2d(...)
torch.nn.init.xavier_uniform(conv1.weight)
Vous pouvez également modifier les paramètres en écrivant dans conv1.weight.data
(qui est a torch.Tensor
). Exemple:
conv1.weight.data.fill_(0.01)
Il en va de même pour les biais:
conv1.bias.data.fill_(0.01)
nn.Sequential
ou personnalisé nn.Module
Passez une fonction d'initialisation à torch.nn.Module.apply
. Il initialisera les poids dans l'ensemble de nn.Module
manière récursive.
apply ( fn ): S'applique de fn
manière récursive à chaque sous-module (tel que renvoyé par .children()
) ainsi qu'à self. L'utilisation typique comprend l'initialisation des paramètres d'un modèle (voir aussi torch-nn-init).
Exemple:
def init_weights(m):
if type(m) == nn.Linear:
torch.nn.init.xavier_uniform(m.weight)
m.bias.data.fill_(0.01)
net = nn.Sequential(nn.Linear(2, 2), nn.Linear(2, 2))
net.apply(init_weights)
reset_parameters
méthode dans le code source de nombreux modules. Dois-je remplacer la méthode d'initialisation du poids?Nous comparons différents modes d'initialisation de poids en utilisant la même architecture de réseau neuronal (NN).
Tous les zéros ou les uns
Si vous suivez le principe du rasoir d'Occam , vous pourriez penser que régler tous les poids à 0 ou 1 serait la meilleure solution. Ce n'est pas le cas.
Avec chaque poids identique, tous les neurones de chaque couche produisent la même sortie. Cela rend difficile le choix des poids à ajuster.
Initialisation uniforme
Une distribution uniforme a la même probabilité de choisir n'importe quel nombre parmi un ensemble de nombres.
Voyons à quel point le réseau de neurones s'entraîne en utilisant une initialisation de poids uniforme, où
low=0.0
ethigh=1.0
.Ci-dessous, nous verrons une autre façon (en plus du code de classe Net) d'initialiser les poids d'un réseau. Pour définir des poids en dehors de la définition du modèle, nous pouvons:
Règle générale pour le réglage des poids
La règle générale pour définir les poids dans un réseau de neurones est de les définir pour qu'ils soient proches de zéro sans être trop petits.
ci-dessous nous comparons les performances de NN, les poids initialisés avec une distribution uniforme [-0,5,0,5) par rapport à celui dont le poids est initialisé en utilisant la règle générale
distribution normale pour initialiser les poids
ci-dessous, nous montrons les performances de deux NN, l'un initialisé avec une distribution uniforme et l'autre avec une distribution normale
la source
Pour initialiser les couches, vous n'avez généralement rien à faire.
PyTorch le fera pour vous. Si vous y réfléchissez, cela a beaucoup de sens. Pourquoi devrions-nous initialiser les couches, alors que PyTorch peut le faire en suivant les dernières tendances.
Vérifiez par exemple le calque linéaire .
Dans la
__init__
méthode, il appellera la fonction d'initialisation de Kaiming He .La même chose est pour les autres types de couches. Par
conv2d
exemple, vérifiez ici .A noter: le gain d'une bonne initialisation est la vitesse d'entraînement plus rapide. Si votre problème mérite une initialisation spéciale, vous pouvez le faire après.
la source
xavier_uniform
initialisation pour les poids (avec des biais initialisés à 0), plutôt que d'utiliser l'initialisation par défaut, ma précision de validation après 30 les époques de RMSprop sont passées de 82% à 86%. J'ai également obtenu une précision de validation de 86% lors de l'utilisation du modèle VGG16 intégré de Pytorch (non pré-formé), donc je pense que je l'ai implémenté correctement. (J'ai utilisé un taux d'apprentissage de 0,00001.)la source
Désolé d'être si tard, j'espère que ma réponse vous aidera.
Pour initialiser les poids avec une
normal distribution
utilisation:Ou pour utiliser une
constant distribution
écriture:Ou pour utiliser un
uniform distribution
:Vous pouvez vérifier d'autres méthodes pour initialiser les tenseurs ici
la source
Si vous souhaitez une flexibilité supplémentaire, vous pouvez également définir les poids manuellement .
Disons que vous avez une entrée pour tous:
Et vous voulez créer une couche dense sans biais (afin que nous puissions visualiser):
Définissez tous les poids sur 0,5 (ou autre chose):
Les poids:
Tous vos poids sont maintenant de 0,5. Transmettez les données via:
Rappelez-vous que chaque neurone reçoit 8 entrées, qui ont toutes un poids de 0,5 et une valeur de 1 (et aucun biais), donc cela fait jusqu'à 4 pour chacune.
la source
Itérer sur les paramètres
Si vous ne pouvez pas utiliser
apply
par exemple si le modèle n'implémente pasSequential
directement:Pareil pour tous
Selon la forme
Vous pouvez essayer avec
torch.nn.init.constant_(x, len(x.shape))
pour vérifier qu'ils sont correctement initialisés:la source
Si vous voyez un avertissement d'obsolescence (@ Fábio Perez) ...
la source
Parce que je n'ai pas eu assez de réputation jusqu'à présent, je ne peux pas ajouter de commentaire sous
Mais je tiens à souligner qu'en fait, nous connaissons certaines hypothèses dans l'article de Kaiming He , Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification , ne sont pas appropriées, bien qu'il semble que la méthode d'initialisation délibérément conçue fasse un succès dans la pratique .
Par exemple, dans la sous-section Cas de propagation vers l'arrière , ils supposent que $ w_l $ et $ \ delta y_l $ sont indépendants l'un de l'autre. Mais comme nous le savons tous, prenons la carte des scores $ \ delta y ^ L_i $ comme instance, c'est souvent $ y_i-softmax (y ^ L_i) = y_i-softmax (w ^ L_ix ^ L_i) $ si nous utilisons un Objectif de la fonction de perte d'entropie croisée.
Je pense donc que la véritable raison sous-jacente pour laquelle He Initialization fonctionne bien reste à démêler. Parce que tout le monde a été témoin de son pouvoir de stimuler la formation en deep learning.
la source