2017-06-22 2 views
2

J'ai deux rangs-2 Tensor s avec des tailles égales le long de la deuxième dimension, mais inégale le long de la première. Par exemple, le tenseur A de forme [a, n] et le tenseur B de forme [b, n]. Ils peuvent être considérés comme deux tableaux contenant des vecteurs de longueur n.Appliquer la fonction pour chaque paire d'éléments dans deux Tensor dans Tensorflow

J'ai une fonction f qui prend deux entrées, chacune un tenseur de forme [n], et renvoie un scalaire. Je veux appliquer cette fonction à chaque paire de vecteurs dans A et B avec pour résultat un tenseur C de forme [a, b] tel que, pour chaque emplacement (i, j) dans C, C[i, j] = f(A[i], B[j]).

Si ceux-ci étaient simplement des tableaux réguliers NumPy, je pouvais accomplir cela avec le code suivant:

# Assume a, b, and n are integers, and A and B are Numpy arrays 
C = numpy.zeros((a, b)) 
for i in range(0, a): 
    for j in range(0, b): 
     C[i, j] = f(A[i], B[j]) 
return C 

Si cela pourrait se faire de telle sorte que f prend simplement A et B en entrée et retourne C, ce serait la solution préférée, de sorte que tout se passe comme des opérations de tenseurs appropriées, de sorte que tout peut être correctement parallélisé par Tensorflow. Juste tant que le résultat final est le même.

J'ai trouvé un solution to this problem spécifiquement pour quand f calcule la distance euclidienne entre chaque paire de vecteurs. Je voudrais étendre ceci à d'autres fonctions, telles que la distance de cosinus ou la distance de Manhattan (L1).

+0

Il pourrait en fait mieux en termes d'évolutivité et de performance pour faire le travail 'f' sur tenseurs de dimensions '[a, n]' et '[b, n]' directement. –

+0

Je suppose que je devrais clarifier, je n'ai pas nécessairement besoin de 'f' pour être une fonction séparée. Je veux juste appliquer _some_ opération qui réalise les résultats spécifiés. Le faire fonctionner directement sur l'ensemble des tenseurs, comme vous l'avez dit, serait la solution préférée. Je vais clarifier cela maintenant. – ItsTimaiFool

+1

J'ai trouvé cette question similaire, je la regarde maintenant pour voir si je peux l'étendre à des fonctions autres que la distance euclidienne: https://stackoverflow.com/questions/37009647/compute-pairwise-distance-in-a- batch-sans-replication-tensor-dans-tensorflow? rq = 1 – ItsTimaiFool

Répondre

2
a = tf.random_normal([10,5]) 
b = tf.random_normal([20,5]) 

Je commencerais en réorientant les deux tableaux comme celui-ci:

a = a[:,tf.newaxis,:] 
b = b[tf.newaxis,:,:] 

Maintenant, les formes sont [a, 1, n] et [1, b, n], donc nous pouvons large moulé sous une soustraction pour calculer le delta pour chaque paire:

delta = (a-b) 

Ceci a une forme de [a, b, n].

Maintenant, la distance euclidienne est simple. (axis=-1 Summs sur le dernier axe):

distance = tf.reduce_sum(delta**2,axis = -1)**0.5 

Et vous avez terminé:

print(distance) 
<tf.Tensor 'pow_3:0' shape=(10, 20) dtype=float32> 
+0

Merci, ceci a été utile! Cela fonctionne avec la distance de Manhattan avec très peu de modifications, et je pense que je peux faire un usage similaire de la diffusion pour mes autres besoins. – ItsTimaiFool