-7

ニューラル ネットワーク アプリケーションを開発していますが、フィードフォワードの出力を印刷しようとすると問題が発生します。コンソールには次の値が表示されます。

出力は常に1 1 1 1 1

2500 個の入力ノード、1800 個の非表示ノード、および 5 個の出力ノードで構成される 3 つのレイヤーを使用しています。アクティベーション関数としてシグモイド バイナリを使用しています。テストの重みは 0.5 に固定されています。

非常に単純なアーキテクチャ (2 つの入力、3 つの非表示、1 つの出力) を使用しようとすると、完全に機能しますが、現在、非常に多くのノードで出力を手動で計算できないため、結果が正しいか間違っているか。

私のコードは間違っていますか、それとも固定の重みを与えることはできませんか? バックプロパゲーションではなく、フィードフォワードを 1 つだけ実行したいのですが、入力は 0 から 1 までランダムです。

これは network.cpp です:

#include <stdio.h>
#include <iostream>
#include "network.h"
#include "neuron.h"

using namespace std;

layer::layer(int numberOfNeuron,int numberOfInput,int numberOfOutput):
neuron_layer(numberOfNeuron)
{
    for(int i=0;i<numberOfNeuron;i++)
    {
        neuron_layer[i] = new neuron(numberOfInput,numberOfOutput);
    }
}
layer::~layer()
{

}

int layer::get_number_of_neuron()
{
    return neuron_layer.size();
}

network::network(int layerNumber,int hiddenNeuronNumber):
    layer_network(layerNumber)
{
    this->layer_numbers = layerNumber;
    for(int i=0;i<layerNumber;i++)
    {
        if(i==0)
        {
            layer_network[i] = new layer(2500,5,hiddenNeuronNumber);
        }
        else if(i==1)
        {
            layer_network[i] = new layer(hiddenNeuronNumber,2500,5);
        }
        else if(i==2)
        {
            layer_network[i] = new layer(5,hiddenNeuronNumber,1);
        }
    }
    cout<<endl<<"Input layer : "<<layer_network[0]->get_number_of_neuron()<<endl;
    cout<<"Hidden layer : "<<layer_network[1]->get_number_of_neuron()<<endl;
    cout<<"Output layer : "<<layer_network[2]->get_number_of_neuron()<<endl;
}

network::~network()
{
}

void network::init_input_layer(int inputNeuronNumber,int hiddenNeuronNumber)
{
    for(int i=0;i<inputNeuronNumber;i++)
    {
        for(int j=0;j<hiddenNeuronNumber;j++)
        {
            layer_network[0]->neuron_layer[i]->outputs[j]->weights = 0.5f;
        }
    }
}

void network::init_hidden_layer(int inputNeuronNumber,int hiddenNeuronNumber,int outputNeuronNumber)
{
    for(int i=0;i<hiddenNeuronNumber;i++)
    {
        for(int j=0;j<inputNeuronNumber;j++)
        {
            layer_network[1]->neuron_layer[i]->inputs[j]->weights = layer_network[0]->neuron_layer[j]->outputs[i]->weights;
        }
    }
    for(int k=0;k<hiddenNeuronNumber;k++)
    {
        for(int l=0;l<outputNeuronNumber;l++)
        {
            layer_network[1]->neuron_layer[k]->outputs[l]->weights = 0.5f;
        }
    }
}

void network::init_ouput_layer(int hiddenNeuronNumber,int outputNeuronNumber)
{
    for(int i=0;i<outputNeuronNumber;i++)
    {
        for(int j=0;j<hiddenNeuronNumber;j++)
        {
            layer_network[2]->neuron_layer[i]->inputs[j]->weights = layer_network[1]->neuron_layer[j]->inputs[i]->weights;
        }
    }
}

これは neuron.cpp です:

#include "neuron.h"
#include <stdio.h>
#include <iostream>

using namespace std;

synapse::synapse()
{

}
synapse::~synapse()
{
}

neuron::neuron(int numberOfInput,int numberOfOutput):
inputs(numberOfInput),outputs(numberOfOutput)
{
    for(int i=0;i<numberOfInput;i++)
    {
        inputs[i] = new synapse();
    }
    for(int i=0;i<numberOfOutput;i++)
    {
        outputs[i] = new synapse();
    }
}
neuron::~neuron()
{
}

int neuron::get_input_size()
{
    int input_length;
    input_length=(int) inputs.size();
    return input_length;
}

int neuron::get_output_size()
{
    int output_length;
    output_length=(int) outputs.size();
    return output_length;
}


void neuron::input_fire()
{
    output_value = inputs[0]->activation_values;
    for(int i=0;i<get_output_size();i++)
    {
        outputs[i]->activation_values = output_value;
    }
}

void neuron::fire()
{
    output_value = 0.0f;
    for(int i=0;i<get_input_size();i++)
    {
        output_value+=(inputs[i]->activation_values)*(inputs[i]->weights);
    }
    //cout<<endl<<"Before Sigmoid"<<output_value;
    output_value = 1.0f / (1.0f+ exp(-output_value));
    //cout<<" After Sigmoid"<<output_value;
    for(int i=0;i<get_output_size();i++)
    {
        outputs[i]->activation_values = output_value;
    }

}

neuron.h と network.h はどちらも宣言のみで構成されているため、投稿する必要はないと思います。.cpp で関数を定義します。これは私がオブジェクトを作成した方法です:

srand (time(NULL));
float inputTest[2500];
network test(3,1800);
test.init_network(1800);
for(int i=0;i<2500;i++)
{
    inputTest[i]=(float)rand()/(float)RAND_MAX;
}
test.feedforward(inputTest);
4

1 に答える 1

3

私はあなたのコードをチェックしませんでしたが... いいえ、そのような固定重量は使用できません。入力の量を増やすと、隠れ層の各ノードの値が大きくなります。Sigmoid は大きな値を 1 にスケーリングします。

考えてみてください: それぞれ「ランダムな」入力値 0.1 を持つ 100 個の入力があるとします。簡単にするために、他のすべてを忘れてしまいましょう。重みは定数 0.5 であるため、隠れ層のすべてのノードは、各入力 * 重みの「シグモイド」合計で構成される同じ値を取得します。つまり、sigm(0.1*0.5*100) = sigm(5) -> ~ 1

したがって、一定の正の重みを持つ正の入力が多いほど、すべての隠れ層の出力が 1 に近づきます。

于 2012-11-21T13:30:42.047 に答える