12
votes

Parallèle d'optimisation dimensionnelle

Je construis un script qui génère des données d'entrée [paramètres] pour un autre programme à calculer. Je voudrais optimiser les données résultantes. Auparavant, j'ai utilisé l'optimisation Numpy Powell. Le code Psuedo ressemble à quelque chose comme ça. XXX PRE>

Ceci fonctionne bien; Cependant, il est incroyablement lent que chaque itération du programme peut prendre des jours à courir. Ce que je voudrais faire est de grain grossier ceci. Donc, au lieu d'exécuter une seule itération à la fois, il fonctionnerait (nombre de paramètres) * 2 à la fois. Par exemple: P>

Initial guess: param=[1,2,3,4,5]

#Modify guess by plus minus another matrix that is changeable at each iteration
jump=[1,1,1,1,1]
#Modify each variable plus/minus jump.
for num,a in enumerate(param):
    new_param1=param[:]
    new_param1[num]=new_param1[num]+jump[num]
    run_program(new_param1)
    new_param2=param[:]
    new_param2[num]=new_param2[num]-jump[num]
    run_program(new_param2)

#Wait until all programs are complete -> Parse Output
Output=[[value,param],...]
#Create new guess
#Repeat


10 commentaires

Ce n'est pas directement lié à votre question; Mais comme votre tâche est cette ressource intensive, il ne serait-il pas plus logique d'utiliser une langue compilée comme c pour les avantages de la performance?


@Ophion, vous voudrez peut-être obtenir votre code en premier. Considérons également ces conseils de performance. wiki.python.org/moin/pythonspeed/performanceCetips


Le code principal est en C et très optimisé, et malheureusement les implémentations pour le paralléliser à travers plusieurs nœuds de calcul ne sont pas particulièrement efficaces. J'ai besoin de quelque chose pour interfacer avec le code principal et optimiser un ensemble de paramètres qu'il n'a pas été conçu pour le faire. Recoverez le primaire pour le faire est une option, mais probablement plus compliquée et finalement à peu d'avantages.


Alors qu'est-ce que tu veux exactement parallèlement? Que fait run_program ()? S'il ne s'agit pas de variables avec des variables, vous pouvez facilement utiliser une piscine et sa fonction de carte ( docs.python.org/2/library/... )


run_program (param) exécute le code principal avec les paramètres d'impuche et renvoie une valeur singulière. Essentiellement ce que je veux faire, c'est avoir une version parallèle de l'algorithme Powell ou un autre algorithme de minimisation qui ne nécessite de préférence pas de dérivés et peut prendre en compte plusieurs suppositions simultanées.


donc vitesse est le problème ou complexité de l'optimisation est le problème ????


Cela ne signifie pas nécessairement que j'ai besoin d'une optimisation qui converge plus rapidement, mais un algorithme pouvant prendre plusieurs suppositions. J'utilise le terme parallélisation pour signifier qu'il peut exécuter plusieurs instances du programme ensemble. La raison en est d'augmenter le nombre de cœurs que le programme peut utiliser est assez inefficace après un certain point, mais j'ai de nombreux nœuds de calcul pour exécuter de nombreuses instances différentes du programme. Donc, si chaque nœud peut fonctionner sa propre hypothèse et que l'algorithme de minimisation peut prendre en compte toutes les suppositions, le temps total de la CPU devrait augmenter, mais le temps réel devrait diminuer.


Certaines informations sur la fonction cible aideraient:


[SRY, pressé Entrée] Certaines informations sur la fonction cible aideraient: y a-t-il des minima locaux? Est-ce une fonction lisse (continue)? Est-ce une fonction discrète? Connaissez-vous les limites dans lesquelles le minimum mentirait? Peut-il y avoir plusieurs minima? Fondamentalement, toutes restrictions sur la fonction cible pourraient aider à répondre à la question de YouT.


Il existe de nombreux minima locaux, il est lisse, discret, il y a des limites et je sais où sont approximativement les minima locaux et mondiaux. Ce n'est pas une surface particulièrement difficile, d'où l'extrapolation parabolique faisant un travail décent.


7 Réponses :


0
votes

Je pense que ce que vous voulez faire est d'utiliser les capacités de threading Python intégrées. Fourni que votre fonction de travail a plus ou moins le même temps d'exécution quels que soient les paramètres, ce serait efficace.

Créez 8 threads dans une piscine, exécutez 8 instances de votre fonction, obtenez 8 résultats, exécutez votre optimisation Algo pour modifier les paramètres avec 8 résultats, répéter .... Bénéfice?


3 commentaires

Le problème est l'algorithme d'optimisation. Je vais réécrire le texte principal pour préciser. La principale question est la suivante: existe-t-il un algorithme de minimisation déjà construit qui prend plusieurs entrées et peut créer plusieurs suppositions pour obtenir la valeur de?


Vous ne pouvez pas créer un processus asynchrone qui exécutez votre fonction d'optimisation pour un résultat à chaque fois qu'un fil termine un travail? Étant donné que la mise en œuvre que vous souhaitez apporter ne sera meilleure que si votre fonction de travail ait un temps de calcul très similaire quel que soit les paramètres.


La variation de temps de calcul de la fonction de travail est de l'ordre de plusieurs pour cent. Le processus asynchrone serait une étape plus avancée, je dois d'abord obtenir un meilleur algorithme de minimisation.



0
votes

Si je n'ai pas eu de mal ce que vous demandez, vous essayez de minimiser votre fonction un paramètre à l'heure.

Vous pouvez l'obtenir en créant un ensemble de fonctions d'un seul argument, où pour chaque fonction Vous gelez tous les arguments sauf un.

Ensuite, vous optimisez une boucle optimisant chaque variable et mettez à jour la solution partielle.

Cette méthode peut accélérer de nombreuses fonctions de plusieurs paramètres où le paysage énergétique n'est pas trop complexe (la dépendance entre les paramètres n'est pas trop forte).

donné une fonction xxx

Vous créez la supposition et la fonction: xxx

que vous les mettez dans un certain cycle de l'optimisation xxx

c'est un très simple mais Méthode efficace de simplification de votre tâche de minimisation. Je ne me souviens pas vraiment de savoir comment cette méthode est appelée, mais un look proche de l'entrée de Wikipedia sur la minimisation devrait faire l'affaire.


3 commentaires

Oui, ce serait très facile si toutes les variables ne dépendaient pas l'une de l'autre.


La méthode est utile car elle fonctionne même sur des variables dépendantes, il a juste besoin de plus d'une itération pour la convergence.


Vous êtes correct dans cela; Cependant, ce n'est pas une amélioration sur ma mise en œuvre actuelle. Je vais énoncer à nouveau ce que je cherche vraiment, c'est un moyen de parallementer un algorithme de minimisation, pas un peu par morceaux. Pour reformuler un bon exemple. L'algorithme de Powell utilise deux boucles, si vous parallélisez la boucle interne, vous pouvez accélérer la boucle extérieure et ainsi l'algorithme entier.



1
votes

sont des dérivés de votre fonction d'objectif disponible? Si oui, vous pouvez utiliser descente de gradient (ancienne, lente mais fiable) ou Gradient de conjugué . Sinon, vous pouvez approximer les dérivés en utilisant des différences finies et utilisez toujours ces méthodes. Je pense en général, si vous utilisez des approximations de différentielles finies aux dérivés, vous êtes beaucoup mieux à utiliser les gradients de conjugué plutôt que sur la méthode de Newton.

Une méthode plus moderne est SPSA qui est une méthode stochastique et ne nécessite pas de dérivés. SPSA nécessite beaucoup moins d'évaluations de la fonction d'objectif pour le même taux de convergence que la différentialité de différentielle finie aux gradients conjugués, pour des problèmes quelque peu bien élevés.


1 commentaires

Des dérivés analytiques sont disponibles, mais discutables. Les méthodes de gradient conjugué fonctionnent très bien pour ce type de travail. Ma mise en œuvre actuelle est un Powell où la boucle interne est parallélique. SPSA est vraiment génial, mais pas vraiment ce que je cherche ici. Vraiment le problème principal se résume à la façon de paralleraliser l'algorithme de minimisation.



1
votes

Il existe deux façons d'estimer des gradients, un facilement parallélizable, une non:

  • autour d'un point unique, par exemple (F (direction X + H i ) - F (x)) / h; Ceci est facilement parallélizable à NDIM
  • dégradé "marche": marcher de x 0 dans la direction E 0 to x 1 , puis à partir de x 1 dans la direction E 1 à x 2 ...; Ceci est séquentiel.

    Les minimiseurs utilisant des gradients sont très développés, puissants, convergent quadratique (sur des fonctions suffisamment lisses). La fonction de gradient fournie par l'utilisateur peut bien sûr être un estimateur de gradient parallèle.
    Quelques minimiseurs utilisent des gradients de "marche", parmi les méthodes de Powell, Voir Recettes numériques p. 509.
    Donc, je suis confus: comment parallèle sa boucle intérieure?

    Je suggérerais scipy fmin_tnc Avec un estimateur de gradient parallèle, peut-être utiliser des différences centrales et non unilatérales.
    (Fwiw, Ce compare certains des optimiseurs scipy non dérivés sur deux fonctions 10-D; ymmv.)


1 commentaires

L'est intéressant que j'ai sauté dessus lorsque je examinais la liste des fonctions implémentées, cela dépendrait fortement des gradients produits. Je vais lui donner un tir en utilisant les dérivés analytiques paraboliques. Les recettes numériques sont un excellent livre! Pour la méthode de Powell, vous pouvez trouver les minima d'une dimension utilisant d'autres méthodes pouvant être paralléléées. Vous recherchez toujours quelque chose déjà implémenté pour le point un si possible.



3
votes

J'ai eu le même problème alors que j'étais à l'université, nous avions un algorithme de Fortran pour calculer l'efficacité d'un moteur basé sur un groupe de variables. Au moment où nous utilisons modefrontier et si je me souviens bien, aucun des algorithmes n'a été capable de générer plusieurs suppositions.

L'approche normale serait d'avoir une DOE et là où certains algorithmes pour générer la DOE au mieux adapté à votre problème. Après cela, nous allions exécuter les entrées de biche unique parallèles et un algorithme «surveillerait» le développement des optimisations indiquant le meilleur design actuel.

Note latérale: Si vous n'avez pas de grappe et si vous avez besoin de plus de puissance informatique, HTCondor peut vous aider.


1 commentaires

Bonjour, je suis heureux d'entendre parler des autres avec des problèmes similaires. Merci de m'avoir présenté à ModeFrontier, il ressemble à un logiciel très intéressant. Quelque chose qui regarde diverses optimisations pourrait être intéressant - je vais examiner. J'ai heureusement un groupe qui a plus que ce qui répond à mes besoins informatiques; Cependant, c'est à la recherche de ce projet particulier, achetant une petite boîte Linux et la poussant sous un bureau pendant un an ressemble à la meilleure façon d'aller à ce sujet.



0
votes

Vous pouvez faire parallèlement à deux parties: 1) parallèlement le calcul de l'itération unique ou 2) Démarrage parallèle N Devoir initial.

On 2) Vous avez besoin d'un contrôleur de travail pour contrôler les n threads de découverte initiales.

Veuillez ajouter une sortie supplémentaire sur votre programme: "Bibliothèque inférieure" qui indique que les valeurs de sortie des décents du paramètre d'entrée actuel ne sont pas inférieures à cette limite inférieure.

Le nouveau thread de devinette initial peut concurrencer les uns avec les autres; Si la limite inférieure d'un fil d'un thread est supérieure à la valeur actuelle du thread existant, ce filetage peut être supprimé par votre contrôleur de travail.


0 commentaires

0
votes

La parallélisation des optimiseurs locaux est intrinsèquement limitée: ils commencent à partir d'un seul point initial et tentent de travailler en descente, des points plus tard dépendent des valeurs des évaluations précédentes. Néanmoins, il y a quelques avenues où une quantité modeste de parallélisation peut être ajoutée.

  • Comme autre réponse indique, si vous devez évaluer votre dérivé à l'aide d'une méthode de différence finie, de préférence avec une taille d'étape adaptative, cela peut nécessiter de nombreuses évaluations de fonction, mais le dérivé par rapport à chaque variable peut être indépendant; Vous pourriez peut-être obtenir une vitesse d'accélération d'un facteur de deux fois le nombre de dimensions de votre problème. Si vous avez plus de processeurs que vous savez quoi faire avec, vous pouvez utiliser des formules de gradient précises à des commandes supérieures nécessitant des évaluations plus (parallèles).
  • Certains algorithmes, à certaines étapes, utilisent des différences finies pour estimer la matrice de Hesse; Cela nécessite environ la moitié du carré du nombre de dimensions de votre matrice, et tout peut être fait en parallèle.

    Certains algorithmes peuvent également être en mesure d'utiliser plus de parallélisme à un coût algorithmique modeste. Par exemple, les méthodes quasi-Newton tentent de construire une approximation de la matrice Hesse, à la mise à jour souvent en évaluant un gradient. Ils font ensuite une étape vers le minimum et évaluent un nouveau gradient pour mettre à jour l'Hesse. Si vous avez suffisamment de processeurs afin que l'évaluation d'un Hesse soit aussi rapide que d'évaluer la fonction une fois, vous pouvez probablement les améliorer en évaluant l'HESSIAN à chaque étape.

    aussi loin que les implémentations vont, je crains que vous n'ayez un peu de chance. Il existe un certain nombre d'implémentations intelligentes et / ou bien testées, mais elles sont toutes, autant que je sache, un seul fileté. Votre meilleur pari est d'utiliser un algorithme qui nécessite un gradient et calculez votre propre en parallèle. Ce n'est pas si difficile d'écrire un adaptatif qui fonctionne en parallèle et choisit des tailles d'étape raisonnables pour ses dérivés numériques.


0 commentaires