我计划将Nguyen-Widrow算法用于具有多个隐藏层的NN。在研究过程中,我发现了很多歧义,我想澄清一下。

以下是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)

要不就



编辑:

因此,hiddenNeurons值将是当前隐藏层的大小,而输入值将是前一个隐藏层的大小?

最佳答案

在我看来,您想要更精确的代码。这是我参与的项目中的一些实际代码行。希望您读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的意图,我不确定我的实现是否正确。我什至不认为我在乎,只要它能改善初学者。

祝好运,
Østein

08-19 23:45