La différence de performance entre numpy et matlab

Je suis le calcul de la backpropagation algorithme pour un clairsemée autoencoder. J'ai implémenté en python à l'aide de numpy et dans matlab. Le code est presque le même, mais les performances sont très différentes. Le temps matlab nécessaire pour terminer la tâche est 0.252454 secondes, tandis que numpy 0.973672151566, qui est près de quatre fois plus. Je vais appeler ce code plusieurs fois plus tard dans un problème de minimisation donc cette différence conduit à quelques minutes de retard entre les implémentations. Est-ce un comportement normal? Comment pourrais-je améliorer les performances dans numpy?

Numpy mise en œuvre:

Rares.rho est un paramètre d'optimisation, éparses.les nœuds sont au nombre de nœuds dans la couche cachée (25), un peu.d'entrée (64) le nombre de nœuds dans la couche d'entrée, theta1 et theta2 sont le poids des matrices pour la première et de la deuxième couche, respectivement, avec les dimensions 25x64 et 64x25, m est égal à 10000, rhoest a une dimension de (25,), x a une dimension de 10000x64, a3 10000x64 et a2 10000x25.

UPDATE: J'ai introduit des changements dans le code ci-dessous quelques idées de réponses. La performance est maintenant numpy: 0.65 vs matlab: 0.25.

partial_j1 = np.zeros(sparse.theta1.shape)
partial_j2 = np.zeros(sparse.theta2.shape)
partial_b1 = np.zeros(sparse.b1.shape)
partial_b2 = np.zeros(sparse.b2.shape)
t = time.time()

delta3t = (-(x-a3)*a3*(1-a3)).T

for i in range(m):

    delta3 = delta3t[:,i:(i+1)]
    sum1 =  np.dot(sparse.theta2.T,delta3)
    delta2 = ( sum1 + sum2 ) * a2[i:(i+1),:].T* (1 - a2[i:(i+1),:].T)
    partial_j1 += np.dot(delta2, a1[i:(i+1),:])
    partial_j2 += np.dot(delta3, a2[i:(i+1),:])
    partial_b1 += delta2
    partial_b2 += delta3

print "Backprop time:", time.time() -t

Matlab mise en œuvre:

tic
for i = 1:m

    delta3 = -(data(i,:)-a3(i,:)).*a3(i,:).*(1 - a3(i,:));
    delta3 = delta3.';
    sum1 =  W2.'*delta3;
    sum2 = beta*(-sparsityParam./rhoest + (1 - sparsityParam) ./ (1.0 - rhoest) );
    delta2 = ( sum1 + sum2 ) .* a2(i,:).' .* (1 - a2(i,:).');
    W1grad = W1grad + delta2* a1(i,:);
    W2grad = W2grad + delta3* a2(i,:);
    b1grad = b1grad + delta2;
    b2grad = b2grad + delta3;
end
toc
  • il y a un module appelé mlabwrap. Vous pouvez utiliser matlab comme une bibliothèque python par l'importation. La syntaxe est très simple. Vous trouverez la source et le détail de la documentation ici.mlabwrap.sourceforge.net
  • Jetez un oeil à cython. La différence de temps est prévu, depuis MATLAB dispose d'une équipe commune d'enquête, et Disponible ne l'est pas. Si tout le code a été une seule numpy appel, puis le temps serait similaire, mais ce que vous voyez peut être interpréter les frais généraux. L'écriture d'une extension avec cython est vraiment facile et vous pouvez obtenir de gros gains de l'ajout de certains types de variables dans les bons endroits.
  • Quelle est la forme de data? Comment, concrètement, ne m comparer avec l'autre dimension?
  • m = 10000, x est un 10000x64 de la matrice, theta1 est un 25x64 de la matrice et theta2 64x25.
  • Si vous ne pouvez pas travailler avec x l'ensemble de la matrice, il est préférable de boucle sur la petite dimension de la grande. Mais que peut exiger une certaine ingéniosité.
InformationsquelleAutor pabaldonedo | 2013-08-29