2016-11-04 35 views
-2

我想實現一個神經網絡到c + +,但我必須表明它是很多未知的錯誤。我已經搜索並找到其他帖子,如(C++ class has no member named),但是這對我沒有幫助。可以請幫我弄清楚如何解決我收到的所有錯誤。 下面的代碼試圖創建一個神經網絡在c + +

#include <iostream> 
#include <vector> 
#include <cstdlib> 
#include <assert.h> 
#include <math.h> 

using namespace std; 

struct Connection 
{ 
    double weight; 
    double deltaWeight; 
}; 

class Neuron {}; 

typedef vector<Neuron> Layer; 

// ************************* class Neuron ************************* 

class Neuron 

{ 
public: 
    Neuron(unsigned numOutputs, unsigned myIndex); 
    void setOutputVal(double val) 
    { 
     m_outputVal = val; 
    }; 
    double getOutputVal(void) const 
    { 
     return m_outputVal; 
    }; 
    void feedForward(const Layer &prevLayer); 
    void calcOutputGradients(double targetVal); 
    void calcHiddenGradients(const Layer &nextLayer); 
    void updateInputWeights(Layer &prevLayer); 

private: 
    static double eta;  // [0.0..1.0] overall net training rate 
    static double alpha;  // [0.0..n] multiplier of last weight change (momentum) 
    static double transferFunction(double x); 
    static double transferFunctionDerivative(double x); 
    static double randomWeight(void) 
    { 
     return rand()/double(RAND_MAX); 
    }; 
    double sumDOW(const Layer &nextLayer) const; 
    double m_outputVal; 
    vector<Connection> m_outputWeights; 
    unsigned m_myIndex; 
    double m_gradient; 
}; 

double Neuron::eta = 0.15; // overall net learning rate, [0.0..1.0] 
double Neuron::alpha = 0.5; // momentum, multiplier of last deltaWeight [0.0..n] 

void Neuron::updateInputWeights(Layer &prevLayer) 
{ 
    // The weight are updated in the Connection container 
    // in the neurons in the preceding layer 

    for (unsigned n = 0; n < prevLayer.size(); ++n) 
    { 
     Neuron &neuron = prevLayer[n]; 
     double oldDeltaWeight = neuron.m_outputWeights[m_myIndex].deltaWeight; 

     double newDeltaWeight = 
      eta 
      * neuron_getOutputVal() 
      * m_gradient 
      + alpha 
      * oldDeltaWeight; 
     neuron.m_outputWeights[m_myIndex].deltaWeight = newDeltaWeight; 
     neuron.m_outputWeights[m_myIndex].weight += newDeltaWeight; 
    } 
} 

double Neuron::sumDOW(const Layer &nextLayer) const 
{ 
    double sum = 0.0; 

    // Sum our contributions of the errors at the nodes we feed 

    for (unsigned n = 0; nextLayer.size() - 1; ++n) 
    { 
     sum += m_outputWeights[n].weight * nextLayer[n].m_gradient; 

    } 
    return sum; 
} 

void Neuron::calcHiddenGradients(const Layer &nextLayer) 
{ 
    double dow = sumDOW(nextLayer); 
    m_gradient = dow * Neuron::transferFunctionDerivative(m_outputVal); 
} 

void Neuron::calcOutputGradients(double targetVal) 
{ 
    double delta = targetVal - m_outputVal; 
    m_gradient = delta * Neuron::transferFunctionDerivative(m_outputVal); 
} 

double Neuron::transferFunction(double x) 
{ 
    // tanh - output range [-1.0..1.0] 
    return tanh(x); 
} 

double Neuron::transferFunctionDerivative(double x) 
{ 
    // tanh derivative 
    return 1.0 - x * x; 
} 

void Neuron::feedForward(const Layer &prevLayer) 
{ 
    double sum = 0.0; 

    // Sum the previous layer's outputs (which are our inputs) 
    // Include the bias node from the previous layer 

    for (unsigned n = 0; n < prevLayer.size(); ++n) 
    { 
     sum += prevLayer[n].getOutputVal() * 
      prevLayer[n].m_outputWeights[m_myIndex].weight; 
    } 

    m_outputVal = Neuron::transferFunction(sum); 
} 

Neuron::Neuron(unsigned numOutputs, unsigned myIndex) 
{ 
    for (unsigned c = 0; c < numOutputs; ++c) 
    { 
     m_outputWeights.push_back(Connection()); 
     m_outputWeights.back().weight = randomWeight(); 
    } 

    m_myIndex = myIndex; 
} 

// ************************* class Net ************************* 

class Net 
{ 
public: 
    Net(const vector<unsigned> &topology); 
    void feedForward(const vector<double> &inputVals); 
    void backProp(const vector<double> &targetVals); 
    void getResults(vector<double> &resultVals) const; 

private: 
    vector<Layer> m_layers; // m_layers{layerNum][neuronNum] 
    double m_error; 
    double m_recentAverageError; 
    double m_recentAverageSmoothingFactor; 
}; 

void Net::getResults(vector<double> &resultVals) const 
{ 
    resultVals.clear(); 

    for (unsigned n = 0; n < m_layers.back().size() - 1; ++n) 
    { 
     resultVals.push_back(m_layers.back()[n].getOutputVals()); 
    } 
} 

void Net::backProp(const vector<double> &targetVals) 
{ 
    // Calculate overall net error (RMS of output errors) 
    Layer &outputLayer = m_layers.back(); 
    m_error = 0.0; 

    for (unsigned n = 0; n < outputLayer.size() - 1; ++n) 
    { 
     double delta = targetVals[n] - outputLayer[n].getOutputVal(); 
     m_error += delta * delta; 
    } 
    m_error /= outputLayer.size() - 1; // get average error squared 
    m_error = sqrt(m_error); // RMS 

    // Implement a recent average measurement: 

    m_recentAverageError = 
     (m_recentAverageError * m_recentAverageSmoothingFactor + m_error) 
     /(m_recentAverageSmoothingFactor + 1.0); 

    // Calculate output layer gradients 
    for (unsigned n = 0; n < outputLayer.size() - 1; ++n) 
    { 
     outputLayer[n].calcOutputGradients(targetVals[n]); 
    } 

    // Calculate gradients on hidden layers 

    for (unsigned layerNum = m_layers.size() - 2; layerNum > 0; --layerNum) 
    { 
     Layer &hiddenLayer = m_layers[layerNum]; 
     Layer &nextLayer = m_layers[layerNum + 1]; 

     for (unsigned n = 0; n < hiddenLayer.size(); ++n) 
     { 
      hiddenLayer[n].calcHiddenGradients(nextLayer); 
     } 
    } 

    // For all layers from output to first hidden layer. 
    // update connection weights 

    for (unsigned layerNum = m_layers.size() - 1; layerNum > 0; --layerNum) 
    { 
     Layer &layer = m_layers[layerNum]; 
     Layer &prevLayer = m_layers[layerNum - 1]; 

     for (unsigned n = 0; n < layer.size() - 1; ++n) 
     { 
      layer[n].updateInputWeights(prevLayer); 
     } 
    } 

} 

void Net::feedForward(const vector<double> &inputVals) 
{ 
    assert(inputVals.size() == m_layers[0].size() - 1); 

    // Assign (latch) the values into the input neurons 
    for (unsigned i = 0; i < inputVals.size(); ++i) 
    { 
     m_layers[0][i].setOutputVal(inputVals[i]); 
    } 

    // Forward propagate 
    for (unsigned layerNum = 1; layerNum = m_layers.size(); ++layerNum) 
    { 
     Layer &prevLayer = m_layers[layerNum - 1]; 
     for (unsigned n = 0; n < m_layers[layerNum].size() - 1; ++n) 
     { 
      m_layers[layerNum][n].feedForward(prevLayer); 
     } 
    } 
} 

Net::Net(const vector<unsigned> &topology) 
{ 
    unsigned numLayers = topology.size(); 
    for (unsigned layerNum = 0; layerNum < numLayers; ++layerNum) 
    { 
     m_layers.push_back(Layer()); 
     unsigned numOutputs = layerNum == topology.size() - 1 ? 0 : topology[layerNum + 1]; 

     // We have made a new layer, now fill it with neurons, and 
     // add a bias neuron to the layer: 
     for (unsigned neuronNum = 0; neuronNum <= topology[layerNum]; ++neuronNum) 
     { 
      m_layers.back().push_back(Neuron(numOutputs, neuronNum)); 
      cout << "Made a Neuron!" << endl; 
     } 
    } 
} 

int main() 
{ 
    // e.g.. { 3, 2, 1 } 
    // THIS IS FOR THE NUMBER OF NEURONS THAT YOU WANT!! 
    vector<unsigned> topology; 
    topology.push_back(3); 
    topology.push_back(2); 
    topology.push_back(1); 
    Net myNet(topology); 

    vector<double> inputVals; 
    myNet.feedForward(inputVals); 

    vector<double> targetVals; 
    myNet.backProp(targetVals); 

    vector<double> resultVals; 
    myNet.getResults(resultVals); 

    system("pause"); 
} 

我已經得到錯誤,如:

錯誤:類「神經元」沒有成員「前饋」 錯誤:類「神經元」沒有成員「setOutputVal」 'neuron_OutputVal':標識符找不到

+0

可能是相關的:https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list –

+0

修復你的'類'重新定義問題,第一次是山姆在答案中提到的,第二,我可以看到'neuron_OutputVal'是一個錯字,這應該是'neuron.OutputVal()'。 –

+0

工作在較小的塊並經常編譯。在他們可能成爲重大錯誤之前,你會發現一些錯誤。 – user4581301

回答

0
class Neuron {}; 

這裏的文件中定義了一個名爲Neuron類。這是一個沒有成員的類,也沒有方法。一個完全空的類。

幾行後:

class Neuron 
{ 
public: 

// ... 

爲什麼,這裏的所謂Neuron另一個類。但是,在C++中,所有類都必須具有唯一的名稱。所以,你的C++編譯器會完全拒絕這個類聲明,並拒絕處理它。或者,採取其他一些未明確的行動。

0

class Neuron {};不是有效的前向聲明。無論如何你都不能使用前向聲明,因爲Layer的聲明需要完整的知識Neuron

您必須完全刪除前向聲明class Neuron {};,並將您的聲明刪除爲typedef vector<Neuron> Layer;。把它放在你的聲明class Net的正上方。

0

你的代碼有三個問題。

首先,正如其他人提到的那樣修復您的前瞻性聲明。

class Neuron; 

請注意,此代碼沒有{}代碼。您不需要將typedef向下移動,因爲您的Neuron類使用typedef'圖層'。

其次,在線路70上,

neuron.getOutputVal 

代替neuron_getOutputVal。

第三行在線167只是從getOutputVal(s)中刪除s。