Crear una tf.Operation en TensorFlow

Contenido del Bootcamp Dirigido por: | Última modificación: 18 de abril de 2024 | Tiempo de Lectura: 3 minutos

Algunos de nuestros reconocimientos:

Premios KeepCoding

Crear una tf.Operation en TensorFlow forma parte de las funciones que puedes implementar en este tipo de framework y que se relaciona con los conceptos clave de esta: los grafos y los tensores. A partir de allí, se instaura la importancia de conocer esta función y su desarrollo en un procesamiento de los macrodatos.

Por este motivo, en este post, te explicamos cómo crear una tf.Operation en TensorFlow, de manera que aprendas qué es y cómo funciona en Deep Learning.

Crear una tf.Operation en TensorFlow

Para crear una tf.Operation en TensorFlow, resulta de suma importancia que conozcas tres conceptos básicos de TensorFlow que se relacionan con esta función:

  • tf.Graph: representa un conjunto de tf.Operations.
  • tf.Operation: son las operaciones indicadas por las ecuaciones que escribimos.
  • tf.Tensor: los resultados de las tf.Operations.

Ahora vamos a ver una tf.Operation. Para ello, vamos a usar «x» para crear y visualizar una distribución Gaussiana. Para los que no la recordéis, la fórmula de la distribución de probabilidad de Gauss es así:

La gráfica la veremos enseguida.

sigma = 1.0
mean = 0

# Implementamos la fórmula de una distribución Gaussiana
g1d = (tf.exp(tf.negative(tf.pow(x - mean, 2.0) / (2.0 * tf.pow(sigma, 2.0)))) *
     (1.0 / (sigma * tf.sqrt(2.0 * 3.1415))))

Podemos comprobar que nuestra tf.Operation se ha incluido efectivamente en nuestro tf.Graph:

if g1d.graph is tf.get_default_graph():
  print('Todo bien')

Todo bien:

# Ejecutando el tf.Graph obtenemos el resultado, y con pyplot lo visualizamos:
plt.plot(g1d.eval())
[<matplotlib.lines.Line2D at 0x7f1ddad404d0>]
# ¿Qué dimensiones tiene "g1d"?
print(g1d.get_shape())  # nos devuelve un objeto de tipo tf.TensorShape
print(type(g1d.get_shape()))

print(g1d.get_shape().as_list())  # nos devuelve algo un poco más normal, una lista
print(type(g1d.get_shape().as_list()))

Habrá momentos en los que no sepamos las dimensiones de una variable hasta que sea ejecutada la operación que devuelve su valor. Para estos casos, podemos utilizar tf.shape(variable), que nos devuelve un Tensor que calculará en tiempo de ejecución las dimensiones de nuestro resultado.

Esto se conoce como ‘static shape’ y ‘dinamic shape’, donde static se calcula teniendo en cuenta las dimensiones de los Tensores y Operaciones involucrados y la dinámica en tiempo de ejecución.

¿Qué pasa si definimos x como un «placeholder»? Un place holder es como una reserva, indica que ahí habrá un tensor, pero no es necesario definirlo en ese momento. Por ejemplo, definiendo:


x = tf.placeholder(tf.int32, shape=[5])

# sabemos que x va a albergar un tensor 1D de 5 dimensiones, como confirma 
# x.get_shape():

print(x.get_shape())
# pero no sabemos qué valores van a formarla hasta que no se lo indiquemos.

# Diferencias entre placeholder y variable:

# Variables

#  - Se utilizan para alojar parámetros que se aprenden durante el entrenamiento
#  - Por tanto, los valores se derivan del entrenamiento
#  - Requieren que se les asigne un valor inicial (puede ser aleatorio)

# Placeholders

#  - Reservan espacio para datos (por ejemplo, para los píxels de una imagen)
#  - No requieren que se les asigne un valor iniciar (aunque se puede)

(5,)

# Sin embargo, este es el valor estático de las dimensiones de x. ¿Qué ocurre
# si aplicamos un tf.unique() sobre x?
y, _ = tf.unique(x)
print(y.get_shape())

(?,)

# tf.unique() devuelve los valores únicos de x, que en un principio no se 
# saben, ya que x está definida como un placeholder, y un placeholder no tiene
# por qué estar definido hasta el momento de la ejecución, como hemos dicho
# antes. De hecho, vamos a ver qué ocurre si alimentamos "x" con dos valores
# distintos:

with tf.Session() as sess:
  print(sess.run(y, feed_dict={x: [0, 1, 2, 3, 4]}).shape)
  print(sess.run(y, feed_dict={x: [0, 0, 0, 0, 1]}).shape)
  
# El tamaño de y cambia dependiendo de lo que devuelve tf.unique(). A 
# esto se le llama "dynamic shape", y siempre está definido, nunca os devolverá
# un interrogante por respuesta. Gracias a esto, TensorFlow soporta operaciones
# como tf.unique(), que pueden tener resultados de tamaños variables.

(5,)
(2,)

# Así que ya sabes, siempre que utilices operaciones con salidas variables
# tendrás que usar tf.shape(variable) para calcular el dynamic shape de un 
# tensor.

sy = tf.shape(y)
# Devuelve una lista con las dimensiones
print(sy.eval(feed_dict={x: [0, 1, 2, 3, 4]}))
print(sy.eval(feed_dict={x: [0, 0, 0, 0, 1]}))

# Accedemos a la dimension que nos interesa
print(sy.eval(feed_dict={x: [0, 1, 2, 3, 4]})[0])
print(sy.eval(feed_dict={x: [0, 0, 0, 0, 1]})[0])

Conoce mucho más del Big Data

En el transcurso de este post, te podido entender cómo crear una tf.Operation en TensorFlow, sin embargo, su desarrollo en realidad forma parte del tipo de datos que te encuentres procesando y los resultados que esperas recibir, así que debes continuar practicando por tu cuenta.

Desde KeepCoding sabemos que instruirte sin una guía adecuada puede resultar complicado y aburrido, por ello, te presentamos el Bootcamp Full Stack Big Data, Inteligencia Artificial & Machine Learning. Aquí, podrás contar con todos los conocimientos necesarios para ser un experto en el ecosistema de sistemas, lenguajes y herramientas del Big Data a la par que los llevas a la práctica guiado por gran un grupo de profesionales. ¡No esperes más para inscribirte!

Posts más leídos

¡CONVOCATORIA ABIERTA!

Big Data, IA & Machine Learning

Full Stack Bootcamp

Clases en Directo | Profesores en Activo | Temario 100% actualizado