4.4 CNeuralNet.h
(ニューラルネットワーククラスヘッダファイル)
CNeuralNet.hファイルでは、我々は人工的な神経細胞の構造を定義し、人工ニューロンと人工ニューラルネットワーク自体の構造層の構造を定義します。私たちは最初の人工神経細胞の構造を調べてみましょう。
4.4.1 SNeuron(神経細胞の構造)
これは非常にシンプルな構造です。人工神経細胞の構造は、多くがそれを入力してくださいどのように記録するために、正の整数でなければなりません、あなたはまだ、ベクトルSTDを必要とする:ベクターは、その重さを表現するために。覚えておいて、各入力ニューロンが対応する重みを持っている必要があります。
Struct SNeuron
{
// 进入神经细胞的输入个数
int m_NumInputs;
// 为每一输入提供的权重
vector;double; m_vecWeight;
//构造函数
SNeuron(int NumInputs);
};
次はSNeuron構造形式コンストラクタです。
SNeuron::SNeuron(int NumInputs): m_NumInputs(NumInputs+1)
{
// 我们要为偏移值也附加一个权重,因此输入数目上要 +1
for (int i=0; i<NumInputs+1; ++i)
{
// 把权重初始化为任意的值
m_vecWeight.push_back(RandomClamped());
}
}
これは、入力ニューロンの数のコンストラクタ引数としてNumInputsを供給し、各入力のためのランダム重みを作成し、上から見ることができます。-1と1の間の重み値。
。。「 何?」私はあなたが言うのを聞きます。「これは重量のある!」はい、これは追加の重量であるので、私は、これに気づくためにお会いできてうれしい非常に重要です。それがあったしかし、なぜ、私はいくつかのより多くの数学の知識を導入する必要があることを説明します。あなたは、すべての刺激値覚えることができることを思い出して重量*重い入力を積の和の、および神経細胞の興奮の出力値は、値がある閾値(t)を超えているかどうかに依存します。これは、次の式で表すことができます。
w1x1 + w2x2 + w3x3 + ... + wnxn> = T
式は、条件のセル出力1です。ネットワークの重みの所有権は、一定の進化(進化)を必要とするため、閾値データも一緒に進化することができた場合、それは非常に重要であろう。これは難しいことではありません行うには、重みしきい値が形になり作ることができる簡単なトリックを使用しています。各Tを減算することによって、上記式の両側から、取得します。
w1x1 + w2x2 + w3x3 + ... + wnxn -t> = 0
この式は形式で書かれており、背中、以下にすることができます。
w1x1 + w2x2 + w3x3 + ... + wnxn + T *( - 1)> = 0
これは、私はあなたが閾値tは常に正しい-1ヘビーのための入力を掛けたことを想像することができる理由を見ることができたと思っています。この特定の量は、通常、各ニューロンは、初期化のために右の理由の量を増加しなければならない理由である、(バイアス)オフセットと呼ばれています。さて、ときにネットワークの進化、あなたはそれが重みベクトルで構築されているため、しきい値問題を検討する必要はありません。どのように、良いアイデア、右?あなたの心は絶対新しい人工ニューロンを確定するためには、図12で再度参照してください、のようにそれが何であったかを学びました。
図帯における人工神経細胞12がオフセット。
4.4.2 SNeuronLayer(神経細胞層)
、非常に単純な神経細胞層SNeuronLayerの構造は、その神経細胞SNeuronを囲む点線13で示すような層を規定します。
図13は、点線ボックス神経細胞層であります
以下は、ソースコードレベルの定義ですが、それはそれ以上の説明は必要はありません。
SNeuronLayer構造体
{
//使用して、現在の層の神経細胞の数
のint m_NumNeuronsを;
//層ニューロン
ベクトル<SNeuron> m_vecNeurons;
SNeuronLayer(NumNeurons INT、INT NumInputsPerNeuron);
};
4.4.3 CNeuralNet(ニューラルネットワークベース)
これは、ニューラルネットワークのオブジェクトクラスを作成することです。のは、どのようなこのクラスの定義を読んでみましょう:
クラスCNeuralNet
{
プライベート:
m_NumInputs int型。
int型m_NumOutputs;
int型m_NumHiddenLayers;
int型m_NeuronsPerHiddenLyr;
//ストア各層の全てのニューロンのメモリ(A含む出力層)
ベクトルを<SNeuronLayer> m_vecLayers。
すべての民間メンバーは、簡単にその名が理解します。本数のクラス定義によって必要とされると、入力および出力の数、いくつかのパラメータの隠れ層の数、及び隠れ層内の他のニューロンのそれぞれの数です。
パブリック:
CNeuralNet();
プライベートメンバ変数の全てを初期化し、ネットワークを作成するためにCreateNetを呼び出すために、コンストラクタを使用してiniファイル。
// SNeuronsネットワーク作成
)(ボイドCreateNetを。
私はすぐにこの関数のコードを、次のことを教えてくれます。
//ニューラルネットワークの重みから(読み出し)を得る
ベクター<ダブル> GetWeights()constは 、
ネットワークの重みが進化を必要として、すべての重みを返すメソッドを作成する必要があります。これらの重みは、ベクトル形式で表され、実際のネットワークの種類に基づいており、我々はゲノムに再エンコードの実数を右ます。私は、遺伝的アルゴリズムに、このプロジェクトの話を始めたとき、私はあなたの体重をエンコードする方法についての正確な指示を与えます。
//は、重いネットワークの重みの合計数を返す
GetNumberOfWeights()のconst int型。
//新しい代わりに、元の重みの重みを持つ
空PutWeights(ベクトル<ダブル>&
ウエイト); この関数は正反対行われる作業や機能GetWeightsを行います。遺伝的アルゴリズムの生成を実行する場合、重量の新世代は、ニューラルネットワークに再挿入されなければなりません。私たちのためにこのタスクは、PutWeight方法です。
// S字応答曲線
インラインダブルシグモイド(二重活性化、二重応答)、
知られているすべての入力ニューロンの生成物の重量*このメソッドは、それがS字状活性化関数に供給されます。
出力計算するための入力//一組
のベクトルを<ダブル>更新(ベクトル<ダブル>&入力)。
機能私はすぐにアノテーションが付けられます。この機能を更新します。
}; //エンドクラスの定義
4.4.3.1 CNeuralNet :: CreateNet(ニューラルネットワークを作成する方法)
私は彼らにあなたのためのより完全なコードを表示しようとするので、私は、前の二つの方法CNeuralNetでそれらについてはコメントしないでください。これらの2つの方法の第一は、ネットワークCreateNetを作成する方法です。:それは一緒にSNeuronLayersニューロンのSNeurons全体ニューラルネットワーク、コードを構成するために収集された細胞層の仕事である
ボイドCNeuralNet :: CreateNet()
{
//個々の層のネットワークを作成
IF(m_NumHiddenLayers> 0)
{
/ /第一隠れ層[注釈]作成
m_vecLayers.push_back(SNeuronLayer(m_NeuronsPerHiddenLyr、
m_NumInputsを));
のために(INT I = O; Iはm_NumHiddenLayers-Lを<; Iは++)
{
m_vecLayers.push_back(SNeuronLayer(m_NeuronsPerHiddenLyr、
m_NeuronsPerHiddenLyr) );
}
//出力層の作成
、m_vecLayers.push_back(SNeuronLayer(m_NumOutput、m_NeuronsPerHiddenLyrを))
}
他//隠れ層、出力層は、単に作成しない
{
//作成し、出力層
m_vecLayers.push_back(SNeuronLayer(m_NumOutputs、m_NumInputs));
}
}
CNeuralNet ::アップデート4.4.3.2(ニューラルネットワークの更新方法)
更新機能(更新機能)は、ニューラルネットワークのメインワークショップとみなされます。ここでは、ネットワークのデータ入力は、倍精度ベクトル入力のstd ::ベクトルデータ形式で渡されます。処理するために各レイヤを介して機能サイクルを更新する入力*重い重量を、我々は以前に、最後の数に述べたように和を乗じ、インセンティブとして、次いで、得られた合計値、各ニューロンは、S字状の出力の関数によって計算されますページで説明したように。更新機能は、人工ニューラルネットワークの出力の全てに対応している倍精度ベクトルのstd ::ベクトルを返します。
。。あなたは正しく、我々が話をし続ける他のことを理解することができます以下のコード更新機能、を理解するために、独自の2分以内に同じ時間がかかるしてください:
ベクター<ダブル> :: CNeuralNet更新(ベクトル<ダブル>入力&)
{
//得られた各レイヤからの出力を保存する
ベクトル<ダブル>出力を、
int型cWeight = 0;
//最初の入力された番号が正しいかチェック
IF(inputs.size()= m_NumInputs!)
{
//そうでない場合、それはヌルベクトル返す
リターン出力を;
}
//レイヤ毎に、...
(INTため0 = Iは、Iが<m_NumHiddenLayersを+ 1、。私は++)
{
IF(I> O)
{
入力出力=;
}
outputs.clear();
cWeight = 0;
//各ニューロンのための、重みを対応する入力を求めます*製品の合計。そして出力計算するS字形スロー関数の和
のために(INT J = 0; J <m_vecLayers [I] .m_NumNeurons; J ++)
{
ダブルnetinput = 0;
INT = NumInputs m_vecLayers [I] .m_vecNeurons [J]を.m_NumInputs;
//各重みのため
のための(int型K = O; ++ K; K <NumInputs-L)は
{
和* //製品の入力の重みを計算します。
netinput + = m_vecLayers [i]は.m_vecNeurons [J] .m_vecWeight [K] *
入力[cWeight ++];
}
//オフセット追加
netinput m_vecLayers = + [I] .m_vecNeurons [J] .m_vecWeight [。-NumInputs 1] *
CParams :: DBIASを。
各神経細胞の重みベクトルの重みのための最後の右の重量は実際に私たちは、すでに説明した値を、オフセットされ、我々は常にそれがなる設定-1を忘れないでください。私はiniファイル内のオフセット値が含まれている、あなたがどんな効果を持って作成し、それを中心に上下記事を行い、そのネットワーク機能を調べることができます。ただし、この値は、通常は変更しないでくださいされています。
//出力各層、我々はそれらを持っていたとき、私たちはそれらを保存する必要があります。しかし、一緒に加算Σを代入
出力得るために濾過による最初のS字関数の//全励起、
outputs.push_back(シグモイド(netinput、CParams :: dActivationResponseを)); = 0 cWeight:
}
}
出力を返します。
}
----------------
[注釈]以上の隠れ層は隠れ層の残りの部分を作成することができるためのループが続く、許可されている場合。
ます。https://my.oschina.net/dake/blog/196825で再現