2016-11-04 14 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。