Прежде всего, я новичок в этой концепции DOD, и хотя я новичок в этом, я считаю ее действительно захватывающей с точки зрения программиста.
Я сделал многослойный персептрон некоторое время назад как проект ОО для себя, и так как я сейчас изучаю DOD, я подумал, что было бы неплохо сделать это с этой парадигмой.
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;
};
Я знаю, что это может быть (и почти наверняка не) лучший формат, но я попытался разделить вещи, которые я бы использовал в разных массивах Layer. Но способ хранения массивов действительно меня заинтриговал, так как они должны быть собраны вместе как структура для более быстрого чтения памяти (или я что-то упустил?). Если я правильно помню, new [] размещает массив где-то в памяти и сохраняет только указатель на это место, в то время как статический массив в структуре будет размещен в его пространстве.
Исходя из этого, я подумал о создании шаблонов Layer (и Network):
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;
};
Если бы таким образом стал Layer, был бы какой-нибудь способ создать вариационный шаблон Network с любым количеством скрытых слоев? Или мое понимание статических массивов неверно? Есть ли разница между созданием таких массивов (и временем доступа)? Где мои ключи?
При использовании массивов в стиле C в Layer
означает, что они будут распределены в пределах struct
улучшит ли это производительность, зависит от того, как вы получаете доступ к своим данным, и обычно вы не хотите слишком сильно беспокоиться об оптимизации, пока у вас не возникнут проблемы с производительностью. Вот почему мне было интересно, почему вы не используете std::vector
производительность будет незначительной, и вам не придется отслеживать размер или беспокоиться о распределении. В противном случае сложно сделать обобщения о производительности, это будет зависеть от конкретного приложения, и вы должны определить лучший подход на основе тестов.
Что касается использования variadic template
за Network
этот пример должен дать вам хорошее представление о том, как заставить его работать:
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>() ) ;
}
Других решений пока нет …