Buceando sobre un tensor

Estoy tratando de procesar un tensor de tamaño variable, en una forma de python que sería algo así como:

# X is of shape [m, n] for x in X: process(x) 

He intentado usar tf.scan , lo que quiero es procesar cada subtensor , por lo que he intentado usar un escaneo nested, pero estaba habilitado para hacerlo, porque tf.scan funciona con el acumulador, si no encontrado tomará la primera entrada de los elementos como inicializador, lo que no quiero hacer. Como ejemplo, supongamos que quiero agregar uno a cada elemento de mi tensor (esto es solo un ejemplo), y quiero procesarlo elemento por elemento. Si ejecuto el siguiente código, solo se agregará uno a un subtensor, porque el escaneo considera el primer tensor como inicializador, junto con el primer elemento de cada subtensor.

 import numpy as np import tensorflow as tf batch_x = np.random.randint(0, 10, size=(5, 10)) x = tf.placeholder(tf.float32, shape=[None, 10]) def inner_loop(x_in): return tf.scan(lambda _, x_: x_ + 1, x_in) outer_loop = tf.scan(lambda _, input_: inner_loop(input_), x, back_prop=True) with tf.Session() as sess: sess.run(tf.global_variables_initializer()) rs = sess.run(outer_loop, feed_dict={x: batch_x}) 

Alguna sugerencia ?

La mayoría de las funciones integradas de tensorflow podrían aplicarse elementwise. Así que podrías pasar un tensor a una función. Me gusta:

 outer_loop = inner_loop(x) 

Sin embargo, si tiene alguna función que no se podría aplicar de esta manera (es realmente tentador ver esa función), podría usar map_fn .

Digamos que su función simplemente agrega 1 a cada elemento de un tensor (o lo que sea):

 inputs = tf.placeholder... def my_elementwise_func(x): return x + 1 def recursive_map(inputs): if tf.shape(inputs).ndims > 0: return tf.map_fn(recursive_map, inputs) else: return my_elementwise_func(inputs) result = recursive_map(inputs) 

Para recorrer un tensor puedes probar tf.unstack

Desempaqueta la dimensión dada de un tensor de rango R en tensores de rango R (1).

Entonces, agregar 1 a cada tensor se vería como:

 import tensorflow as tf x = tf.placeholder(tf.float32, shape=(None, 10)) x_unpacked = tf.unstack(x) # defaults to axis 0, returns a list of tensors processed = [] # this will be the list of processed tensors for t in x_unpacked: # do whatever result_tensor = t + 1 processed.append(result_tensor) output = tf.concat(processed, 0) with tf.Session() as sess: print(sess.run([output], feed_dict={x: np.zeros((5, 10))})) 

Obviamente, puede desempaquetar cada tensor de la lista para procesarlo, hasta los elementos individuales. Sin embargo, para evitar un montón de desempaquetado nested, podrías intentar aplanar x con tf.reshape(x, [-1]) primero, y luego recorrerlo como

 flattened_unpacked = tf.unstack(tf.reshape(x, [-1]) for elem in flattened_unpacked: process(elem) 

En este caso elem es un escalar.