/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * * PANIC * Portable Algorithms and Numerics In C++ * * Scientific computing from scratch, with feeling. * * Copyright (c) 2026 Michelle Bausager * * This file is part of PANIC. * * PANIC is free software licensed under the GNU General Public License v3.0 or later. * You may redistribute and/or modify it under the terms of the GPL. * * PANIC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the LICENSE file for the full license text. * * SPDX-License-Identifier: GPL-3.0-or-later * *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * * Project Name: PANIC * Module Name: neural_network * File Name: layer_dense.cpp * Revision: 0.1.0 * Date: 28-07-2026 * Author: Michelle Bausager * * Description: * Defines the dense layers used in neural network * *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ //--------------------------------------------------------------------------------------------------------------------------- // INCLUDE DESCRIPTION //--------------------------------------------------------------------------------------------------------------------------- #include #include #include #include #include #include #include #include //--------------------------------------------------------------------------------------------------------------------------- // PRIVATE CONSTANTS //--------------------------------------------------------------------------------------------------------------------------- /** * @brief Minimum number of element operations before using the OpenMP-enabled loop. * * Small vectors and matrices are kept serial because the overhead of starting * worker threads can be larger than the work itself. */ static const panic::types::uint_t layer_dense_omp_min_size = 500; //--------------------------------------------------------------------------------------------------------------------------- // INPLEMENTATION //--------------------------------------------------------------------------------------------------------------------------- namespace panic{ namespace neural_network{ //-------------------------------------------------------------------------------------------------------------------------- // Constructor Name : panic::neural_network::layer_dense // // Description: // Creates an empty layer. //-------------------------------------------------------------------------------------------------------------------------- layer_dense::layer_dense() { weights.resize(0,0); biases.resize(0); dweights.resize(0,0); dbiases.resize(0); } //-------------------------------------------------------------------------------------------------------------------------- // Constructor Name : panic::neural_network::layer_dense // // Description: // Creates an empty layer with neurons. //-------------------------------------------------------------------------------------------------------------------------- layer_dense::layer_dense(panic::types::uint_t input_size, panic::types::uint_t neurons) { weights.resize(input_size, neurons); panic::random::uniform(weights); panic::math::mul(weights, static_cast(0.01), weights); biases.resize(neurons); biases.fill(0); } //-------------------------------------------------------------------------------------------------------------------------- // Function Name : panic::neural_network::layer_dense.forward // // Description: // Calculated the forward pass: // outputs = inputs * weights + biases //-------------------------------------------------------------------------------------------------------------------------- bool layer_dense::forward(const panic::tensor::real_matrix& input_data){ inputs = input_data; if (inputs.cols() != weights.rows()){ return false; } if (!outputs.resize(inputs.rows(), weights.cols())){ return false; } if (!panic::math::matmul(inputs, weights, outputs)){ return false; } if (!panic::math::add_rowwise(outputs, biases, outputs)){ return false; } return true; } //-------------------------------------------------------------------------------------------------------------------------- // Function Name : panic::neural_network::layer_dense.backward // // Description: // Calculated the backward pass: // ?? //-------------------------------------------------------------------------------------------------------------------------- bool layer_dense::backward(const panic::tensor::real_matrix& dvalues){ // Gradients on parameters dweights = panic::math::matmul(panic::math::transpose(inputs), dvalues); dbiases = panic::math::sum_colwise(dvalues); // Gradients on values dinputs = panic::math::matmul(dvalues, panic::math::transpose(weights)); return true; } } // namespace tensor } // namespace panic