54 votes

Comment faire du détourage de gradient dans pytorch ?

Quelle est la manière correcte d'effectuer l'écrêtage du gradient dans pytorch ?

J'ai un problème de gradients explosifs, et je dois programmer pour le contourner.

0 votes

4 votes

@pierrom Merci. J'ai trouvé ce fil moi-même. J'ai pensé que le fait de le demander ici éviterait à tous ceux qui viennent après moi et qui cherchent une réponse rapide sur Google de devoir lire toute la discussion (que je n'ai pas encore terminée moi-même), et qu'ils obtiendraient simplement une réponse rapide, à la manière de stackoverflow. Aller sur les forums pour trouver des réponses me rappelle 1990. Si personne d'autre ne poste la réponse avant moi, je le ferai dès que je l'aurai trouvée.

120voto

Rahul Points 6

Un exemple plus complet

optimizer.zero_grad()        
loss, hidden = model(data, hidden, targets)
loss.backward()

torch.nn.utils.clip_grad_norm_(model.parameters(), args.clip)
optimizer.step()

Source : https://github.com/pytorch/pytorch/issues/309

1 votes

Pourquoi est-ce plus complet ? Je vois le plus de votes, mais je ne comprends pas vraiment pourquoi c'est mieux. Pouvez-vous m'expliquer ?

10 votes

Cela suit simplement un modèle populaire, où l'on peut insérer torch.nn.utils.clip_grad_norm_(model.parameters(), args.clip) entre la perte.backward() et l'optimiseur.step()

56voto

a_guest Points 5059

clip_grad_norm (qui est en fait déprécié au profit de l'option clip_grad_norm_ en suivant la syntaxe plus cohérente d'une terminaison _ lorsque la modification en place est effectuée) clive la norme de la global gradient en concaténant tous les paramètres passés à la fonction, comme on peut le voir dans l'exemple suivant la documentation :

La norme est calculée sur tous les gradients ensemble, comme s'ils étaient concaténés en un seul vecteur. Les gradients sont modifiés sur place.

D'après votre exemple, il semble que vous vouliez clip_grad_value_ à la place, qui a une syntaxe similaire et modifie également les gradients in-place :

clip_grad_value_(model.parameters(), clip_value)

Une autre option consiste à enregistrer un crochet arrière . Il prend le gradient actuel en entrée et peut retourner un tenseur qui sera utilisé à la place du gradient précédent, c'est-à-dire en le modifiant. Ce hook est appelé chaque fois qu'un gradient a été calculé, c'est-à-dire qu'il n'y a pas besoin d'écrêter manuellement une fois que le hook a été enregistré :

for p in model.parameters():
    p.register_hook(lambda grad: torch.clamp(grad, -clip_value, clip_value))

10voto

Gulzar Points 620

Lire à travers la discussion du forum a donné ça :

clipping_value = 1 # arbitrary value of your choosing
torch.nn.utils.clip_grad_norm(model.parameters(), clipping_value)

Je suis sûr qu'il y a plus de profondeur que ce simple extrait de code.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X