web-dev-qa-db-fra.com

recherche du code source de gen_nn_ops dans tensorflow

Je suis novice en tensorflow pour l'apprentissage en profondeur et je m'intéresse aux opérations de déconvolution (transposition par convolution) dans tensorflow. Je dois jeter un œil au code source pour opérer la déconvolution. La fonction est je suppose conv2d_transpose () dans nn_ops.py .

Cependant, dans la fonction, il appelle une autre fonction appelée gen_nn_ops.conv2d_backprop_input(). Je dois jeter un œil à ce qui se trouve à l'intérieur de cette fonction, mais je ne parviens pas à le trouver dans le référentiel. Toute aide serait appréciée.

27
HojjaxX

Vous ne pouvez pas trouver cette source car la source est automatiquement générée par bazel. Si vous construisez à partir des sources, vous verrez ce fichier dans bazel-genfiles. Il est également présent dans votre distribution locale que vous pouvez trouver en utilisant le module inspect. Le fichier contient des enveloppes Python générées automatiquement pour les implémentations C++ sous-jacentes, donc il se compose essentiellement d'un tas de fonctions de 1 ligne. Un raccourci pour trouver l'implémentation C++ sous-jacente de ces Python op est de convertir l'étui à serpent en étui à chameau, c'est-à-dire conv2d_backprop_input -> Conv2dBackpropInput

# figure out where gen_nn_ops is
print(tf.nn.conv2d_transpose.__globals__['gen_nn_ops'])

from tensorflow.python.ops import gen_nn_ops
import inspect
inspect.getsourcefile('gen_nn_ops.conv2d_backprop_input')
'/Users/yaroslav/anaconda/lib/python3.5/site-packages/tensorflow/python/ops/gen_nn_ops.py'

Si vous souhaitiez découvrir comment ce fichier a réellement vu le jour, vous pouvez suivre la trace des dépendances bazel dans les fichiers BUILD. Pour trouver la cible Bazel qui l'a générée à partir de l'arbre source tensorflow:

fullname=$(bazel query tensorflow/python/ops/gen_nn_ops.py)
bazel query "attr('srcs', $fullname, ${fullname//:*/}:*)"

//tensorflow/python:nn_ops_gen

Alors maintenant, allons dans le fichier BUILD dans tensorflow/python vous voyez qu'il s'agit d'une cible de type tf_gen_op_wrapper_private_py qui est défini ici et appelle gen_op_wrapper_py de tensorflow/tensorflow.bzl qui ressemble à ceci

def tf_gen_op_wrapper_py(name, out=None, hidden=None, visibility=None, deps=[],
....
      native.cc_binary(
      name = tool_name,

Cette native.cc_binary construct est un moyen d'avoir une cible Bazel qui représente l'exécution d'une commande arbitraire. Dans ce cas, il appelle tool_name avec quelques arguments. Avec quelques étapes supplémentaires, vous pouvez trouver que "l'outil" ici est compilé à partir de framework/python_op_gen_main.cc

La raison de cette complication est que TensorFlow a été conçu pour être indépendant du langage. Donc, dans le monde idéal, vous auriez chaque opération décrite dans ops.pbtxt , puis chaque opération aurait une implémentation par type de matériel en utilisant REGISTER_KERNEL_BUILDER, donc toutes les implémentations se feraient en C++/CUDA/Assembly et deviendraient automatiquement disponibles pour tous les frontaux du langage. Il y aurait un traducteur équivalent comme "python_op_gen_main" pour chaque langue et tout le code de la bibliothèque client serait généré automatiquement. Cependant, parce que Python est tellement dominant, il y avait une pression pour ajouter des fonctionnalités du côté Python. Il y a donc maintenant deux types d'opérations - les opérations TensorFlow pures) vu dans des fichiers comme gen_nn_ops.py, et opérations Python uniquement dans des fichiers comme nn_ops.py qui encapsule généralement les fichiers générés automatiquement par les opérations gen_nn_ops.py mais ajoutez des fonctionnalités/sucre de syntaxe supplémentaires. De plus, à l'origine, tous les noms étaient camel-case, mais il a été décidé que la version publique devrait être conforme à PEP avec une syntaxe plus courante Python, c'est donc une raison pour camel-case/snake-case non concordance entre les interfaces C++/Python du même op

40
Yaroslav Bulatov

Malheureusement, le code TensorFlow n'est pas facile à lire :(

Pour accélérer les choses, le code python doit entrelacer du code C++, qui utilise également des dépendances indirectes.

gen_X les fonctions sont générées à partir de leur code C++; pour le trouver, vous devez rechercher Conv2dBackpropInput.

Vous pouvez trouver l'enregistrement de l'op du noyau dans ops/nn_ops.cc et l'implémentation concrète dans kernels/conv_grad_input_ops.cc .

7
sygi

Ce fichier est généré lorsque vous générez Tensorflow. Après avoir créé la source Tensorflow, vous devriez voir un fichier de lien symbolique nommé "bazel-genfiles" dans le répertoire racine tensorflow, et allez à l'emplacement qu'il pointe, puis vous pouvez le trouver sur tensorflow/python/ops/gen_nn_ops.py

2
Jason