tf.nn.conv2d vs tf.layers.conv2d

¿Hay alguna ventaja en el uso de tf.nn.* sobre tf.layers.* ?

La mayoría de los ejemplos en el documento usan tf.nn.conv2d , por ejemplo, pero no está claro por qué lo hacen.

Para la convolución, son lo mismo. Más precisamente, tf.layers.conv2d (en realidad _Conv ) usa tf.nn.convolution como backend. Puede seguir la cadena de llamadas de: tf.layers.conv2d>Conv2D>Conv2D.apply()>_Conv>_Conv.apply()>_Layer.apply()>_Layer.\__call__()>_Conv.call()>nn.convolution()...

Como mencionó GBY, usan la misma implementación.

Hay una ligera diferencia en los parámetros.

Para tf.nn.conv2d:

 filter: A Tensor. Must have the same type as input. A 4-D tensor of shape [filter_height, filter_width, in_channels, out_channels] 

Para tf.layers.conv2d:

 filters: Integer, the dimensionality of the output space (ie the number of filters in the convolution). 

Yo usaría tf.nn.conv2d al cargar un modelo pre-entrenado (código de ejemplo: https://github.com/ry/tensorflow-vgg16 ), y tf.layers.conv2d para un modelo entrenado desde cero.

Como otros mencionaron, los parámetros son diferentes, especialmente el “filtro (s)”. tf.nn.conv2d toma un tensor como filtro, lo que significa que puede especificar la disminución de peso (o quizás otras propiedades) como las siguientes en el código cifar10 . (Si desea / necesita tener una disminución de peso en la capa de conv es otra pregunta).

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

No estoy muy seguro de cómo establecer la caída de peso en tf.layers.conv2d ya que solo toma un entero como filtros. Tal vez utilizando kernel_constraint ?

Por otro lado, tf.layers.conv2d maneja la activación y el sesgo automáticamente, mientras que usted tiene que escribir códigos adicionales para estos si usa tf.nn.conv2d.

Eche un vistazo aquí: tensorflow> tf.layers.conv2d

y aquí: tensorflow> conv2d

Como puedes ver, los argumentos de la versión de capas son:

tf.layers.conv2d (entradas, filtros, tamaño de kernel, strides = (1, 1), relleno = ‘válido’, formato de datos = ‘channels_last’, dilation_rate = (1, 1), activación = Ninguno, use_bias = True, kernel_initializer = Ninguno, bias_initializer = tf.zeros_initializer (), kernel_regularizer = None, bias_regularizer = None, activity_regularizer = None, trainable = True, name = None, reuse = None)

y la versión nn:

tf.nn.conv2d (entrada, filtro, zancadas, relleno, use_cudnn_on_gpu = Ninguna, formato de datos = Ninguna, nombre = Ninguna)

¡Creo que puedes elegir la que más te guste!

Todas estas otras respuestas hablan de cómo los parámetros son diferentes, pero en realidad, la principal diferencia entre tf.nn y tf.layers conv2d es que para tf.nn, debe crear su propio tensor de filtro y pasarlo. Este filtro necesita tener el tamaño de: [kernel_height, kernel_width, in_channels, num_filters]