From b80c97794359b025f30bd8e4a8b5b4504cac1490 Mon Sep 17 00:00:00 2001 From: Daniel Lidstrom Date: Mon, 10 Nov 2025 09:54:16 +0100 Subject: [PATCH 1/2] refactor(network): replace overloaded Predict with distinct functions and optimize memory handling This commit refactors the neural network prediction process by replacing the overloaded Predict method with two distinct functions. The first function now returns the output vector, while the second fills the provided vectors for hidden and output layers directly. Additionally, object initialization in the Create methods of the Trainer class has been optimized using move semantics, and unnecessary copies have been eliminated for improved performance and memory efficiency. These changes enhance code clarity and reduce potential overheads during the prediction and training processes. --- Cpp/neural.cpp | 62 +++++++++++++++++++++++++------------------------- Cpp/neural.h | 49 ++++++++++++++++++++------------------- 2 files changed, 56 insertions(+), 55 deletions(-) diff --git a/Cpp/neural.cpp b/Cpp/neural.cpp index 8ff179f..035a317 100644 --- a/Cpp/neural.cpp +++ b/Cpp/neural.cpp @@ -30,13 +30,14 @@ double sigmoid_prim(double f) { return f * (1.0 - f); } /* network */ Vector Network::Predict(const Vector &input) const { - Vector y_hidden = Vector(hiddenCount); - Vector y_output = Vector(outputCount); - return Predict(input, y_hidden, y_output); + Vector y_hidden(hiddenCount); + Vector y_output(outputCount); + Predict(input, y_hidden, y_output); + return y_output; } -Vector Network::Predict(const Vector &input, Vector &hidden, - Vector &output) const { +void Network::Predict(const Vector &input, Vector &hidden, + Vector &output) const { for (std::size_t c = 0; c < hiddenCount; c++) { double sum = 0.0; for (size_t r = 0; r < input.size(); r++) { @@ -54,43 +55,42 @@ Vector Network::Predict(const Vector &input, Vector &hidden, output[c] = sigmoid(sum + biasesOutput[c]); } - - return output; } /* trainer */ -Trainer Trainer::Create(Neural::Network &&network, size_t hiddenCount, - size_t outputCount) { - Vector hidden = Vector(hiddenCount); - Vector output = Vector(outputCount); - Vector gradHidden = Vector(hiddenCount); - Vector gradOutput = Vector(outputCount); - return Trainer{.network = network, - .hidden = hidden, - .output = output, - .gradHidden = gradHidden, - .gradOutput = gradOutput}; +Trainer Trainer::Create(Neural::Network network) { + Vector hidden(network.hiddenCount); + Vector output(network.outputCount); + Vector gradHidden(network.hiddenCount); + Vector gradOutput(network.outputCount); + return Trainer{.network = std::move(network), + .hidden = std::move(hidden), + .output = std::move(output), + .gradHidden = std::move(gradHidden), + .gradOutput = std::move(gradOutput)}; } Trainer Trainer::Create(size_t inputCount, size_t hiddenCount, size_t outputCount, std::function rand) { - Vector hidden = Vector(hiddenCount); - Vector output = Vector(outputCount); - Vector gradHidden = Vector(hiddenCount); - Vector gradOutput = Vector(outputCount); - Vector weightsHidden = Vector(); + Vector hidden(hiddenCount); + Vector output(outputCount); + Vector gradHidden(hiddenCount); + Vector gradOutput(outputCount); + Vector weightsHidden; + weightsHidden.reserve(inputCount * hiddenCount); for (size_t i = 0; i < inputCount * hiddenCount; i++) { weightsHidden.push_back(rand() - 0.5); } - Vector biasesHidden = Vector(hiddenCount); - Vector weightsOutput = Vector(); + Vector biasesHidden(hiddenCount); + Vector weightsOutput; + weightsOutput.reserve(hiddenCount * outputCount); for (size_t i = 0; i < hiddenCount * outputCount; i++) { weightsOutput.push_back(rand() - 0.5); } - Vector biasesOutput = Vector(outputCount); + Vector biasesOutput(outputCount); Neural::Network network = {.inputCount = inputCount, .hiddenCount = hiddenCount, .outputCount = outputCount, @@ -98,11 +98,11 @@ Trainer Trainer::Create(size_t inputCount, size_t hiddenCount, .biasesHidden = std::move(biasesHidden), .weightsOutput = std::move(weightsOutput), .biasesOutput = std::move(biasesOutput)}; - return Trainer{.network = network, - .hidden = hidden, - .output = output, - .gradHidden = gradHidden, - .gradOutput = gradOutput}; + return Trainer{.network = std::move(network), + .hidden = std::move(hidden), + .output = std::move(output), + .gradHidden = std::move(gradHidden), + .gradOutput = std::move(gradOutput)}; } void Trainer::Train(const Vector &input, const Vector &y, double lr) { diff --git a/Cpp/neural.h b/Cpp/neural.h index 4f5b591..62c66fe 100644 --- a/Cpp/neural.h +++ b/Cpp/neural.h @@ -24,30 +24,31 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include namespace Neural { - typedef std::vector Vector; - typedef std::vector Matrix; - struct Network { - size_t inputCount; - size_t hiddenCount; - size_t outputCount; - Vector weightsHidden; - Vector biasesHidden; - Vector weightsOutput; - Vector biasesOutput; - Vector Predict(const Vector& input) const; - Vector Predict(const Vector& input, Vector& hidden, Vector& output) const; - }; +typedef std::vector Vector; +typedef std::vector Matrix; +struct Network { + size_t inputCount; + size_t hiddenCount; + size_t outputCount; + Vector weightsHidden; + Vector biasesHidden; + Vector weightsOutput; + Vector biasesOutput; + Vector Predict(const Vector &input) const; + void Predict(const Vector &input, Vector &hidden, Vector &output) const; +}; - struct Trainer { - Network network; - Vector hidden; - Vector output; - Vector gradHidden; - Vector gradOutput; - static Trainer Create(Neural::Network&& network, size_t hiddenCount, size_t outputCount); - static Trainer Create(size_t inputCount, size_t hiddenCount, size_t outputCount, std::function rand); - void Train(const Vector& input, const Vector& output, double lr); - }; -} +struct Trainer { + Network network; + Vector hidden; + Vector output; + Vector gradHidden; + Vector gradOutput; + static Trainer Create(Neural::Network network); + static Trainer Create(size_t inputCount, size_t hiddenCount, + size_t outputCount, std::function rand); + void Train(const Vector &input, const Vector &output, double lr); +}; +} // namespace Neural #endif From 76d795912b9c87694029d9ec17fd9790f0c29e8e Mon Sep 17 00:00:00 2001 From: Daniel Lidstrom Date: Mon, 10 Nov 2025 09:58:42 +0100 Subject: [PATCH 2/2] refactor(core): introduce RandFcn typedef for random function Replaced std::function with a typedef RandFcn in neural.cpp and neural.h for improved code readability and maintainability. This change simplifies the function signature and makes it easier to update or replace the random function type in the future. No functional changes were made. --- Cpp/neural.cpp | 2 +- Cpp/neural.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Cpp/neural.cpp b/Cpp/neural.cpp index 035a317..c815166 100644 --- a/Cpp/neural.cpp +++ b/Cpp/neural.cpp @@ -72,7 +72,7 @@ Trainer Trainer::Create(Neural::Network network) { } Trainer Trainer::Create(size_t inputCount, size_t hiddenCount, - size_t outputCount, std::function rand) { + size_t outputCount, RandFcn rand) { Vector hidden(hiddenCount); Vector output(outputCount); Vector gradHidden(hiddenCount); diff --git a/Cpp/neural.h b/Cpp/neural.h index 62c66fe..02b73cf 100644 --- a/Cpp/neural.h +++ b/Cpp/neural.h @@ -26,6 +26,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. namespace Neural { typedef std::vector Vector; typedef std::vector Matrix; +typedef std::function RandFcn; struct Network { size_t inputCount; size_t hiddenCount; @@ -46,7 +47,7 @@ struct Trainer { Vector gradOutput; static Trainer Create(Neural::Network network); static Trainer Create(size_t inputCount, size_t hiddenCount, - size_t outputCount, std::function rand); + size_t outputCount, RandFcn rand); void Train(const Vector &input, const Vector &output, double lr); }; } // namespace Neural