NOMAD:自宅での「ブラックボックス」の最適化

この記事では、私と同僚が練習でよく使用する便利なツールについて説明します。 このツールはNOMADと呼ばれます。 このパッケージは、さまざまな複雑さの関数、主に計算が困難な関数、何らかの理由でアクセスできない勾配、ノイズの多い関数などを最適化するように設計されています。



最適化(最小化)機能は「ブラックボックス」と見なされます。個別に実装されたスクリプトまたはプログラム(バッチモードで動作する場合)または特別に実装されたC ++クラス(ライブラリモードで動作する場合)がその計算を担当します。 MADSアルゴリズムを使用して最適化が実行されます



ソースはLGPLライセンスの下で提供され、Unix、Linux、Mac OS X、およびWindowsのバージョンが利用可能です。ダウンロードには登録は必要ありませんが、短い形式(名前、組織、都市、国)を記入する必要があります。



NOMAD:ブラックボックス最適化ソフトウェア

画像



なぜそれが必要ですか



基本的なシナリオは次のとおりです。 あなたは、共通の利益に貢献する子供の天才を開発しています。 このプロセスでは、構成に配置された数値パラメーターを使用して構成できるクールで超近代的な方法とアルゴリズムを使用します(マジックナンバーの形式でコードが単純に光らない場合)。 システムには特定の品質インジケータがあり、誰も計算方法がわからないため、現在は約98%であり、99.5%に到達したいと考えています。 「ツイスト」を与えてお茶を飲むことができるツールが欲しいのですが、彼はシステムの品質を少し高めます。 このクラスの問題を解決するための優れたツールは、NOMADです。



特別な場合。 同じ問題を解決するには、2つの異なるアルゴリズムを使用します。 タスクには、入力オブジェクトの分類または評価(例は認識)が含まれ、出力では評価値のベクトルを取得します(例はニューラルネットワークの代替の出力ベクトルです)。 最初のアルゴリズムは1つのタイプのソースデータでより適切に機能し、2番目のアルゴリズムは他のタイプでより適切に機能し、何らかの理由で入力データのタイプを明確に区別できません。 可能な方法は、両方のアルゴリズムを使用して、事後の結果を「平均化」することです。 唯一の問題は、結果を平均化するためにどの係数(重み)を使用するかです。 最適な平均化係数を決定するために、入力データの特定のサンプルにエラーの総数や何らかのペナルティなどの機能を割り当てる場合、NOMADを使用できます。



使い方



NOMADをバッチモードで使用する簡単な例を考えてみましょう。 タスクは次のとおりです。オブジェクトをセットXからABの 2つのクラスに分割する単純な関数を作成します 小規模な統計調査の後、オブジェクトxがあるクラスに属していることを示す記号f1f2 、およびf3があることがわかりました。 f1f2 、およびf3は、値が実数であるオブジェクトの関数です。 C(x)= a1 * f1(x)+ a2 * f2(x)+ a3 * f3(x)+ bの形式で分類関数を検索します。ここで、 a1a2a3は実数で、 b-からの整数です11C(x)> = 0の場合、 xAに属し、それ以外の場合xBに属します キャッチは、間違えてオブジェクトxをセットBに定義した場合、実際にはAからのものですが、これは確かに不快ですが、致命的ではありませんが、 xAに定義したが100倍悪い。



この問題を解決するいくつかの巧妙な方法がありますが、たとえば、評価関数を構築し、NOMADを使用して係数を見つけます。



そのようなデータを含むトレーニングベースがあるとします。真のクラス(ここで定義する必要があります)

x)および符号f1(x)f2(x)f3(x)の値 。 ベースは、次のようなテキストファイルです:(base.dataなど)



A 1.0 3.0 4.5555 B 2.3 2.3 0.0 B 2.4 2.5 9.0 ...
      
      





このように機能を定義します。エラーが発生した場合、データベースを調べ、機能の値にこのエラーのコストを追加します。 「私たちはAでなければならず、 Bと言っ 」エラーのコストは1に等しく、「私たちはBとしなければならなかったし、 Aと言っ 」エラーのコストは100です。



環境への唯一の引数として係数a1a2a3bを持つファイルを受け入れ、機能の値を標準出力ストリームに出力する単純なプログラムを作成します。



 #!/usr/bin/python #  evaluator.py import sys #     def C(f, a): return a[3] + sum([x * y for x, y in zip(f, a[:3])]) #      def penalty(correct, f, a): answer = 'A' if C(f, a) >= 0.0 else 'B' #    -   if answer == correct: return 0.0 #   ,    elif correct == 'A': return 1.0 #   ,    else: return 100.0 if __name__ == '__main__': F = 0.0 #    sys.argv[1] a = list(map(float, list(open(sys.argv[1], 'r'))[0].split())) #      with open('base.data', 'r') as base: for line in base: line = line.strip().split() correct = line[0] f = map(float, line[1:]) F += penalty(correct, f, a) #    print(F)
      
      





次のステップは、NOMAD構成ファイルです(たとえばparams.nomad)



 #    DIMENSION 4 # ,    #    BB_EXE "$python evaluator.py" #   : #       BB_INPUT_TYPE ( RRRI ) #   : #    (OBJ) #    - # (   ) BB_OUTPUT_TYPE OBJ #   X0 ( 0 0 0 0 ) #    LOWER_BOUND ( -10 -10 -10 -1 ) UPPER_BOUND ( 10 10 10 1 ) #     MAX_BB_EVAL 1000 #   TMP_DIR /tmp
      
      





NOMADを起動します。



 kbulatov@node ~> ./NOMAD.3.6.0/bin/nomad params.nomad NOMAD - version 3.6.0 - www.gerad.ca/nomad Copyright (C) 2001-2013 { Mark A. Abramson - The Boeing Company Charles Audet - Ecole Polytechnique de Montreal Gilles Couture - Ecole Polytechnique de Montreal John E. Dennis, Jr. - Rice University Sebastien Le Digabel - Ecole Polytechnique de Montreal Christophe Tribes - Ecole Polytechnique de Montreal } Funded in part by AFOSR and Exxon Mobil. License : '$NOMAD_HOME/src/lgpl.txt' User guide: '$NOMAD_HOME/doc/user_guide.pdf' Examples : '$NOMAD_HOME/examples' Tools : '$NOMAD_HOME/tools' Please report bugs to nomad@gerad.ca MADS run { BBE OBJ 1 41100.0000000000 5 27814.0000000000 12 22459.0000000000 14 5070.0000000000 36 4853.0000000000 44 4828.0000000000 49 4720.0000000000 58 4657.0000000000 78 4583.0000000000 93 4514.0000000000 106 4509.0000000000 115 4495.0000000000 117 4494.0000000000 118 4484.0000000000 119 4453.0000000000 133 4379.0000000000 145 4376.0000000000 153 4217.0000000000 156 4158.0000000000 177 4034.0000000000 181 3982.0000000000 184 3942.0000000000 216 3918.0000000000 237 3905.0000000000 262 3903.0000000000 458 3903.0000000000 } end of run (mesh size reached NOMAD precision) blackbox evaluations : 458 best feasible solution : ( 1.300140381 0.6046962738 -0.9088993073 -1 ) h=0 f=3903
      
      





最後の行には、必要な係数が含まれています。



追加機能



構成ファイルでは、最適化アルゴリズムの膨大な数の追加パラメーターを指定できます。このレビューでは、主要なパラメーターのみを説明しています。



NOMADを静的C ++ライブラリ(ライブラリモード)として使用することもできます。 この場合、次のような機能を計算するクラスを作成する必要があります。



 class MyEvaluator: public NOMAD::Evaluator { public: MyEvaluator(NOMAD::Parameters const& p) : NOMAD::Evaluator(p) {} ~MyEvaluator() {} bool eval_x(NOMAD::Eval_Point& x, NOMAD::Double const& h_max, bool& count_eval) const { ///   ///  false,  -    ... count_eval = true; return true; } }
      
      





あとがき



この例はややタイトであることが判明しました。より効率的な検索のためには、もちろん、ライブラリモードを使用する必要がありました。 さらに、この場合の汎関数はスケーリングされた信号関数の合計であり、これらの信号関数が何らかのシグモイドによって近似される場合、アルゴリズムの動作を大幅に促進することができました。 少なくとも、機能は継続的です。 しかし、目標は-例証する-達成されています。



誰かがそれらを知っていて、成功したアプリケーションの経験があるなら、私はあなたがこのようなことをすることを可能にする他のツールについて聞いてうれしいです。






All Articles