7

複数の隠れ層を持つ NN に Nguyen-Widrow アルゴリズムを使用する予定です。調査中に多くのあいまいさを見つけたので、それらを明確にしたいと思います。

以下は、Nguyen-Widrow アルゴリズムの擬似コードです。

      Initialize all weight of hidden layers with random values
      For each hidden layer{
          beta = 0.7 * Math.pow(hiddenNeurons, 1.0 / number of inputs);
          For each synapse{
             For each weight{
              Adjust weight by dividing by norm of weight for neuron and * multiplying by beta value
            }
          } 
      }

hiddenNeurons の値が特定の隠れ層のサイズなのか、それともネットワーク内のすべての隠れ層のサイズなのかを明確にしたかっただけです。いろいろなソースを見て混乱しました。

つまり、ネットワーク (3-2-2-2-3) (インデックス 0 は入力レイヤー、インデックス 4 は出力レイヤー)がある場合、hiddenNeurons の値は次のようになります。

NumberOfNeuronsInLayer(1) + NumberOfNeuronsInLayer(2) + NumberOfNeuronsInLaer(3)

あるいは単に

NumberOfNeuronsInLayer(i) 、ここで i は現在のレイヤーです

編集:

では、hiddenNeurons の値は現在の隠れ層のサイズになり、入力値は前の隠れ層のサイズになりますか?

4

2 に答える 2

3

Nguyen-Widrow初期化アルゴリズムは次のとおりです。

  1. (範囲の) ランダム値で非表示レイヤーのすべての重みを初期化します
  2. 隠れ層ごと
    に 2.1 ベータ値 0.7 * N 番目 (入力層の #neurons) 現在の層の #neurons のルートを計算します
    2.2 各シナプス
    について 2.1.1 各重みについて
    2.1.2 ニューロンの重みのノルムで割って重みを調整し、ベータ値を掛ける

Encog Java フレームワーク

于 2012-12-09T01:46:37.060 に答える
2

より正確なコードが必要なように思えます。これが私が参加しているプロジェクトからの実際のコード行です。あなたがCを読んでくれることを願っています。それは少し抽象化されて単純化されています。struct nnニューラルネットデータを保持する、があります。あなたはおそらくあなた自身の抽象データ型を持っています。

私のプロジェクトのコード行(やや簡略化):

float *w = nn->the_weight_array;
float factor = 0.7f * powf( (float) nn->n_hidden, 1.0f / nn->n_input);

for( w in all weight )
    *w++ = random_range( -factor, factor );

/* Nguyen/Widrow */
w = nn->the_weight_array;
for( i = nn->n_input; i; i-- ){
    _scale_nguyen_widrow( factor, w, nn->n_hidden );
    w += nn->n_hidden;
}

呼び出される関数:

static void _scale_nguyen_widrow( float factor, float *vec, unsigned int size )
{
    unsigned int i;
    float magnitude = 0.0f;
    for ( i = 0; i < size; i++ )
        magnitude += vec[i] * vec[i];

    magnitude = sqrtf( magnitude );

    for ( i = 0; i < size; i++ )
         vec[i] *= factor / magnitude;
}

static inline float random_range( float min, float max)
{
    float range = fabs(max - min);
    return ((float)rand()/(float)RAND_MAX) * range + min;
}

ヒント:
Nguyen / Widrowの重みの初期化を実装した後、各アクティベーションをファイルにダンプするフォワード計算に実際に小さなコード行を追加できます。次に、ニューロンのセットが活性化関数にどれだけうまく当たるかを確認できます。平均と標準偏差を見つけます。プロットツールを使用してプロットすることもできます。gnuplot。(エラー率などをプロットするには、とにかくgnuplotのようなプロットツールが必要です。)実装のためにそれを行いました。プロットはうまくいき、私のプロジェクトにNguyen / Widrowを使用すると、最初の学習がはるかに速くなりました。

PS:NguyenとWidrowsの意図に従って、私の実装が正しいかどうかはわかりません。それが最初の学習を改善する限り、私は気にしないと思います。

頑張って、
-Øystein

于 2012-12-12T15:11:05.397 に答える