2017-10-09 2 views
1

J'implémente une fonction de perte qui utilisera un tenseur de masque (M) consistant en 0s and 1s pour éliminer certaines valeurs de perte étant donné les prédictions (P) et les tenseurs de terrain (G).Lequel est le plus efficace: tf.where ou multiplication par élément?

Donc, j'ai 2 façons:

multiplication élément par élément:

loss = K.sum(M * K.binary_crossentropy(G, P))

sélection conditionnelle:

bin_ce = K.binary_crossentropy(G, P) 
loss = K.sum(tf.where(tf.equal(M, 1), bin_ce, 0)) 

Alors, qui sera plus efficace en termes de temps de fonctionnement?

+1

Avez-vous des points de repère exécuté vous-même? –

+0

Je cours un benchmark mais pas encore fini. Je demande votre avis à l'avance. – mkocabas

+1

Je suis assez convaincu que le cas de multiplication sera mieux .... en attendant les résultats de vos tests. Je ne peux pas imaginer le deuxième cas en utilisant moins de 2 étapes. –

Répondre

1

J'ai fait le benchmark et il est clair que la multiplication est bien meilleure que la sélection conditionnelle.

Voici les résultats:

A chart is worth a thousand words..

Un graphique vaut mille mots.

Code de référence:

import keras.backend as K 
import tensorflow as tf 
import numpy as np 
import sys 
import time 
import matplotlib.pyplot as plt 


def elm(G, P, M): 
     return K.sum(M * K.binary_crossentropy(G, P)) 

def cond(G, P, M, t): 
     C = K.variable(np.zeros((t, t))) 
     bin_ce = K.binary_crossentropy(G, P) 
     return K.sum(tf.where(tf.equal(M, 1), bin_ce, C)) 


s = [100, 1000, 10000, 100000] 
elms = [] 
conds = [] 

for t in s: 
     print t 
     t = int(t) 
     # number of 1s in mask 
     n = int(t/2) 

     M = np.zeros((t,t)) 
     P = np.random.rand(t, t) 
     G = np.random.rand(t, t) 

     for i in range(n): 
       r = np.random.randint(0, t) 
       c = np.random.randint(0, t) 
       M[r,c] = 1 

     M = K.variable(M) 
     P = K.variable(P) 
     G = K.variable(G) 

     start_time = time.time() 
     elm(G, P, M) 
     elms.append(time.time() - start_time) 

     start_time = time.time() 
     cond(G, P, M, t) 
     conds.append(time.time() - start_time) 

print elms 
print conds 

# create plot 
fig, ax = plt.subplots() 
index = np.arange(n_groups) 
bar_width = 0.35 
opacity = 0.8 

rects1 = plt.bar(index, elms, bar_width, 
       alpha=opacity, 
       color='b', 
       label='Element-wise') 

rects2 = plt.bar(index + bar_width, conds, bar_width, 
       alpha=opacity, 
       color='g', 
       label='Conditional') 

plt.xlabel('Input tensor size') 
plt.ylabel('Execution time (s)') 
plt.title('') 
plt.xticks(index + bar_width, ('100', '10e3', '10e4', '10e5')) 
plt.legend() 

plt.tight_layout() 
plt.show()