2012-11-21 18 views
-5

我正在開發一個神經網絡的應用程序,但我有,當我試圖打印前饋的輸出問題:控制檯顯示該值:神經網絡的輸出始終爲1

輸出總是1 1 1 1 1

我使用3層由2500個輸入節點,1800個隱藏節點和5個輸出節點組成。 我使用sigmoid二進制作爲激活函數,測試的權重固定爲0.5。

當我試圖使用一個非常簡單的架構(2輸入,3隱藏,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); 
+0

你的日誌讀取'輸出 - >隱藏1 1 1 1 1' - 沒有按這是否意味着輸出權重都是1-s?嘗試更小的結構(從你提到的2-3-1開始),並查看網絡是否飽和。還要考慮使用一些衆所周知且經過驗證的實現。 – Stan

+0

輸出 - >隱藏1 1 1 1 1意味着隱藏層的所有輸出都是1,我想這也許是我出錯的地方。我試圖創建一個更小的結構,它運行良好我用手動計算檢查了結果 –

回答

3

我沒有檢查你的代碼,但... 不,你不能用固定重量這樣。隨着您增加輸入量,隱藏層中的每個節點都會變得越來越大。 Sigmoid會將較大的值縮放到1.

想一想: 假設您有100個輸入,每個輸入的「隨機」輸入值均爲0.1。爲了簡單起見,讓我們忘記一切。由於你的權重恆定爲0.5,所以隱藏層中的所有節點將得到一個相同的值,它由每個輸入*權重的「sigmoided」和組成,即sigm(0.1 * 0.5 * 100)= sigm(5) - >〜 1

所以,你越是有一定的正權重積極投入越靠近所有隱藏圖層的輸出將成爲1

+0

啊好吧,我明白了!謝謝你的解釋! –