TensorFlow: numpy.répéter() alternative
Je veux comparer les valeurs prédites yp
de mon réseau de neurones par paires de la mode, et j'ai donc été à l'aide de (de retour dans mon ancien numpy mise en œuvre):
idx = np.repeat(np.arange(len(yp)), len(yp))
jdx = np.tile(np.arange(len(yp)), len(yp))
s = yp[[idx]] - yp[[jdx]]
Ce créer une indexation mesh que j'utilise ensuite. idx=[0,0,0,1,1,1,...]
tout jdx=[0,1,2,0,1,2...]
. Je ne sais pas si il y a une manière plus simple de le faire...
De toute façon, TensorFlow a un tf.tile()
, mais il semble manquer un tf.repeat()
.
idx = np.repeat(np.arange(n), n)
v2 = v[idx]
Et j'obtiens l'erreur:
TypeError: Bad slice index [ 0 0 0 ..., 215 215 215] of type <type 'numpy.ndarray'>
Il ne fonctionne pas à utiliser un TensorFlow constante pour l'indexation:
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'>
L'idée est de convertir mon RankNet mise en œuvre de TensorFlow.
Vous devez vous connecter pour publier un commentaire.
Vous pouvez obtenir l'effet de
np.repeat()
à l'aide d'une combinaison detf.la tuile()
ettf.reshape()
:Vous pouvez simplement calculer
jdx
à l'aide detf.tile()
:Pour l'indexation, vous pouvez essayer d'utiliser
tf.gather()
pour extraire non contigus des tranches de l'yp
tenseur:len(yp)==4
et la sortie deidx
était[0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3]
et pas[0,0,0,1,1,1,...]
.tf.transpose
appel après la pose du carrelage obtient de bons résultats[0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3]
. La ligne correcte estidx = tf.transpose(tf.tile(idx, [len(yp), 1]))
?jdx
! J'ai mis à jour pour clarifier la façon dont on pourrait calculéidx
etjdx
.Il ressemble à votre question est si populaire que les gens consultez sur TF tracker. Malheureusement, la même fonction n'est pas encore mis en œuvre en TF.
Vous pouvez la mettre en œuvre en combinant tf.tuile, tf.remodeler, tf.squeeze. Voici un moyen de convertir des exemples de np.répétez:
Dans le dernier cas, où les répétitions sont différents pour chaque élément, vous sera très probablement besoin boucles.
1-d tenseurs, j'ai fait cette fonction
Juste au cas où quelqu'un est intéressé pour un 2D méthode pour copier les matrices. Je pense que cela pourrait fonctionner:
Résultats à partir de:
À:
Si vous le souhaitez:
Simplement utiliser
tf.tile(x, [N, 1])
Selon tf api document,
tf.keras.backend.repeat_elements()
fait le même travail avecnp.repeat()
. Par exemple,Vous pouvez simuler manquant
tf.repeat
partf.stack
ing la valeur de lui-même:Je le conseil à l'aide de ce sur des petites répétez compte.
Bien que beaucoup de nettoyage et de solutions de travail ont été donnés, ils semblent tous être basée sur la production de l'ensemble des indices à partir de zéro à chaque itération.
Alors que le coût de production de ces nœuds n'est généralement pas significative au cours de la formation, il peut être important si l'utilisation de votre modèle pour l'inférence.
Répéter tf.gamme (comme ton exemple) a mis un peu de temps alors j'ai construit la fonction suivante créateur. Étant donné le nombre maximum de fois que quelque chose sera répété et le nombre maximum de choses qui ont besoin de la répétition, elle renvoie une fonction qui produit les mêmes valeurs que
np.repeat(np.arange(len(multiples)), multiples)
.L'idée générale est de stocker un répétée tenseur, puis masque, mais il peut aider à voir visuellement (c'est pour l'exemple donné ci-dessus):
tl;dr: Pour éviter de produire des indices à chaque fois (peut être coûteux), pré-répéter tout et puis masque tenseur chaque fois
Un relativement rapide mise en œuvre a été récemment ajouté à
RaggedTensor
utilitaires de 1,13, mais ce n'est pas une partie de la exporté officiellement API. Vous pouvez toujours l'utiliser, mais il y a une chance qu'il pourrait disparaître.À partir du code source: