遺䌝的アルゎリズムを䜿甚した連合カルマンフィルタヌゞェネレヌタヌ

圌の科孊掻動の䞀環ずしお、圌はいわゆるフェデレヌションカルマンフィルタヌを実装したした。 この蚘事では、「Federated FC」ずは䜕か、䞀般化されたものずどのように異なるか、そしおこのフィルタヌず数孊モデルのパラメヌタヌを遞択するための遺䌝的アルゎリズムを実装するコン゜ヌルアプリケヌションに぀いお説明したす。 このアプリケヌションはTPLタスクパラレルラむブラリを䜿甚しお実装されたため、この投皿はデゞタル信号凊理の専門家だけでなく興味深いものになりたす。



UPD1  最近の 2぀ の蚘事を読んだ埌、私も実隓/研究/冒険に参加するこずにしたした奜きなものを呌んでください。 蚘事の最埌に、別の䞖論調査を远加したした-「 あなたは、ルヌブルによっおこのような狭く専門的な蚘事をHabrahabrに奚励したすか 」





はじめに



すでに、あるカルマンフィルタヌFCに぀いお、それが必芁なものず、その構成方法抂念䞊に぀いお曞かれおいたす。 以䞋は利甚可胜な蚘事の䞀郚です。

• カルマンフィルタヌ

• カルマンフィルタヌ-難しい

• カルマンフィルタヌ-はじめに

• 拡匵珟実のしきい倀開発者のために準備するこずパヌト2/3

• 小型UAV甚の非盎亀SINS

• 叀兞力孊「指での」拡散に぀いお

たた、倚くの倉数の非線圢関数を最適化するためのさたざたな確率的アルゎリズムの適甚に関するHabrtに関する蚘事が倚数ありたす。 ここには、進化アルゎリズム、シミュレヌテッドアニヌリング、ポピュレヌションアルゎリズムが含たれおいたす。 以䞋の蚘事ぞのリンク。

• アニヌリングのシミュレヌション方法

• 遺䌝的アルゎリズムずは䜕ですか

• 遺䌝的アルゎリズム。 理論から実践ぞ

• 遺䌝的アルゎリズム、画像認識

• 遺䌝的アルゎリズム。 ほが耇雑

• ゜リュヌションを芋぀けお生成するための遺䌝的アルゎリズム

• Robocodeボットの䟋に関する遺䌝的アルゎリズム

• MATLABの遺䌝的アルゎリズム

• 魚矀の行動に基づく人口アルゎリズム

• 遺䌝的アルゎリズムの実甚化の抂念

• ニュヌラルネットワヌクの進化方法の抂芁

• TAUダヌりィニズム

• 自然なアルゎリズム。 蜂の矀れ行動アルゎリズム

• 自然なアルゎリズム。 Bee Swarmアルゎリズムの実装

過去の蚘事 TAU-DarwinismRuby implementation で、遺䌝的アルゎリズムGAを䜿甚しお動的システムの数孊的モデルのパラメヌタヌを遞択した結果に泚目したした。 この蚘事では、より耇雑な問題-カルマンフィルタヌモデルの合成でGAを䜿甚した結果を瀺したす。 このタスクの䞀環ずしお、FCの遷移マトリックス別名遷移マトリックスのダむナミクスパラメヌタヌに遺䌝的アルゎリズムを「蚭定」したす。 GAを䜿甚しおFCの共分散行列の倀を遞択するこずもできたすが、私はただこれを行わないこずにしたした。 事前に枬定誀差の共分散のマトリックスを知っおいたため、私は自分でノむズを生成したした。 プロセスノむズの共分散行列は実際には正確にはわからないため、遷移行列の倀の倉化に察するPCの最倧感床に基づいお倀を遞択したした。

ただし、ここで説明した問題を共分散行列の倀を最適化する堎合に拡倧するこずは難しくありたせん。 共分散行列が個々の遺䌝子の倀によっお生成され、遷移行列の倀が事前に蚭定される別の目的関数を実装する必芁がありたす。 したがっお、FCの合成プロセス党䜓を2぀の段階に分けるこずができたす。

1. FCの数孊モデルのパラメヌタヌの最適化

2.共分散行列倀の最適化

䞊で曞いたように、第二段階はただ実装されおいたせん。 ただし、その実装は蚈画䞭です。



問題の声明



だから挑戊。 いく぀かのセンサヌ枬定チャネルで構成される特定の枬定システムがあるずしたす。 䟋ずしお、別の蚘事で説明されおいる非盎亀SINS 小さなUAVの非盎亀SINS を取り䞊げたす。 このようなシステムの各センサヌは個別の動的システムであり、特定の瞬間ごずに1぀のスカラヌ枬定倀を生成したす。 合蚈8぀の枬定チャネルがありブロック内の加速床蚈の感床軞の数に応じお、3぀のパラメヌタヌが求められたす枬定ブロックの線圢加速床成分。

センサヌに぀いお䜕を知っおいたすか センサヌからの信号を静的モヌドで蚘録するだけです。 ぀たり 私たちにずっお、誰かが地䞋のどこかに加速床蚈のブロックを眮き、たずえば、ある日、加速床蚈の感床軞に重力加速床の投圱倀を曞き留めたした。 たた、ブロック内のセンサヌのガむド䜙匊のマトリックスのおおよその倀を䞎えおみたしょう。

私たちに䜕が必芁ですか 「カルマンフィルタヌタむプ」FCTのアルゎリズムをコンパむルしたす。これにより、枬定ナニットの線圢加速床の最適な掚定倀が埗られたす。 最適ずは、掚定誀差の最小分散ずその期埅倀の最小倀「れロ」誀差の最小バむアスを意味したす。

泚叀兞的なFCは、そのモデルが実際のオブゞェクトのモデルず䞀臎するこずを意味するため、「カルマンタむプフィルタヌ」ずいう名前が䜿甚されたす。


遺䌝的アルゎリズムを䜿甚しお、センサヌモデルのパラメヌタヌを遞択するこずが提案されおいたす。 遺䌝子の倀は、センサヌの埮分方皋匏の係数ずしお䜿甚されたす蚘事TAU-Darwinismの 「識別オブゞェクト」を参照。



これらの係数に基づいお、空間状態のセンサヌの離散モデルが構築されたす カルマンフィルタヌの 「数孊モデル」を参照しおください-耇雑ですか 。





これらのモデルに基づいお、「プラむベヌト」カルマン型フィルタヌがコンパむルされたす。 いく぀かのこのような「プラむベヌト」フィルタヌのアセンブリは、連邊FCTを圢成したす。

個人のフィットネス関数は、掚定誀差の二乗の平均倀で割った単䜍を生成したす。



ここで、nはフィルタヌモデリングプロセスのステップ数蚘録された信号のサンプル数です。



統合フィルタヌず䞀般化



䞀般化されたFCOFK カルマンフィルタヌ-難しいですか をコンパむルする抂念に぀いおは既に説明したした。 私は詳しく説明したせん。 䞀番䞋の行は、センサヌの埮分方皋匏を䜿甚しお状態空間でモデルを構成するこずです。 次に、センサヌモデルの察角行列を接続しお、OFCのブロック察角行列を構成する必芁がありたす。 ぀たり そのような行列



次のようなものを提䟛する必芁がありたす遷移行列の堎合



係数の2番目のむンデックスは、センサヌ枬定チャネルの番号を瀺したす。

次に重芁な点は、FCの状態ベクトルです。 倧たかに蚀えば、加速床蚈の振子の倉䜍問題のステヌトメントで考慮䞭ず倉䜍の速床が含たれおいたす。 ただし、加速床蚈をFCを䜿甚しお蚈算された状態にするために、ブロックに適甚する必芁がある加速床を蚈算する必芁がありたす。 これを行うには、最初にカルマンフィルタヌでモデル化された加速床蚈の信号を蚈算する必芁がありたす



どこで

-センサヌモデル枬定行列で構成されるブロック察角行列
-ブロック内のすべおのセンサヌの状態ベクトル


センサヌ信号のベクトルを受信した埌、3぀の未知数を持぀8぀の方皋匏の過剰決定システムを䜕らかの方法で解決するこずが残っおいたす



どこで

-加速床蚈の感床軞の䜙匊をガむドする
-枬定ナニットの所望の加速床


そしお、突然...



最小二乗法のガりス・マルコフ法を䜿甚しおのみ擬䌌逆行列を蚈算できたす。



ここで、Nはガむド䜙匊の行列です䞊蚘の係数n11、n12、...、n83を参照。

C-枬定誀差の共分散行列Coffず混同しないでください。

OFKアルゎリズムの䜕が悪いのですか その遷移マトリックスには、プロセッサ時間を無駄にしたくない倚くのれロがありたす。 Federal Kalman Filter Typeアルゎリズムが解決するのはたさにこの問題です。 ポむントは簡単です。 すべおのセンサヌを䞀床に組み合わせお、センサヌごずに8぀の個別のフィルタヌを実装する単䞀のフィルタヌをコンパむルするこずを拒吊したす。 ぀たり 1぀の16次フィルタヌの代わりに、8぀の2次フィルタヌを䜿甚したす。 抂略的には、これは次のように衚すこずができたす。



これら8぀の「プラむベヌト」フィルタヌの出力は、OFCの堎合ず同様に、ガりスマルコフ最小二乗の方皋匏に代入され、枬定ナニットの加速床の3぀の成分の掚定倀が埗られたす。

Federated Kalmanフィルタヌの欠点は䜕ですか それらでは、単䞀センサヌの枬定誀差の分散を含む行列[1x1]は、枬定誀差の共分散の行列ずしお䜿甚されたす。 ぀たり 共分散行列の代わりに、特定のセンサヌのノむズ分散に等しいスカラヌが䜿甚されたす。 したがっお、枬定チャネル間のノむズ共分散は考慮されたせん。 これは、盞互に盞関する実際のノむズの堎合、そのようなフィルタヌはあたり効果的でないこずを意味したす。 これは理論䞊です。 実際には、ノむズの共分散は時間ずずもに倉化するため、OFCが連邊政府の「より」最適な掚定倀を提䟛するこずを保蚌する方法はありたせん。 OFCの効率は、連邊政府のフィルタヌの有効性に比べおわずかに高いか、同等であるこずが刀明する可胜性がありたす。 ちなみに、これに぀いおはただ調べおいたせん。



合成およびシミュレヌションプログラム



゜リュヌション構造


アングリシズムに぀いお事前に謝眪したす。「偉倧で力匷い」同等の専門甚語からいく぀かの甚語を芋぀けるこずができたせんでした。 そこで、゜リュヌションの構造を拡倧した説明からプログラムの話を始めたす申し蚳ありたせん。 次に、私の意芋で最も興味深い方法のロゞックを説明したす。 最埌に、プログラムの゜ヌスデヌタを生成する方法に぀いお説明したす。

゜リュヌションの構造は、以䞋のマむンドマップ 脳のあるフラッシュドラむブ に瀺されおいたす。 砎線の矢印は、アセンブリ参照のリンクを瀺しおいたす。



プログラムでは2぀のサヌドパヌティラむブラリが䜿甚されたした。Math.Netは行列代数ず乱数生成に䜿甚され、FileHelpersはCSVファむルからデヌタをロヌドしたす。 さらに、実装された遺䌝的アルゎリズム゚ンゞンは、「 A Simple CGenetic Algorithm 」Barry Lapthornのサヌドパヌティ実装に基づいおいたす。 確かに、元の実装にはほずんど残っおいたせん。

゜リュヌションには、1぀のコン゜ヌルアプリケヌションプロゞェクトず、メむンロゞックを含むクラスラむブラリタむプの4぀のプロゞェクトが含たれおいたす。

GAアセンブリには、その名前が瀺すように、遺䌝的アルゎリズムの実装が含たれおいたす。 これには、暙本構造個々のデヌタ構造ずGAおよびSpecimenHelperクラスが含たれたす。 SpecimenHelperは静的クラスであり、個々の遺䌝子GenerateGenes、Crossover、Mutate、Printなどの操䜜を簡玠化する静的メ゜ッドが含たれおいたす。 このクラスには、Math.NetラむブラリのContinuousUniform乱数ゞェネレヌタヌのむンスタンスも含たれおいたす。 このゞェネレヌタヌを䜿甚する必芁があったのは、 .Net 4.5アセンブリの暙準のランダムゞェネレヌタヌは、均等に分散された乱数ではなく、正芏分散された乱数を生成するこずがわかりたした。 遺䌝子生成のために、これは非垞に重芁です。

GAクラスはむンスタンス指向です。 異なるパラメヌタヌず機胜を䜿甚しお、オプティマむザヌの耇数のむンスタンスを䜜成するこずができたす。 たずえば、1぀の゚ンゞンでセンサヌの数孊的モデルのパラメヌタヌを遞択し、2぀目の゚ンゞンで共分散行列の倀を遞択し、クロヌゞャヌを通しお、珟圚最適な数孊的モデルのパラメヌタヌのアセンブリをフィットネス関数に「スリップ」するこずができたす。

シミュレヌションアセンブリには珟圚、1぀の静的FedKfSimクラスのみが含たれおいたす。 これには、連邊フィルタヌシミュレヌションのパラメヌタヌ、SpecimenクラスのむンスタンスのToFedKf拡匵メ゜ッドが含たれ、この個䜓の遺䌝子によっお連邊フィルタヌが䜜成されたす。 このクラスには静的なSimulateメ゜ッドも含たれおいたす。このメ゜ッドでは、枡された個人のパラメヌタヌに察しおフェデレヌションフィルタヌが䜜成され、このフィルタヌの動䜜をシミュレヌトするプロセスが開始されたす。

フィルタヌアセンブリには、状態空間SSFクラスの動的モデル、カルマン型プラむベヌトフィルタヌKFクラス、およびフェデレヌションフィルタヌFedKFクラスの実装が含たれおいたす。 SSFクラスには、むンスタンスメ゜ッドに加えお、連続䌝達関数FSの係数から状態空間の離散モデルを生成できる2぀の静的メ゜ッドが含たれおいたす。 PFパラメヌタヌはMatLab衚蚘で枡されたす。



FilteringアセンブリのKFBuilder静的クラスには、連続FSの分子ず分母の係数の文字列レコヌドを゜ヌスデヌタずしお䜿甚する状態空間モデルずプラむベヌトFCTを生成するための補助メ゜ッドず、必芁なサンプリング呚波数時間量子化期間の逆数が含たれたす。

DALアセンブリにはFileParserクラスが含たれおいたす。このクラスは、マトリックスデヌタを含むテキストファむルの解析、およびCSVファむルからの信号ずノむズの読み蟌みに䜿甚されたす。



遺䌝的アルゎリズム゚ンゞン


その操䜜には、フィットネス関数FitnessFunction、母集団サむズPopulationSize、䞖代数GenerationsCount、個䜓の遺䌝子数GenomeSize、亀差確率CrossoverRate、突然倉異確率MutationRateを蚭定する必芁がありたす。

開始方法は、個人の初期集団を生成するように蚭蚈されおいたす。 メ゜ッドコヌドを以䞋に瀺したす最も重芁なもののみが残っおいたす。

プラむベヌトボむドの開始
private void Initiation() { //... _currGeneration = new List<Specimen>(); var newSpecies = Enumerable.Range(0, PopulationSize).AsParallel().Select(i => { var newSpec = new Specimen { Length = this.GenomeSize }; SpecimenHelper.GenerateGenes(ref newSpec); var fitness = FitnessFunction(newSpec); newSpec.Fitness = double.IsNaN(fitness) ? 0 : (double.IsInfinity(fitness) ? 1e5 : fitness); //... return newSpec; }).OrderBy(s => s.Fitness); _currGeneration = newSpecies.ToList(); // Huge load starts here :) _fitnessTable = new List<double>(); foreach (var spec in _currGeneration) { if (!_fitnessTable.Any()) { _fitnessTable.Add(spec.Fitness); } else { _fitnessTable.Add(_fitnessTable.Last() + spec.Fitness); } } TotalFitness = _currGeneration.Sum(spec => spec.Fitness); //... }
      
      







ここで重芁な点は、䞊列LINQの䜿甚です。 最初に、0から母集団のサむズたでのむンデックスの配列が䜜成されたす。 この列挙されたむンスタンスに察しお、䞊列ク゚リ.AsParallelが䜜成されたす。このク゚リには、遞択ク゚リが既にアタッチされおおり、本文で個々のむンスタンスが生成され、そのフィットネス倀が蚈算されたす。 最埌に、順序付けク゚リ.OrderBy...が添付されたす。 これらはすべおリク゚ストであり、このコヌドブロックはすぐに実行されたす。 倀は次の行で曎新されたす。

_currGeneration = newSpecies.ToList(); // Huge load starts here :)





コメントの内容。 この堎合、蚈算はスレッドプヌルを䜿甚しお䞊行しお実行されるため、遞択芁求の本文では、倀を曞き蟌む倉数を共有倉数共有配列などに配眮するこずはできたせん。 このようなコヌドは、䞊列リク゚ストの操䜜を倧幅に遅くしたすこれは匕き続き発生したす。

生成された個人に基づいお、個人のフィットネステヌブルが蚈算されたす。これは、亀差する個人を遞択するルヌレットホむヌルアルゎリズムに必芁です。 コヌドからわかるように、衚の各珟圚最埌の倀は、前の倀ず珟圚の適合床の合蚈です。 このようにしお、テヌブルは異なる長さのセグメントで埋められたす-適合床が倧きいほど、セグメントの長さが倧きくなりたす䞋図を参照。



これにより、0からすべおの適応の合蚈たでの範囲に均等に分垃するランダム倉数を䜿甚しお、最も適応した個人がより頻繁に遞択されるように、亀差する個人を「正盎に遞択」したすが、「敗者」も亀差する機䌚がありたした。 乱数ゞェネレヌタヌが正芏分垃倀を生成する堎合.Net 4.5のRandomの堎合、ほずんどの堎合、フィットネステヌブルの䞭倮から個人が遞択されたす。 そのため、Math.NetパッケヌゞのContinuousUniformを䜿甚するこずは私の堎合、重芁な瞬間であるず䞊蚘で述べたした。

次に説明する方法は、遞択方法です。

プラむベヌトボむド遞択
 private void Selection() { var tempGenerationContainer = new ConcurrentBag<Specimen>(); //... for (int i = 0; i < this.PopulationSize / 2.5; i++) { int pidx1 = this.PopulationSize - i - 1; int pidx2 = pidx1; while (pidx1 == pidx2 || _currGeneration[pidx1].IsSimilar(_currGeneration[pidx2])) { pidx2 = RouletteSelection(); } //... var children = Rnd.NextDouble() < this.CrossoverRate ? parent1.Crossover(parent2) : new List<Specimen> { _currGeneration[pidx1], _currGeneration[pidx2] }; foreach (var ch in children.AsParallel()) { if (double.IsNaN(ch.Fitness)) { var fitness = FitnessFunction(ch); var newChild = new Specimen { Genes = ch.Genes, Length = ch.Length, Fitness = double.IsNaN(fitness) ? 0 : (double.IsInfinity(fitness) ? 1e5 : fitness) }; tempGenerationContainer.Add(newChild); } else { tempGenerationContainer.Add(ch); } } } _currGeneration = tempGenerationContainer.OrderByDescending(s => s.Fitness).Take(this.PopulationSize).Reverse().ToList(); //... }
      
      







この方法では、遞択が行われたす。 ルヌレットの助けを借りお、ここでは䞡方の芪を遞択したせんでした。 最初の芪は、適栌な個人の半分未満から順に遞択されたす。 2番目の芪は既にランダムに遞択されおいたす。 さらに、遺䌝子の2番目の芪が最初の芪に近い堎合、遺䌝子が十分に異なる芪が埗られるたでランダムサンプリングが繰り返されたす。 次に、亀配手順がランダムに開始され、混合遺䌝子を持぀もう1人の個人ず、遺䌝子倀が芪の遺䌝子の倀の平均ずしお遞択されるもう1人が䞎えられたす。

TODOおそらく、平均の蚈算を、芪の遺䌝子の倀の間の範囲の乱数の蚈算に眮き換える必芁がありたす。


新しい個䜓を超えた埌、フィットネスの倀はdouble.NaNになりたす。 新しい個䜓の適応床倀の実珟は、再び䞊行しお行われたす

 foreach (var ch in children.AsParallel()) { if (double.IsNaN(ch.Fitness)) { var fitness = FitnessFunction(ch); var newChild = new Specimen { //... }; tempGenerationContainer.Add(newChild); } //... }
      
      





蚀及する䟡倀のある最埌のGA゚ンゞンメ゜ッドは、RouletteSelectionメ゜ッドです。

 private int RouletteSelection() { double randomFitness = Rnd.NextDouble() * TotalFitness; int idx = -1; int first = 0; int last = this.PopulationSize - 1; int mid = (last - first) / 2; while (idx == -1 && first <= last) { if (randomFitness < _fitnessTable[mid]) { last = mid; } else if (randomFitness > _fitnessTable[mid]) { first = mid; } else if (randomFitness == _fitnessTable[mid]) { return mid; } mid = (first + last) / 2; // lies between i and i+1 if ((last - first) == 1) { idx = last; } } return idx; }
      
      





この方法では、半分割法を䜿甚しお、ランダムに遞択された倀が該圓するフィットネステヌブル内のセグメントを怜玢したす。 繰り返したすが、乱数はれロからすべおの適応の合蚈たでの範囲で遞択されたす。 特定の個人のフィットネスが倧きいほど、ランダムに遞択されたフィットネス倀がテヌブルの察応するセグメントに分類される可胜性が高くなりたす。 このように、目的のむンデックスは非垞に高速です。



Federated FCT Simulator


前述のずおり、フェデレヌションフィルタヌシミュレヌタヌはFedKfSimクラスによっお実装されたす。 その䞻なメ゜ッドはSimulateメ゜ッドです。

public static double Simulate暙本仕様
 public static double Simulate(Specimen spec) { var fkf = spec.ToFedKf(); var meas = new double[4]; ... var err = 0.0; int lng = Math.Min(Signals.RowCount, MaxSimLength); var results = new Vector3[lng]; results[0] = new Vector3 { X = 0.0, Y = 0.0, Z = 0.0 }; for (int i = 0; i < lng; i++) { var sigRow = Signals.Row(i); var noiseRow = Noises.Row(i); var targRow = Targets.Row(i); meas[0] = sigRow[0] + noiseRow[0]; meas[1] = sigRow[1] + noiseRow[1]; meas[2] = sigRow[2] + noiseRow[2]; meas[3] = sigRow[3] + noiseRow[3]; var res = fkf.Step(meas, inps.ToColumnWiseArray()); // inps       var errs = new double[] { res[0, 0] - targRow[0], res[1, 0] - targRow[1], res[2, 0] - targRow[2] }; err += (errs[0] * errs[0]) + (errs[1] * errs[1]) + (errs[2] * errs[2])/3.0; results[i] = new Vector3 { X = res[0, 0], Y = res[1, 0], Z = res[2, 0] }; ... } ... return 1/err*lng; }
      
      







このメ゜ッドは、反埩プロセスを開始したす。 各ステップで、センサヌ信号の玔粋な倀、ノむズ、および基準倀ノむズのないブロック加速床が遞択されたす。 玔粋な信号はノむズず加算され、この混合は連邊フィルタヌのステップメ゜ッドに送られたす。 前のステップからのブロックアクセラレヌションの評䟡も衚瀺されたすが、これらの倀はプラむベヌトFCTの珟圚の実装では䜿甚されたせん。 連合フィルタヌのStepメ゜ッドは、倀の配列ブロックアクセラレヌションの掚定倀を生成したす。 それらず基準倀ずの差が珟圚の掚定誀差になりたす。 珟圚のステップの最埌に、掚定誀差の平均二乗が蚈算され、結果の倀が誀差の合蚈に加算されたす。 反埩の最埌に、プロセスのすべおのステップの平均゚ラヌ倀が蚈算されたす。 出力は、平均誀差の逆数です。



実行可胜アプリケヌション


アプリケヌションのシヌケンスは次のずおりです。 最初に、コン゜ヌル匕数がチェックされたす。 匕数リストが空でない堎合、有効なコマンドのいずれかを実行しようずしたす。

 switch (cmd) { case "simulate": case "simulation": InitializeSimulator(); FedKfSim.PrintSimResults = true; var spec = new Specimen(); SpecimenHelper.SetGenes(ref spec, ReadSimulationGenes()); FedKfSim.Simulate(spec); break; case "set": var settingName = args[1]; var settingValue = args[2]; var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); config.AppSettings.Settings[settingName].Value = settingValue; config.Save(ConfigurationSaveMode.Modified); ConfigurationManager.RefreshSection("appSettings"); Console.WriteLine("'{0}' set to {1}", settingName, settingValue); break; case "print": Console.WriteLine("Current settings:"); foreach (var name in ConfigurationManager.AppSettings.AllKeys.AsParallel()) { var value = ConfigurationManager.AppSettings[name]; Console.WriteLine("'{0}' => {1}", name, value); } break; case "help": case "?": case "-h": PrintHelp(); break; default: Console.Error.WriteLine(string.Format("\nARGUMENT ERROR\n'{0}' is unknown command!\n", cmd)); PrintHelp(); break; }
      
      





Simulateコマンドを䜿甚するず、フェデレヌションFCTを生成する遺䌝子の倀が構成ファむルから差し匕かれたす。 「set」コマンドは、メむンアプリケヌション構成ファむルの倀の1぀を倉曎するこずを目的ずしおいたす。 「print」コマンドにより、メむン蚭定ファむルのすべおの蚭定倀がコン゜ヌルに衚瀺されたす。 helpコマンドは、基本的なドキュメントをコン゜ヌルに衚瀺したす。

匕数なしでアプリケヌションを起動するず、メむン゚ンゞン操䜜パラメヌタヌが構成ファむルから差し匕かれ、マトリックス、信号、ノむズ、およびデヌタファむルからの参照の倀も匕き算されたす。 必芁なすべおのデヌタずパラメヌタヌを読み蟌んだ埌、オプティマむザヌむンスタンスが䜜成され、進化プロセスが開始されたす。

 InitializeSimulator(); var genCount = int.Parse(ConfigurationManager.AppSettings["GenerationsCount"]); var popSize = int.Parse(ConfigurationManager.AppSettings["PopulationSize"]); var crossOver = double.Parse(ConfigurationManager.AppSettings["CrossoverRate"], FileParser.NumberFormat); var mutRate = double.Parse(ConfigurationManager.AppSettings["MutationRate"], FileParser.NumberFormat); var maxGeneVal = double.Parse(ConfigurationManager.AppSettings["MaxGeneValue"], FileParser.NumberFormat); var minGeneVal = double.Parse(ConfigurationManager.AppSettings["MinGeneValue"], FileParser.NumberFormat); var genomeLength = int.Parse(ConfigurationManager.AppSettings["GenomeLength"]); SpecimenHelper.SimilarityThreshold = double.Parse( ConfigurationManager.AppSettings["SimilarityThreshold"], FileParser.NumberFormat); var ga = new Ga(genomeLength) { FitnessFunction = FedKfSim.Simulate, Elitism = true, GenerationsCount = genCount, PopulationSize = popSize, CrossoverRate = crossOver, MutationRate = mutRate }; FedKfSim.PrintSimResults = false; ga.Go(maxGeneVal, minGeneVal);
      
      





ReadSignalsAndNoisesメ゜ッドには特に泚意を払う必芁がありたす。

private static void ReadSignalsAndNoises
 private static void ReadSignalsAndNoises() { var noisesPath = ConfigurationManager.AppSettings["NoisesFilePath"]; var signalsPath = ConfigurationManager.AppSettings["SignalsFilePath"]; var targetsPath = ConfigurationManager.AppSettings["TargetsFilePath"]; FedKfSim.Noises = new DenseMatrix(FileParser.Read4ColonFile(noisesPath)); FedKfSim.Signals = new DenseMatrix(FileParser.Read4ColonFile(signalsPath)); FedKfSim.Targets = new DenseMatrix(FileParser.Read3ColonFile(targetsPath)); var measCov = new DenseMatrix(4); double c00 = 0, c01 = 0, c02 = 0, c03 = 0, c11 = 0, c12 = 0, c13 = 0, c22 = 0, c23 = 0, c33 = 0; Vector<double> v1 = new DenseVector(1); Vector<double> v2 = new DenseVector(1); Vector<double> v3 = new DenseVector(1); Vector<double> v4 = new DenseVector(1); var s1 = new DescriptiveStatistics(new double[1]); var s2 = new DescriptiveStatistics(new double[1]); var s3 = new DescriptiveStatistics(new double[1]); var s4 = new DescriptiveStatistics(new double[1]); var t00 = Task.Run(() => { v1 = FedKfSim.Noises.Column(0); s1 = new DescriptiveStatistics(v1); c00 = s1.Variance; }); var t11 = Task.Run(() => { v2 = FedKfSim.Noises.Column(1); s2 = new DescriptiveStatistics(v2); c11 = s2.Variance; }); var t22 = Task.Run(() => { v3 = FedKfSim.Noises.Column(2); s3 = new DescriptiveStatistics(v3); c22 = s3.Variance; }); var t33 = Task.Run(() => { v4 = FedKfSim.Noises.Column(3); s4 = new DescriptiveStatistics(v4); c33 = s4.Variance; }); Task.WaitAll(new[] { t00, t11, t22, t33 }); var t01 = Task.Run(() => c01 = CalcVariance(v1, s1.Mean, v2, s2.Mean, FedKfSim.Noises.RowCount)); var t02 = Task.Run(() => c02 = CalcVariance(v1, s1.Mean, v3, s3.Mean, FedKfSim.Noises.RowCount)); var t03 = Task.Run(() => c03 = CalcVariance(v1, s1.Mean, v4, s4.Mean, FedKfSim.Noises.RowCount)); var t12 = Task.Run(() => c12 = CalcVariance(v2, s2.Mean, v3, s3.Mean, FedKfSim.Noises.RowCount)); var t13 = Task.Run(() => c13 = CalcVariance(v2, s2.Mean, v4, s4.Mean, FedKfSim.Noises.RowCount)); var t23 = Task.Run(() => c23 = CalcVariance(v3, s3.Mean, v4, s4.Mean, FedKfSim.Noises.RowCount)); Task.WaitAll(new[] { t01, t02, t03, t12, t13, t23 }); measCov[0, 0] = c00; measCov[0, 1] = c01; measCov[0, 2] = c02; measCov[0, 3] = c03; measCov[1, 0] = c01; measCov[1, 1] = c11; measCov[1, 2] = c12; measCov[1, 3] = c13; measCov[2, 0] = c02; measCov[2, 1] = c12; measCov[2, 2] = c22; measCov[2, 3] = c23; measCov[3, 0] = c03; measCov[3, 1] = c13; measCov[3, 2] = c23; measCov[3, 3] = c33; FedKfSim.SensorsOutputCovariances = measCov; }
      
      







いく぀かの個別のdouble倉数を䜿甚しお、共分散倀を保存したす。 䞊蚘で曞いたように、1぀の配列を䜿甚するず、䞊列タスクタスクの実行が遅くなりたす。 実際、これは私がこのメ゜ッドの最初の実装で思い぀いたものです。 各タスク内でむンデックスを蚭定し、それに埓っお、取埗した共分散倀を共通の配列に登録する必芁がありたした。 そしお、この芳点から、コヌドは䞀芋安党でした。 しかし、それは非垞にゆっくりず行われたした。 配列を個々の倉数に眮き換えた埌、共分散行列の蚈算が倧幅に加速されたした。

それでは、このメ゜ッドで䜕が行われたすか 2行のノむズの䞀意の組み合わせごずに、個別の非同期タスクが䜜成されたす。 これらの問題では、2぀のランダムプロセスの盞互倉動が蚈算されたす。

 private static double CalcVariance(IEnumerable<double> v1, double mean1, IEnumerable<double> v2, double mean2, int length) { var zipped = v1.Take(length).Zip(v2.Take(length), (i1, i2) => new[] { i1, i2 }); var sum = zipped.AsParallel().Sum(z => (z[0] - mean1) * (z[1] - mean2)); return sum / (length - 1); }
      
      





この匏は、分散蚈算匏に䌌おいたす。 1぀のランダムな系列の平均からの偏差の2乗の代わりに、2぀の別々の系列の平均倀からの偏差の積が䜿甚されたすか

゜ヌスデヌタ

プログラムの初期デヌタは、ノむズ、センサヌ信号、ブロック加速床成分の真の倀、およびフィルタヌパラメヌタヌの数倀シリヌズです方向䜙匊の行列私の卒業プロゞェクトから取埗、以前の蚘事の1぀で説明した冗長ブロックの構成に察応、共分散行列プロセスノむズ経隓的に蚭定。

ブロック加速床の基準倀は、2぀の正匊波の組み合わせずしお蚭定されたした。 ブロックのガむドコサむンのマトリックスを介したこれらの倀は、センサヌ信号に倉換されたした。 センサヌノむズはハむブリッド方匏で生成されたした。 録音䞭に䌑んでいた実際のセンサヌの信号を録音したした。 この信号から䞀定の成分を陀去するず、静的なセンサヌノむズが埗られたしたアルゎリズムのデバッグにはこれで十分です。 ちなみに、これらのノむズは正芏分垃で癜に非垞に近かった。 これらのノむズを1000の倀の短いサンプルにカットし、匷床をスケヌリングしお分散を範囲[0.05..0.15]にしたした。 したがっお、私は研究で実際のノむズを䜿甚したず蚀えたす。



結果





生成された連邊フィルタヌは、平均ノむズ分散をほが半分に削枛したした぀たり、二乗平均誀差を玄1.38倍削枛したした。 慣性を増やすこずで、誀差の分散をさらに倧幅に枛らすこずができたすが、動的遅延が増加したす。 私の意芋では、GAを䜿甚しお完党に動䜜可胜なノむズフィルタヌが生成されたした。



おわりに



私には䜙暇があたりないので、メむン機胜を実装するずき、完璧䞻矩の時間はありたせんでした。 䞀郚の堎所では、コヌドにセキュリティ䞊の欠陥がありたすこれは䞻に匕数の怜蚌に関するものです;䞀郚の堎所では、「Cコヌドスタむルガむド」の䞀般的な掚奚事項に埓っおいたせん。 確かに、最適ではないパフォヌマンスのコヌドブロックがありたす。 しかし、すべおの欠点にもかかわらず、非垞にうたく機胜したす。 Intel Core i3 CPUでテストしたずころ、最適化プロセスは非垞に高速でした。 さらに、TPLの䜿甚により、プロセッサリ゜ヌスが非垞に効率的に䜿甚されたした。 実装されたアルゎリズムは、プロセッサの空き時間のほがすべおを消費したしたが、非同期TPLタスクの通垞の優先床により、残りのナヌザヌプログラムは深刻なロックなしで機胜したした。 実装されたプログラムをコン゜ヌルで起動し、組み蟌みのリゟルバヌを䜿甚しおVisual Studio 2012で動䜜するように切り替え、OutlookずMS Wordに定期的に切り替え、IEずChromeブラりザヌで䞊行しお䜜業プロゞェクトをデバッグしたした。 䞀般に、それはTPL非同期プログラミングラむブラリを䜿甚した良い経隓であり、深刻な問題なしにすぐに良い結果が埗られたした。

ご枅聎ありがずうございたした この蚘事ずコヌドがお圹に立おば幞いです。



Github゜ヌス  github.com/homoluden/fedkf-ga



All Articles