68 votes

Tf.nn.conv2d vs tf.layers.conv2d

Y a-t-il un avantage à utiliser tf.nn.* plutôt que tf.layers.* ?

La plupart des exemples dans la documentation utilisent tf.nn.conv2d, par exemple, mais il n'est pas clair pourquoi ils le font.

1 votes

Y a-t-il une différence de performance?

43voto

Mircea Points 480

Comme l'a mentionné GBY, ils utilisent la même implémentation.

Il y a une légère différence dans les paramètres.

Pour tf.nn.conv2d:

filtre : Un tenseur. Doit avoir le même type que l'entrée. Un tenseur 4-D de forme [hauteur_filtre, largeur_filtre, canaux_entrée, canaux_sortie]

Pour tf.layers.conv2d:

filtres : Entier, la dimension de l'espace de sortie (c'est-à-dire le nombre de filtres dans la convolution).

Je voudrais utiliser tf.nn.conv2d lors du chargement d'un modèle pré-entraîné (exemple de code : https://github.com/ry/tensorflow-vgg16), et tf.layers.conv2d pour un modèle entraîné à partir de zéro.

3 votes

Les paramètres filter et filters sont exactement la différence !

2 votes

N'est-ce pas aussi une différence majeure que pour tf.nn.conv2d, vous devez spécifier explicitement les input_channels (comme partie du filter), alors que tf.contrib.layers.conv2d détermine apparemment cela implicitement ? Y a-t-il un cas où les input_channels sont autres que input.shape[-1] (la dernière dimension de l'entrée) ?

1 votes

@Mircea Pourquoi utiliseriez-vous tf.layers.conv2d lors de la construction d'un modèle à partir de zéro ? Alors que tf.nn.conv2d vous permettra d'initialiser les filtres ce qui accélérera le temps d'entraînement.

30voto

GBY Points 73

Pour la convolution, elles sont les mêmes. Plus précisément, tf.layers.conv2d (en fait _Conv) utilise tf.nn.convolution comme backend. Vous pouvez suivre la chaîne d'appel de : tf.layers.conv2d>Conv2D>Conv2D.apply()>_Conv>_Conv.apply()>_Layer.apply()>_Layer.\__call__()>_Conv.call()>nn.convolution()...

2 votes

Ils ne sont pas les mêmes car ils diffèrent dans la façon dont ils définissent une couche complexe (voir la réponse ci-dessous).

0 votes

Ami, vous avez créé une précondition qui est "pour la convolution". Je me demande si la couche max_pool est la même ou quelle est la différence entre elles? J'espère recevoir votre message, merci beaucoup.

13voto

EXP0 Points 180

Comme d'autres l'ont mentionné, les paramètres sont différents, en particulier les "filtres". tf.nn.conv2d prend un tenseur en tant que filtre, ce qui signifie que vous pouvez spécifier la décroissance pondérale (ou peut-être d'autres propriétés) comme suit dans le code cifar10. (Que vous souhaitez/avez besoin d'avoir une décroissance pondérale dans la couche de convolution est une autre question.)

noyau = _variable_with_weight_decay('poids',
                                     forme=[5, 5, 3, 64],
                                     stddev=5e-2,
                                     wd=0.0)
conv = tf.nn.conv2d(images, noyau, [1, 1, 1, 1], padding='SAME')

Je ne suis pas tout à fait sûr de comment définir la décroissance pondérale dans tf.layers.conv2d puisqu'il prend seulement un entier en tant que filtres. Peut-être utiliser kernel_constraint ?

D'autre part, tf.layers.conv2d gère automatiquement l'activation et le biais tandis que vous devez écrire des codes supplémentaires pour cela si vous utilisez tf.nn.conv2d.

8voto

hotvector Points 41

Toutes ces autres réponses parlent de la différence entre les paramètres, mais en réalité, la principale différence entre tf.nn et tf.layers conv2d est que pour tf.nn, vous devez créer votre propre tenseur de filtre et le passer. Ce filtre doit avoir la taille suivante : [hauteur_du_noyau, largeur_du_noyau, canaux_d'entrée, nombre_de_filtres]

Essentiellement, tf.nn est de niveau inférieur à tf.layers. Malheureusement, cette réponse n'est plus applicable car tf.layers est obsolète

2voto

rmeertens Points 2982

Regardez ici: tensorflow > tf.layers.conv2d

et ici: tensorflow > conv2d

Comme vous pouvez le voir, les arguments de la version layers sont :

tf.layers.conv2d(inputs, filters, kernel_size, strides=(1, 1), padding='valid', data_format='channels_last', dilation_rate=(1, 1), activation=None, use_bias=True, kernel_initializer=None, bias_initializer=tf.zeros_initializer(), kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, trainable=True, name=None, reuse=None)

et la version nn :

tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, data_format=None, name=None)

Je pense que vous pouvez choisir celui avec les options que vous souhaitez / avez besoin / aimez !

5 votes

J'ai lu le document, mais je me demandais simplement s'il y avait un avantage à utiliser tf.nn.conv2d + les initialiseurs et toutes les fonctionnalités fournies par tf.layer par rapport à tf.nn.layers.conv2d, par exemple si c'est plus rapide.

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