2017-08-06 3 views
0

Je réalise une évaluation pour mes recherches dans le domaine des systèmes de recommandation dans TensorFlow. J'ai préformé un classificateur binaire qui produit une valeur dans [0, 1]. Il nécessite un utilisateur et une représentation d'élément qui sont ensuite transformés en incorporations dans le modèle.Calculer efficacement toutes les combinaisons (en ligne) de deux matrices en tant qu'entrée pour un classificateur binaire préchargé dans TensorFlow?

J'ai 100'000 utilisateurs chacun représenté par 3'283 caractéristiques, ainsi la matrice de l'utilisateur a des dimensions 100000x3283. Il y a ~ 1.7M articles qui sont également représentés presque le même nombre (3277) de fonctionnalités. Les caractéristiques sont encore divisées en parst continu et catégorique. Ainsi, il existe 4 paramètres fictifs du modèle qui attendent les valeurs avec la quantité de caractéristiques entre parenthèses:

  • utilisateur continue (12)
  • utilisateur catégorique (3271)
  • élément continu (6)
  • article (3271)

J'ai besoin de calculer la valeur respective pour chacune des combinaisons> 10^11 et de collecter les indices et les valeurs de sortie des 1000 meilleurs éléments pour chaque utilisateur rgd. la sortie réseau la plus élevée.

Quelle serait la manière la plus efficace de le faire?

Rencontrant la fonction tf.nn.top_k Je suis toujours pas sûr de données préchargement (partiellement) dans une variable Tensor (depuis Constantes utilisent trop de mémoire en raison de copies internes faites par TF), ou par une alimentation tableau numpy, et comment faire les combinaisons à l'intérieur. J'ai joué avec des boucles et np.repeat autour des sessions de session, mais c'est trop de mémoire intense et trop de temps inefficace. Ainsi, le code ci-dessous était un premier essai - sachant qu'il est inefficace, mais au moins obtenir quelque chose au travail:

sess = tf.Session() 
saver.restore(sess, tf.train.latest_checkpoint('logging_embed/')) 
results = np.zeros(len(items)) 
start = time.time() 
results = sess.run(out_layer, feed_dict={user_cont: np.repeat(np.atleast_2d(profiles[user, :12]), len(items), axis=0), 
             user_cat: np.repeat(np.atleast_2d(profiles[user, 12:]), len(items), axis=0), 
             item_cont: np.atleast_2d(items[:, :6]), 
             item_cat: np.atleast_2d(items[:, 6:])}) 
print(str(time.time() - start)) 

Je courais des expériences sur 2 Tesla K80 avec un GPU-RAM totale d'environ 23GB, mais déjà noté que la représentation Variable à l'aide de tf.float32 est 3-4 fois plus grande qu'elle devrait l'être, donc le découpage des éléments serait nécessaire, par exemple 200k ou 300k.

Merci d'avance pour toute suggestion utile!

Répondre

0

Je ne sais pas si c'est le moyen le plus efficace, mais j'aborderais le problème comme suit. Faites en sorte que votre modèle prenne en tant qu'entrée n utilisateur et m des profils d'éléments et fournisse une matrice de sorties n x m - une pour chaque paire utilisateur/élément dans l'entrée. Une fois que vous avez ce modèle, vous pouvez expérimenter avec les valeurs de n et m qui fonctionnent bien sur votre matériel. Ensuite, il suffit d'invoquer ce modèle avec les bons segments d'utilisateur/éléments et de mettre à jour les meilleurs éléments actuels pour chaque utilisateur après chaque invocation de modèle.

La maintenance doit être gérable et peut probablement être effectuée sur la CPU. 1000 articles pour 100k utilisateurs -> 4 * 1000 * 100k = 400MB matrice. Si vous conservez les scores des articles pour chaque utilisateur, les mises à jour peuvent être relativement bon marché. En outre, vous ne traiterez qu'avec des utilisateurs n à la fois.