training sklearn scikit neighbors neighbor nearest multiple multiclass learn force example brute tensorflow

sklearn - TensorFlow: alternativa numpy.repeat()



python knn algorithm (9)

Quiero comparar los valores pronosticados yp de mi red neuronal de manera pareada, y entonces estaba usando (en mi antigua implementación numpy):

idx = np.repeat(np.arange(len(yp)), len(yp)) jdx = np.tile(np.arange(len(yp)), len(yp)) s = yp[[idx]] - yp[[jdx]]

Esto básicamente crea una malla de indexación que luego uso. idx=[0,0,0,1,1,1,...] mientras que jdx=[0,1,2,0,1,2...] . No sé si hay una manera más simple de hacerlo ...

De todos modos, TensorFlow tiene un tf.tile() , pero parece que le falta un tf.repeat() .

idx = np.repeat(np.arange(n), n) v2 = v[idx]

Y me sale el error:

TypeError: Bad slice index [ 0 0 0 ..., 215 215 215] of type <type ''numpy.ndarray''>

Tampoco funciona usar una constante TensorFlow para la indexación:

idx = tf.constant(np.repeat(np.arange(n), n)) v2 = v[idx]

-

TypeError: Bad slice index Tensor("Const:0", shape=TensorShape([Dimension(46656)]), dtype=int64) of type <class ''tensorflow.python.framework.ops.Tensor''>

La idea es convertir mi implementación de RankNet a TensorFlow.


Aunque se han dado muchas soluciones limpias y de trabajo, parece que todas se basan en producir el conjunto de índices desde cero en cada iteración.

Si bien el costo para producir estos nodos generalmente no es significativo durante el entrenamiento, puede ser significativo si usa su modelo para inferencia.

La repetición de tf.range (como su ejemplo) ha aparecido varias veces, así que creé el siguiente creador de funciones. Dada la cantidad máxima de veces que se repetirá algo y la cantidad máxima de cosas que necesitarán repetirse, devuelve una función que produce los mismos valores que np.repeat(np.arange(len(multiples)), multiples) .

import tensorflow as tf import numpy as np def numpy_style_repeat_1d_creator(max_multiple=100, max_to_repeat=10000): board_num_lookup_ary = np.repeat( np.arange(max_to_repeat), np.full([max_to_repeat], max_multiple)) board_num_lookup_ary = board_num_lookup_ary.reshape(max_to_repeat, max_multiple) def fn_to_return(multiples): board_num_lookup_tensor = tf.constant(board_num_lookup_ary, dtype=tf.int32) casted_multiples = tf.cast(multiples, dtype=tf.int32) padded_multiples = tf.pad( casted_multiples, [[0, max_to_repeat - tf.shape(multiples)[0]]]) return tf.boolean_mask( board_num_lookup_tensor, tf.sequence_mask(padded_multiples, maxlen=max_multiple)) return fn_to_return #Here''s an example of how it can be used with tf.Session() as sess: repeater = numpy_style_repeat_1d_creator(5,4) multiples = tf.constant([4,1,3]) repeated_values = repeater(multiples) print(sess.run(repeated_values))

La idea general es almacenar un tensor repetido y luego enmascararlo, pero puede ser útil verlo visualmente (esto es para el ejemplo dado anteriormente):

In the example above the following Tensor is produced: [[0,0,0,0,0], [1,1,1,1,1], [2,2,2,2,2], [3,3,3,3,3]] For multiples [4,1,3] it will collect the non-X values: [[0,0,0,0,X], [1,X,X,X,X], [2,2,2,X,X], [X,X,X,X,X]] resulting in: [0,0,0,0,1,2,2,2]

tl; dr: Para evitar producir los índices cada vez (puede ser costoso), repita todo y luego enmascare ese tensor cada vez


De acuerdo con el document tf api, tf.keras.backend.repeat_elements() hace el mismo trabajo con np.repeat() . Por ejemplo,

x = tf.constant([1, 3, 3, 1], dtype=tf.float32) rep_x = tf.keras.backend.repeat_elements(x, 5, axis=0) # result: [1. 1. 1. 1. 1. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 1. 1. 1. 1. 1.]


En caso de que alguien esté interesado en un método 2D para copiar las matrices. Creo que esto podría funcionar:

TF_obj = tf.zeros([128, 128]) tf.tile(tf.expand_dims(TF_obj, 2), [1, 1, 2])


Parece que su pregunta es tan popular que las personas la refieren en el rastreador TF . Lamentablemente, la misma función aún no se implementa en TF.

Puede implementarlo combinando tf.tile , tf.reshape , tf.squeeze . Aquí hay una manera de convertir ejemplos de np.repeat :

import numpy as np import tensorflow as tf x = [[1,2],[3,4]] print np.repeat(3, 4) print np.repeat(x, 2) print np.repeat(x, 3, axis=1) x = tf.constant([[1,2],[3,4]]) with tf.Session() as sess: print sess.run(tf.tile([3], [4])) print sess.run(tf.squeeze(tf.reshape(tf.tile(tf.reshape(x, (-1, 1)), (1, 2)), (1, -1)))) print sess.run(tf.reshape(tf.tile(tf.reshape(x, (-1, 1)), (1, 3)), (2, -1)))

En el último caso donde las repeticiones son diferentes para cada elemento, lo más probable es que necesites loops .


Puede lograr el efecto de np.repeat() usando una combinación de tf.tile() y tf.reshape() :

idx = tf.range(len(yp)) idx = tf.reshape(idx, [-1, 1]) # Convert to a len(yp) x 1 matrix. idx = tf.tile(idx, [1, len(yp)]) # Create multiple columns. idx = tf.reshape(idx, [-1]) # Convert back to a vector.

Simplemente puede calcular jdx usando tf.tile() :

jdx = tf.range(len(yp)) jdx = tf.tile(jdx, [len(yp)])

Para la indexación, puede intentar usar tf.gather() para extraer tf.gather() no contiguos del tensor yp :

s = tf.gather(yp, idx) - tf.gather(yp, jdx)


Puede simular tf.repeat faltante tf.repeat el valor consigo mismo:

value = np.arange(len(yp)) # what to repeat repeat_count = len(yp) # how many times repeated = tf.stack ([value for i in range(repeat_count)], axis=1)

Aconsejo usar esto solo en pequeños recuentos repetidos.


Recientemente se agregó una implementación relativamente rápida con RaggedTensor utilidades RaggedTensor de 1.13, pero no es parte de la API exportada oficialmente. Todavía puede usarlo, pero existe la posibilidad de que desaparezca.

from tensorflow.python.ops.ragged.ragged_util import repeat

Del código fuente:

# This op is intended to exactly match the semantics of numpy.repeat, with # one exception: numpy.repeat has special (and somewhat non-intuitive) behavior # when axis is not specified. Rather than implement that special behavior, we # simply make `axis` be a required argument.


Solo para tensores 1-d, he hecho esta función

def tf_repeat(y,repeat_num) return tf.reshape(tf.tile(tf.expand_dims(y,axis=-1),[1,repeat_num]),[-1])


import numpy as np import tensorflow as tf import itertools x = np.arange(6).reshape(3,2) x = tf.convert_to_tensor(x) N = 3 # number of repetition K = x.shape[0] # for here 3 order = list(range(0, N*K, K)) order = [[x+i for x in order] for i in range(K)] order = list(itertools.chain.from_iterable(order)) x_rep = tf.gather(tf.tile(x, [N, 1]), order)

Resultados de:

[0, 1], [2, 3], [4, 5]]

A:

[[0, 1], [0, 1], [0, 1], [2, 3], [2, 3], [2, 3], [4, 5], [4, 5], [4, 5]]

Si tu quieres:

[[0, 1], [2, 3], [4, 5], [0, 1], [2, 3], [4, 5], [0, 1], [2, 3], [4, 5]]

Simplemente use tf.tile(x, [N, 1])