ニューラル・ネットワーク専門家からの質問 - ページ 21

 
alsu:

4) 重みの初期化パラメータ - 値の分布形式とその分散。

発見されました。重みの初期化パラメータを設定することが可能です。

デフォルト値を使用したようです。


 
LeoV:
人工ニューラルネットワークと遺伝的アルゴリズム 短期上級トレーニングコース
と遺伝的アルゴリズム"

短期上級研修「人工ニューラルネットワークと遺伝的アルゴリズム」の募集を締め切りました。
人工ニューラルネットワークと遺伝的アルゴリズム」。
M.V.ロモノーソフ・モスクワ国立大学生涯教育学部が実施。
V.V. ロモノーソフ・モスクワ国立大学 原子力研究所に基づく
モスクワ国立大学コース修了者には、州の上級専門教育修了証が授与されます。
ステート・サーティフィケイト・オブ・アドバンスト・トレーニング。
週2回、夜19:00からトレーニングが行われる予定です。
授業は2011年2月25日から開始します。

コースプログラムについて詳しく知りたい方は、詳細情報を入手し
お申し込みはこちらからお願いします。
http://www.neuroproject.ru/kpk.php
申し訳ありませんが、これは広告でしょうか、それともご自身で受講されるのでしょうか?
 
lasso:

発見されました。スケールの初期化パラメータを設定することが可能です。

私はデフォルト値を使用していたようです。


さて、ここで何が問題なのかが明らかになったようだ。

あなたの問題(1次元のデータを2つのクラスに分けたいということですね)から出発して、ポイントは、指定した分割を最適に実行する、入力値の集合上の点(1つだけ!)を見つけることです。1-7-1のネットワークがあるとします。このネットワークは21個の重みを持つ(隠れ層への7個の入力、それに対する7個のオフセット、出力ニューロンへの7個の入力)。21個の変数を拾って、1点を見つけようとしていることがわかります。このように21対1の冗長性があれば、ネットワークの読みが大きく変化しても不思議はない。初期の重みが少しでも違えば、学習後の出力は大きくばらつくことになる。大雑把に言うと、ネットワークにとっては単純すぎるタスクであることが分かるのですが、ネットワークはそれを知らないので、存在しないものを探してしまうのです。技術的には再教育と言えるかもしれませんが、要するにスズメに大砲を撃っているようなものです。

厳密に言えば、1次元のデータを2つのクラスに分割する作業は、1つの入力重みと1つのバイアスを持つ1つのニューロンでうまく実行される。

 
lasso:

もうひとつ。現在のネットワーク出力の範囲の「狭さ」に警鐘を鳴らしているのです。明確にすること。

-- MLPネットワークは1-7-1

-- ネットワークの出力は[0;1]の範囲に均等に分布しており、学習例での出力は1と-1で表される。

学習後、入力値の全範囲をネットワークに通すと、ネットワークの出力は非常に狭い範囲にあることがわかる。例えば、こんな感じです。

opt_max_act=-0.50401336 opt_min_act=-0.50973881 step=0.0000286272901034

其の癖

opt_max_real=-0.99997914 opt_min_real=-0.99999908 step=0.00000010

これは正しいのか、そうでないのか?


正しさについては何とも言えませんが...。じょうきょうによる

あなたの例によると

この場合、すべての入力に対して最初のネットワークは「わからない」と言い、同じ入力に対して2番目のネットワークは「クラス-1」と言うことになる。データが同じで、重みの初期化だけが違う場合、クラスの混在が強く、グリッドが学習パターンを理解できず、結果的に「ランダムに」動作していることがほとんどです。このようなことが起こり得るかについてですが、ネットワークが(おそらくそうですが)偏ったニューロンを使っている場合、グリッドは単にすべての情報入力の重みをゼロにして、偏りだけを残して分析するのだと思います。もちろん、この「分析」は名目上のもので、ネットワークはダチョウの原理に従って動作しているため、単に入力を見ていないだけである。これを確認するためには、学習したネットワークの 行列を見る必要があります。

 

以下は、「統計」で生成されたMLP NSコードです。

/* ------------------------------------------------------------------------- */


#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>

#ifndef FALSE
#define FALSE 0
#define TRUE 1
#endif

#define MENUCODE -999


static double NNCode38Thresholds[] =
{

/* layer 1 */
-0.78576109762088242, -0.23216582173469763, -1.6708808507320108, -1.525614113040888,
1.4153558659332133, -0.77276960668316319, 2.3600992937381298, 2.473963708568014,
-0.43422405325901231, 0.68546943611132893, 0.19836417975077064, 0.26461366779934564,
-0.19131682804149783, 0.24687125804149584, -0.95588612620053504, 0.25329560565058901,
-1.0054817062488075, 1.3224622867600988, 0.88115523574528376, 0.32309684489223067,
0.52538428519764313,

/* layer 2 */
-1.8292886608617505

};

static double NNCode38Weights[] =
{

/* layer 1 */
1.8660729426318707,
1.3727568288578245,
3.1175074758006374,
3.356836518157698,
3.2574311486418068,
3.2774957848884769,
1.4284147042568165,
3.534875314491805,
2.4874577673065557,
2.1516346524000403,
1.9692127720516106,
4.3440737376517129,
2.7850179803408932,
-12.654434243399631,
2.4850018642785399,
2.1683631515554227,
1.77850226182071,
2.1342779960924272,
2.8753050022428206,
3.9464397902669828,
2.5227540467556553,

/* layer 2 */
-0.041641949353302246, -0.099151657230575702, 0.19915689162090328, -0.48586373846026099,
-0.091916813099494746, -0.16863091580772138, -0.11592356639654273, -0.55874391921850786,
0.12335845466035589, -0.022300206392803789, -0.083342117374385544, 1.550222748978116,
0.10305706982775611, 3.9280003726494575, 0.12771097131123971, -0.12144621860368633,
-0.40427171889553365, -0.072652508364580259, 0.20641498115269669, 0.1519896468808962,
0.69632055946019444

};

static double NNCode38Acts[46];

/* ---------------------------------------------------------- */
/*
  NNCode38Run - run neural network NNCode38

  Input and Output variables.
  Variable names are listed below in order, together with each
  variable's offset in the data set at the time code was
  generated (if the variable is then available).
  For nominal variables, the numeric code - class name
  conversion is shown indented below the variable name.
  To provide nominal inputs, use the corresponding numeric code.
  Input variables (Offset):
  stoch

  Выход:
  res
    1=1
    2=-1

*/
/* ---------------------------------------------------------- */

void NNCode38Run( double inputs[], double outputs[], int outputType )
{
  int i, j, k, u;
  double *w = NNCode38Weights, *t = NNCode38Thresholds;

  /* Process inputs - apply pre-processing to each input in turn,
   * storing results in the neuron activations array.
   */

  /* Input 0: standard numeric pre-processing: linear shift and scale. */
  if ( inputs[0] == -9999 )
    NNCode38Acts[0] = 0.48882189239332069;
  else
    NNCode38Acts[0] = inputs[0] * 1.0204081632653061 + 0;

  /*
   * Process layer 1.
   */

  /* For each unit in turn */
  for ( u=0; u < 21; ++u )
  {
    /*
     * First, calculate post-synaptic potentials, storing
     * these in the NNCode38Acts array.
     */

    /* Initialise hidden unit activation to zero */
    NNCode38Acts[1+u] = 0.0;

    /* Accumulate weighted sum from inputs */
    for ( i=0; i < 1; ++i )
      NNCode38Acts[1+u] += *w++ * NNCode38Acts[0+i];

    /* Subtract threshold */
    NNCode38Acts[1+u] -= *t++;

    /* Now apply the logistic activation function, 1 / ( 1 + e^-x ).
     * Deal with overflow and underflow
     */
    if ( NNCode38Acts[1+u] > 100.0 )
       NNCode38Acts[1+u] = 1.0;
    else if ( NNCode38Acts[1+u] < -100.0 )
      NNCode38Acts[1+u] = 0.0;
    else
      NNCode38Acts[1+u] = 1.0 / ( 1.0 + exp( - NNCode38Acts[1+u] ) );
  }

  /*
   * Process layer 2.
   */

  /* For each unit in turn */
  for ( u=0; u < 1; ++u )
  {
    /*
     * First, calculate post-synaptic potentials, storing
     * these in the NNCode38Acts array.
     */

    /* Initialise hidden unit activation to zero */
    NNCode38Acts[22+u] = 0.0;

    /* Accumulate weighted sum from inputs */
    for ( i=0; i < 21; ++i )
      NNCode38Acts[22+u] += *w++ * NNCode38Acts[1+i];

    /* Subtract threshold */
    NNCode38Acts[22+u] -= *t++;

    /* Now calculate negative exponential of PSP
     */
    if ( NNCode38Acts[22+u] > 100.0 )
       NNCode38Acts[22+u] = 0.0;
    else
      NNCode38Acts[22+u] = exp( -NNCode38Acts[22+u] );
  }

  /* Type of output required - selected by outputType parameter */
  switch ( outputType )
  {
    /* The usual type is to generate the output variables */
    case 0:


      /* Post-process output 0, two-state nominal output */
      if ( NNCode38Acts[22] >= 0.05449452669633785 )
        outputs[0] = 2.0;
      else
        outputs[0] = 1.0;
      break;

    /* type 1 is activation of output neurons */
    case 1:
      for ( i=0; i < 1; ++i )
        outputs[i] = NNCode38Acts[22+i];
      break;

    /* type 2 is codebook vector of winning node (lowest actn) 1st hidden layer */
    case 2:
      {
        int winner=0;
        for ( i=1; i < 21; ++i )
          if ( NNCode38Acts[1+i] < NNCode38Acts[1+winner] )
            winner=i;

        for ( i=0; i < 1; ++i )
          outputs[i] = NNCode38Weights[1*winner+i];
      }
      break;

    /* type 3 indicates winning node (lowest actn) in 1st hidden layer */
    case 3:
      {
        int winner=0;
        for ( i=1; i < 21; ++i )
          if ( NNCode38Acts[1+i] < NNCode38Acts[1+winner] )
            winner=i;

        outputs[0] = winner;
      }
      break;
  }
}
 
alsu:

正しさについては何とも言えませんが...。は、状況によって異なります。

あなたの例によると

この場合、すべての入力に対して1つ目のネットは「わからない」と言い、同じ入力に対して2つ目のネットは「クラス-1」と言うことになる。データが同じで、重みの初期化だけが違う場合、クラスの混在が強く、グリッドが学習パターンを理解できず、結果的に「ランダムに」動作してしまうことがほとんどです。このようなことが起こり得るかについてですが、ネットワーク(おそらくそうでしょう)が偏ったニューロンを使っている場合、グリッドは単にすべての情報入力の重みをゼロにし、偏りだけを残して分析するのだと思います。もちろん、この「分析」は名目上のもので、ネットワークはダチョウの原理に従って動作しているため、単に入力を見ていないだけである。これを確認するためには、学習したネットワークの行列を見る必要があります。

もうひとつ、FANNは受信レイヤーを除くすべてのレイヤーでバイアスシフトを適用しています。

しかし、Statistics 6のNNパッケージの説明には、バイアスに類するものは見つかりませんでした。

NSの初心者にとっては、これらのバイアスは本当に頭の痛い問題です...。

 

そう、私が言ったことと非常によく似ている、ただ逆なだけだ。ネットワークはデータの中に紛れ込んでしまうだけ。注:ネットワークの構造から、第1層のすべての重みは入力データに対して等しく、理論的にはゼロの周りに均等に分布しているはずです。しかし、図にあるように、それらは上に押し上げられ、隠れ層のニューロンは飽和状態になりました(あなたはロジスティック 活性化関数を使用しています)。出力ニューロンも同様で、予想通り、最初のニューロンの言うことを何も理解しませんでした。しかし、このニューロンに何が起こったかは、すでに解明されているのです。


 

素晴らしい!!!

重みと閾値の値を図式化したものです。

そして、まったく異なる視点。ありがとうございます。

 
lasso:

以下は、「統計」で生成されたMLP NSのコードです。

こんにちは。

Statisticaで生成したニューラルネットワークをCファイルからdllファイルにコンパイルする方法を、プログラマーの 手を借りて習得することは可能なのか、端的に提案していただけないでしょうか。一度手順を説明してもらって、その後スキームにしたがって自分でできるようにするという意味です。ただ、学校でBasicでプログラミングするレベル、NSモデルでForehと連携するのですが、定期的にネットワークを更新する必要があり、新しいDLLを読み込んで生成しています。MQLのコードでは、いちいち修正するのはちょっと面倒です。

 
alexeymosc:

こんにちは。

Statisticaで生成したニューラルネットワークをCファイルからdllファイルにコンパイルする方法をプログラマに教えてもらうことは可能でしょうか?

おやすみなさい!

例外は、そのプログラマーがStatistica自体で働いていない場合のみです ))

アレクセイモスク

MQLのコードでは、いちいち修正するのはちょっと面倒です。

統計学ではどのようなNSを使っているのですか?

手動で修正するということは、アルゴリズムがあるということなので、自動化する必要があるのですが...。

上記でGAを使うことを勧められましたが、ちょうど今日、joo ライブラリ(UGALib)の助けを借りて、望ましい安定した結果を得ることができました。

では、このケースをドラッグ&ドロップで4...

アンドレイ(作者)に深く感謝します。非常に期待できる、柔軟な方向性です。

もしかしたら、この方向で掘っていく価値があるかもしれませんね。