Comment PyTorch implémente la convolution vers l'arrière?

Nov 05 2020

J'ai lu sur le code source de Pytorch, et je trouve étrange qu'il n'implémente pas la convolution_backwardfonction, la seule convolution_backward_overrideablefonction est directement lève une erreur et censée ne pas tomber ici.

J'ai donc évoqué la mise en œuvre de CuDNN / MKLDNN, ils implémentent tous les deux des fonctions telles que cudnn_convolution_backward.

J'ai la question suivante:

  1. Quelles sont les implémentations natives de CUDA / CPU? Je peux trouver quelque chose comme thnn_conv2d_backward_out, mais je n'ai pas pu trouver où cela s'appelle.

  2. Pourquoi PyTorch n'a pas mis la convolution_backwardfonction dans Convolution.cpp ? Il offre une _convolution_double_backward()fonction. Mais c'est le double en arrière, c'est le dégradé de dégradé. Pourquoi n'offrent-ils pas une seule fonction vers l'arrière?

  3. Si je veux appeler la fonction native convolution / convolution_backward pour mon tenseur pur cpu / cuda, comment dois-je écrire du code? Ou où pourrais-je me référer? Je n'ai pas trouvé d'exemple pour cela.

Merci !

Réponses

2 unlut Nov 05 2020 at 15:59

1- L'implémentation peut différer selon le backend que vous utilisez, elle peut utiliser l'implémentation de convolution CUDA à partir d'une bibliothèque, l'implémentation de convolution CPU d'une autre bibliothèque, ou une implémentation personnalisée, voir ici: pytorch - Où «conv1d» est-il implémenté? .

2- Je ne suis pas sûr de la version actuelle, mais un seul vers l'arrière a été calculé via autograd, c'est pourquoi il n'y avait pas de fonction différente explicite pour cela. Je ne connais pas les détails sous-jacents de l'autograd mais vous pouvez vérifierhttps://github.com/pytorch/pytorch/blob/master/torch/csrc/autograd/autograd.cpp. Cette fonction double_backward n'est là que si vous avez besoin de dérivés d'ordre supérieur.

3- Si vous voulez faire cela en C, le fichier que vous avez lié (convolution.cpp) vous montre comment faire cela (fonction à :: Tensor _convolution ...). Si vous inspectez la fonction, vous la voyez, elle vérifie simplement quelle implémentation utiliser (params.use_something ...) et l'utilise. Si vous voulez faire cela en python, vous devez commencer le traçage de conv jusqu'à l'endroit où ce fichier convolution.cpp est appelé.

1 Sut Nov 13 2020 at 15:57

J'ai pensé à quelque chose d'ajout au message de @ unlut.

  1. La méthode de convolution se trouve dans des fichiers séparés pour différentes implémentations. Vous pouvez trouver facilement cudnn_convoluton_backward ou mkldnn_convolution_backward. Une chose délicate est que la fonction de chute native finale est difficile à trouver. C'est parce qu'actuellement les équipes Pytorch portent la fonction Thnn vers ATen, vous pouvez vous référer à PR24507 .

La fonction native peut être trouvée comme thnn_con2d_backward .

  1. La convolution vers l'arrière n'est pas calculée via autograd, il faut plutôt une fonction conv_backward et celle-ci doit être enregistrée dans dérivés.yaml. Si vous voulez trouver une fonction arrière spécifique, reportez-vous à ce fichier est un bon début.

  2. À propos de ce code, si vous souhaitez appeler directement la fonction thnn_backward, vous devez explicitement construire finput et fgrad_input. Ce sont deux tenseurs vides offrant comme tampon.

at::Tensor finput = at::empty({0},input.options()); 
at::Tensor fgrad_input = at::empty({0}, input.options());
auto kernel_size = weight.sizes().slice(2);
auto &&result = at::thnn_conv2d_backward(grad_output, input, weight,kernel_size , stride, padding, 
finput, fgrad_input, output_mask);