[J'ajoute cela comme une nouvelle réponse, car il est une autre solution.]
Notez que déconvolution dans l'apprentissage en profondeur est également connu comme « convolution transposée », ce qui signifie que c'est la même chose que faire une convolution régulière mais avec les noyaux horizontalement et verticalement retournés. Vous devriez donc être en mesure d'utiliser une couche MPSCNNConvolution
qui prend le MPSImage
que vous souhaitez déconvoluer en entrée, et qui utilise les mêmes noyaux que l'étape de convolution «forward», mais inversée horizontalement et verticalement. L'avantage de faire cela en écrivant votre propre noyau de calcul est que vous pouvez utiliser les noyaux très rapides de MPS.
Édition: Un exemple. Disons que votre poids du noyau de conv ressemblent à ceci:
1, 2, 3
4, 5, 6
7, 8, 9
Puis, après retournement du noyau, les poids se présentent comme suit:
9, 8, 7
6, 5, 4
3, 2, 1
En d'autres termes, vous devez faire une copie de votre tableau de poids et inversez-le. En mémoire les premiers poids ressemblent à ceci:
1, 2, 3, 4, 5, 6, 7, 8, 9
Le noyau basculée ressemble à ceci en mémoire, il est tout simplement le noyau d'origine, mais dans l'ordre inverse:
9, 8, 7, 6, 5, 4, 3, 2, 1
Ensuite, vous faites une nouvelle couche de convolution en utilisant ce tableau inversé. C'est maintenant votre couche de déconv.
Je n'ai pas d'exemple de code Metal pour vous montrer, mais ce n'est vraiment pas différent de créer un calque MPSCNNConvolution
. Vous avez juste à inverser les poids pour la couche.
Oui, je le sais. Avez-vous des exemples sur comment passer 'MPSImage' comme paramètre et travailler avec lui dans la fonction' kernel'? – s1ddok
Vous ne transmettez pas 'MPSImage' directement. Au lieu de cela, vous utilisez 'image.texture', comme je l'ai fait dans l'exemple de code. Si vous avez <= 4 canaux alors la texture est juste un objet de texture unique; avec> 4 canaux c'est en fait un tableau de textures. –