ニューラルネットワークスターター - 5シリアル

4.5 ニューラルネットワーク符号化
(ネットワークのエンコーディング)


この本の最初の数章では、遺伝的アルゴリズム符号化のための様々な方法を使用する方法を見てきました。私はここに滞在してご紹介したい知っているのでしかし、彼は、あなたに実数をコードの具体例を説明していませんでした。私は、フィードフォワードニューラルネットワークを設計するために、コーディングは非常に簡単ですが、話しました。我々は、このようにネットワークを実現する、ベクター内に格納されたデータを順次読み出すために、読み出された第一中間層の各層の重量の右右ニューロンに左から読み出され、その後層をそれを読み戻しますコーディング。我々は、図14に示すネットワークを持っているのであれば、それは重みベクトルのエンコードになります。

0.3 -O.8、-O.2、0.6、O.1、-0.l、0.4、0.5

このネットワークでは、簡単のために、私は再付属の価値を相殺する権利を持っていません。しかし、実際の実装コードでは、この重量のオフセット値を含める必要があります、またはあなたは確かにあなたが必要な結果を得ることができません。

図14は、重み符号化です。

あなたはそれについて理解し、物事の話をする前?非常によく、その後のは、遺伝的アルゴリズムを使用して、それをコードする遺伝子を操作する方法を検討するために電源を入れてみましょう。


4.6遺伝的アルゴリズム(遺伝的アルゴリズム)

..//この、すべての重みは、遺伝的アルゴリズムの適用として、以前、この本の中で述べたように、我々はできる、文字列を形成し、バイナリコード化されたゲノムとしてのようになっています。遺伝的アルゴリズム(GA)は、地雷除去機におけるフレームのユーザが指定した数に応じて、許可された(何らかの理由で、私はダニと呼ばれる次のフレームを好む、英語ティックである)の動作の後に行われます。あなたはティック(iNumTicks)のこの番号を見つけることができますiniファイルに設定されています。ここではゲノムのコード構造です。これらのためにあなたは非常に身近なものでなければなりません。

SGenome構造体
{
ベクトル<ダブル> vecWeights;

ダブルdFitness;

SGenome():dFitness(0){}

SGenome(ベクトル<ダブル>ダブルF、W):vecWeights(W)、dFitness(F){}

//リロード'ソート<APOS
友人BOOL演算子<(CONST&SGenome LHS、RHS&SGenome CONST)
{
リターン(lhs.dFitness <rhs.dFitness);
}
};

あなたは上記のコード、SGenome構造から見ることができると私たちは本のSGenome構造の他のすべての部分で見てきたことはほとんど同じである、ここでの唯一の違いは、染色体がのstd ::ベクトルの倍精度ベクトルであるということです。したがって、ハイブリダイゼーションおよび通常の操作と選択操作を適用することが可能です。突然変異操作は、ここで重み値は、嫌がらせの乱数dMaxPerturbation最大値幾分異なっています。このパラメータdMaxPerturbationはiniファイル内で宣言されています。さらに、浮動小数点アルゴリズムとして、突然変異率が高く設定されています。0.1に設定され、このプロジェクトで。

以下は見変異型の関数として、遺伝的アルゴリズムに基づく工学地雷除去機です。

::変異しCGenAlgボイド(ベクトル<ダブル>クロモ&は)
{
//反復重みベクトル、変異した各重量突然変異率
のためには、(私は++;; I <chromo.size()I = 0はint型)
{
//私たちは、重みが行う嫌がらせをしたいですか?
IF(RandFloat()<m_dMutationRate)
{
//重量増加であるか、または少量の減少
クロモ[I] + =(RandomClamped()* CParams :: dMaxPerturbatlonを);
}
}
}

以前のプロジェクトと同じように、私はスマート掃海艇プロジェクトの非常に単純な遺伝的アルゴリズムv1.0のバージョンを保持しているよう。あなたはそれが以前に学んだ技術を向上させるために使用できるように、これは、あなたに多くの余地を残します。他のほとんどのエンジニアリング、唯一の選択エリートルーレットモードでv1.Oバージョン、およびシングルポイント十字架好きなように。

注:プログラムを実行すると、重量が任意のサイズへと進化することができ、それらは制限の任意の形態を受けません。


4.7 地雷除去機のタイプ(CMinesweeperクラス)

これは、地雷除去機を定義するために使用されるクラスです。前の章で説明したように月のようなボートクラスは、レコード地雷除去機の位置、速度、方向、等、どのようデータを変換するを含むクラス地雷除去機があります。さらに視線ベクトルクラス地雷除去機(ルックでベクター)を含む、その2つの成分は、ニューラルネットワークの入力2として使用されます。これは、各フレームは、図2に示すように、向かう方向である現在の地雷除去機を示している地雷除去機械自体の回転角度に基づいて算出された正規化されたベクターです。

ここで地雷除去機クラスCMinesweeper文はあります:

CMinesweeperクラス
{
プライベート:
//地雷除去機のニューラルネットワーク
CNeuralNet m_ItsBrain。

//世界でその位置が座標
SVector2D m_vPosition;

方向//地雷除去機の顔
SVector2D m_vLookAt。

//その回転(サプライズサプライズ)
ダブルm_dRotation。

ダブルm_dSpeed;

ANNは、//出力セーブ
ダブルm_lTrack、
m_rTrackを。

ネットワークm_rTrack m_lTrackは、現在のフレームの出力を保持します。
これらは、転舵角と地雷除去機の移動速度を決定するために使用されます。

適合スコアを測定するために使用する//地雷除去機
ダブルm_dFitnessを。

地雷除去機は鉱山を見つけるためにするたびに、その適応性のスコアが増加します。

地雷除去機は塗装//サイズ比
重m_dScaleを。

//地雷除去機、最寄りのインデックス位置鉱山は
m_iClosestMineをint型。

コントローラクラスCControl1erでは、STDのメンバーであるすべての鉱山のベクトル::ベクトルがあります。
m_iClosestMineは添字はそのベクトルにおける地雷地雷除去機の最も近い位置を表しています。

パブリック:

CMinesweeper();

//更新するために、人工ニューラルネットワークから得た情報を使用して地雷除去機環境
ブールアップデートを(ベクトル<SVector2D>&鉱山)。

それは、その後の外に引き出すことができるように//、各頂点地雷除去機を形質転換するために使用し
、空隙WorldTransform(ベクトル<SPOINT>&スイーパー)

//最も近い鉱山へのベクトルを返す
5Vector2D GetClosestMine(ベクトル<SVector2D>・オブジェクト)。

//地雷がことが判明しているかどうかを確認するために地雷除去機をチェック
CheckForMine int型(ベクトル<SVector2D>&鉱山、ダブルサイズ);

リセットを無効();

// -----------------定义各种供访问用的函数
SVector2D位置()constは{m_vPositionを返します。}
ボイドIncrementFitness(ダブルヴァル){m_dFitness + =ヴァル。}
ダブルフィットネス()constは{m_dFitnessを返します。}
ボイドPutWeights(ベクトル<ダブル>&W){m_ItsBrain.PutWeights(W)。}
GetNumberOfWeights()のconst int型
{戻りm_ItsBrain.GetNumberOfWeightsを(); }
}。


CMinesweeper ::更新機能4.7.1での

(地雷除去機の更新機能)

CMinesweeperクラスメソッドより詳細に更新更新機能だ一つだけを説明する必要があります。この関数は、フレームごとに呼び出された地雷除去機のニューラルネットワークを更新する必要があります。私たちはどのようないくつかのものでは胃のこの機能を調べてみましょう:

BOOL CMinesweeper ::更新(ベクトル<SVector2D>&鉱山)

{
//このベクトルは、すべてのニューラルネットワークの入力記憶するために使用される
ベクター<ダブル>の入力を、

地雷除去機との間の//ベクトルがこれに最も近い(二点)に鉱山から計算さ
SVector2D vClosestMine = GetClosestMine(鉱山)。

//ベクトルの正規化
Vec2DNormalize(vClosestMine)。

次いで、標準化させ第一鉱山、地雷除去機これに最も近いを算出する機能、の間のベクトル。しかし、視線ベクトル地雷除去機のラインは、(ルックでベクター)は1に等しい長さを有しているので、標準化する必要がない時間を(それは正規化ベクトルの長さが1に等しいで、思い出してください)。二つのベクトルは同じ大きさの範囲にそれを効果的になっているので、我々は、入力が、私は以前の話これは、標準化されていると考えることができます。

//追加地雷除去機- >最寄り鉱山間のベクトル
Inputs.push_back(vClosestMine.x);
Inputs.push_back(vCIosestMine.y)。

//追加地雷除去機の視線ベクトル
Inputs.push_back(m_vLookAt.x);
Inputs.push_back(m_vLookAt.y)。

//は、脳を更新し、ネットワークの出力から得ること
ベクトル<ダブル>出力= m_ItsBrain.Update(入力)。

次に、視線ベクトルと最も近い地雷除去機と鉱山間のベクトルは、ニューラルネットワークに入力されます。CNeuralNet :: Update関数は、地雷除去機ネットワークを更新するためにこの情報を使用し、出力ベクトルとしてのstd ::ベクトルを返します。

//エラーが出力の計算で発生しないよう
(output.size()<CParams :: iNumOutputs)IF
{
偽に戻ります。
}

左右の車輪のトラックに割り当てられた//出力地雷除去機
m_lTrack =出力[0];
m_rTrack出力= [1]。

ニューラルネットワークを更新すると、エラーが実際に検出されなかった場合、プログラムは出力m_lTrackとm_rTrackを割り当てます。これらの値は、左に適用される右ホイールトラックレール地雷除去機に力を表します。

//駆動力を計算
ダブルRotForce = m_lTrack - m_rTrackを。

//左または右用の
クランプ(RotForce、-CParams dMaxTurnRate ::、:: CParams dMaxTurnRate);

m_dSpeed =(+ m_lTrack m_rTrack);

回転力地雷除去機関車は左を使用、力が右輪トラックに適用されます算出した差。左側のトラックに加えられた力を減算して正しい軌道上の力は、車両の回転力を得る地雷除去機に適用することを規定しています。それは、最大回転速度指定回転練習INIファイルを超えないように、そして、これは、地雷除去に機関車の力を入れています。脱マイニング機関車の走行速度が、その左側車輪速レールとその右側車輪とレールの速度です。私たちは、パワーとスピードの地雷除去機の移転は、その場所と偏向角も更新することができることを知っているので。

//更新左右舵角地雷除去機
m_dRotation + = RotForce;

//更新視線角度
m_vLookAt.x = -sin(m_dRotation);
m_vLookAt.y = COS(m_dRotation)。

その位置更新//
m_vPosition + =(m_vLookAt * m_dSpeed)を 、

フォームの地雷除去機はそれを実装取り巻く、それは消えません周りに達した場合は//離れて形成
する場合(m_vPosition.x> :: CParams WindowWidth)m_vPosition.x = 0;
もし(m_vPosition.x <0) :: = WindowWidth m_vPosition.x CParams;
IF(m_vPosition.yを> :: CParams WindowHeight)m_vPosition.y = 0;
IF(m_vPosition.y <D)m_vPosition.y :: = CParams WindowHeight、

できるだけ簡単に物事を保つために、私は顔に地雷除去機は背面の(ラップ)ターンの周囲に境界線を形成させています。このように、プログラムは、もはや必要ないでしょう
仕事の応答側面-任意の衝突を行うこと。私たちのためにオープンスペースのスピンを囲む非常に信じられないほどのアクションですが、地雷除去機の、その
アヒルの池などがあります。

trueを返します。
}

4.8 CControllerクラス(コントローラクラス)


CControllerクラスはクラスであり、すべてがリンクされています。図15は、様々なクラスおよびその他CControllerクラスとの関係を示しています。
ここでは、クラスの定義は次のとおりです。

クラスCController
{
プライベート:
//動的メモリ(ベクトル)ゲノム人口
ベクトル<SGenome> m_vecThePopulation。



図15掃海艇エンジニアリングプログラムのフローチャート


//地雷除去機のベクトル保存
ベクトル<CMinesweeper> m_vecSweepersを;

//は鉱山ベクトル保存
ベクトル<SVector2D> m_vecMinesを。

//オブジェクト遺伝的アルゴリズムを指すようにポインタ
CGenAIg m_pGA *;

int型m_NumSweepers;

int型m_NumMines。

//ニューラルネットワークで使用される重み値の合計数
int型m_NumWeightsInNN。

//各地雷除去機械頂点バッファの形状記憶
ベクトルを<SPOINT> m_SweeperVB。

//ストア各頂点バッファ鉱山形状
ベクトル<SPOINT> m_MineVB。

描画するための世代あたり//ストア適応分数平均、
ベクトル<ダブル> m_vecAvFitness;

//適応の各世代の最高点格納
ベクター<ダブル> m_vecBestFitnessと、

我々が使用するブラシの//異なる種類
; HPEN m_RedPen
HPEN m_BluePen;
HPEN m_GreenPen;
HPEN m_OldPenを。

//アプリケーションウィンドウハンドル
HWND m_hwndMainを。

地雷除去機の走行速度切り替え//
BOOL m_bFastRenderを;

//すべての世代のフレーム(ティック)
m_iTicksをint型。

//世代数の
int型のm_iGenerations。

//フォームのクライアント領域のサイズ
int型cxClient、cyClient。

//この関数は動作に示されている平均有する-図、適応および最適値
ボイドPlotStats(HDC面)。

パブリック:

CController(HWND hwndMain)。

〜CController();

ボイド(HDC面)レンダリング。

空WorldTransform(ベクトル<SPOINT>&VBuffer、
SVector2D VPOS)。

ブール値を更新();

いくつかのアクセス方法//パブリック
BOOL FastRender(){m_bFastRender返す;}
ボイドFastRender(BOOLのArg)= {m_bFastRenderのArg;}
ボイドFastRenderToggle()= {m_bFastRender m_bFastRenderを;!}
}。

あなたは、インスタンスCControllerクラスを作成すると、起こる事柄の一連のがあるでしょう。

CMinesweeperオブジェクトを作成します。
ニューラルネットワークにおける統計的重みの合計重量が使用され、すなわち、この数は、クラスのインスタンスに遺伝的アルゴリズムを初期化するために利用されます。
(慎重に脳手術を使用して)、遺伝的アルゴリズム、ランダムに抽出されたオブジェクト(重量)の染色体とは、ネットワークを介して、地雷除去機に挿入されます。
地雷を大量に作成し、ランダムに周りに広がります。
関数を描いているGDIブラシを使用するすべての必要性を作成しました。
地雷除去機や形状鉱山の場合は頂点バッファを作成しました。

すべてが今、初期化を完了し、これを更新する方法は、各フレーム内の地雷除去機の進化に呼び出すことができます。


4.8.1 CController :: Updateメソッド(コントローラ更新方法)

コントローラ更新方法CController :: Updateメソッド(または関数)であることが各フレームで呼び出されます。更新関数を呼び出す場合、そのよう地雷除去機の発見など、すべての地雷除去機を、リサイクルすることで、前半の機能は、適応分数の地雷除去機の更新に地雷を発見しました。m_vecThePopulationはゲノムのすべてのコピーが含まれているため、関連する適応端数は、この時に調整する必要があります。世代(世代)の完成のためのフレーム数が経過しているために必要な場合は、この方法は、重量の新世代を生成するために、遺伝的アルゴリズムの時代を実行します。各パラメータの地雷除去機は新世代への参入の準備のために、リセットされるようにこれらの重みは、代わりに中央平原といくつかの古い重みの地雷除去機のニューラルネットワークの使用されています。

CController ::更新BOOL()
{
CParamsとして実行されている総//地雷除去機:: iNumTicksサイクル時間。このサイクルでは、ニューラルネットワークの地雷除去機は、
//情報を更新するために、その周りにユニークな環境を継続して使用します。希望地雷除去機を達成するように、ニューラルネットワークの出力から得られる
//操作。地雷地雷除去機会が会った場合、それはそれに応じて適応的に更新され、それが対応するのと同じ方法で更新されます
適応//ゲノム。
(m_iTicks ++ <CParams :: iNumTicks)IF
{
(;;私はm_NumSweepersを<I ++は私が= O INT)のために
、{
位置し、ニューラルネットワーク更新//
(!m_vecSweepers [I] .Update(m_vecMines))IFを
{
//処理とき、ニューラルネットワーク、エラー終了エラーが発生した後、
メッセージボックス(m_hwndMain、「NN入力の間違った量「、!
"エラー"、MB_OK);

falseを返します;
}

//マシンが地雷の地雷除去することが見出されたかどうかを確認してください
int型= GrabHit m_vecSweepers [I] .CheckForMine(m_vecMines、
CParams :: dMineScale)。

IF(GrabHit> = 0)
{
//鉱山に地雷除去機を有する見つけるので、その適応分数増加に
m_vecSweepersを[I] .IncrementFitness()。

//地雷を除去するに代わりに配置され鉱山の新しいランダムな位置で、地雷除去機を発見した
m_vecMines [GrabHit] = SVector2D(RandFloat()* cxClient、
RandFloat()* cyClient);
}

//更新適応値ゲノム
M-vecThePopulation [I] = .dFitness m_vecSweepers [I] .Fitness();
}
}

ます。https://my.oschina.net/dake/blog/196622で再現

おすすめ

転載: blog.csdn.net/weixin_34409703/article/details/91508124