问题
First of all, I'm new to this concept of DOD, and while new to it, I find it really exciting from a programmer perspective.
I made a Multi-Layer Perceptron a while ago as an OO project for myself, and since I'm learning DOD now, I thought it would be nice to make it with this paradigm.
struct Neuron
{
double bias;
double error;
};
struct Layer
{
Neuron* neurons;
double* output;
double** connections;
unsigned numberNeurons;
};
struct Network
{
unsigned numberInput;
double* input;
std::vector<Layer*> hidden;
Layer* output;
};
I know it may not be (and almost certainly isn't) the best format, but I tried to separate the things I'd use more in different arrays of the Layer. But the way the arrays are stored is really intriguing me, since they are supposed to be stacked together as a struct for faster memory reading (or did I miss something?). If I recall correctly, new[] allocates the array somewhere in the memory and stores only the pointer to that location, while a static array in a struct would be allocated within its space.
Based on that, I thought of making Layer (and Network) template structs:
template<unsigned n_neurons, unsigned n_connections>
struct Layer
{
Neuron neurons[n_neurons];
double output[n_neurons];
double connections[n_neurons][n_connections];
static const unsigned numberNeurons = n_neurons;
};
If Layer became such thing, though, would there be any way to make a variadic template of Network with any number of hidden layers? Or is my understanding of static arrays wrong? Is there any difference between creation of such arrays (and access time)? Where are my keys?
回答1:
While using C-style arrays in Layer
means that they will be allocated within the struct
whether that will improve performance is going to depend on how you access your data and usually you don't want to worry too much about optimizing until you start having performance issues. Which is why I was wondering why don't you use std::vector
there would be little performance hit and you don't have to keep track of size or worry about allocation. Otherwise it is hard to make generalizations about performance it will be application specific and you should determine the best approach based on benchmarks.
As for using a variadic template
for Network
this sample should give you a good idea how to make it work:
template<unsigned n_neurons, unsigned n_connections>
struct Network
{
unsigned numberInput;
double* input;
std::vector<Layer<n_neurons,n_connections>*> hidden;
Layer<n_neurons,n_connections>* output;
template <typename... Args>
void helper( Layer<n_neurons,n_connections>* layer)
{
std::cout << "final helper" << std::endl ;
std::cout << layer->numberNeurons << std::endl ;
}
template <typename... Args>
void helper( Layer<n_neurons,n_connections>* layer, Args... args)
{
std::cout << "helper" << std::endl ;
std::cout << layer->numberNeurons << std::endl ;
helper( args... ) ;
}
template <typename... Args>
Network(Args... args)
{
std::cout << "Network ctor()" << std::endl ;
helper( args... ) ;
}
};
int main()
{
Network<10,5> N1( new Layer<10,5>(), new Layer<10,5>(), new Layer<10,5>() ) ;
}
来源:https://stackoverflow.com/questions/15961835/how-do-i-create-a-multi-layer-perceptron-following-dod-or-how-are-dynamically-a