Line data Source code
1 : /** 2 : * @file Neuron.h 3 : * @author Damien Balima (www.dams-labs.net) 4 : * @brief Neuron class 5 : * @date 2024-03-07 6 : * 7 : * @copyright Damien Balima (c) CC-BY-NC-SA-4.0 2024 8 : * 9 : */ 10 : #pragma once 11 : #include "ActivationFunctions.h" 12 : #include "NeuronConnection.h" 13 : #include <exception> 14 : #include <functional> 15 : #include <math.h> 16 : #include <opencv2/opencv.hpp> 17 : #include <random> 18 : #include <stdexcept> 19 : #include <vector> 20 : 21 : namespace sipai { 22 : 23 : /** 24 : * @brief The Neuron class represents a neuron in a neural network. It contains 25 : * a value, bias, error, and a vector of weights. It also has methods for 26 : * initializing weights. 27 : */ 28 : class Neuron { 29 : public: 30 : // Default constructor 31 73 : Neuron() = default; 32 : 33 : // The weights of the neuron 34 : cv::Mat weights; 35 : 36 : // Index in current layer 37 : size_t index_x; 38 : size_t index_y; 39 : 40 : // Some indexes to use with Vulkan 41 : mutable size_t weightsIndex = 0; 42 : mutable size_t neighborsIndex = 0; 43 : mutable size_t neighborsSize = 0; 44 : 45 : // Connections to the adjacents neurons in the same layer, using 46 : // 4-neighborhood (Von Neumann neighborhood). Could be improve to 47 : // 8-neighborhood (Moore neighborhood) or Extended neighborhood (radius) 48 : // later. 49 : std::vector<NeuronConnection> neighbors; 50 : 51 : /** 52 : * @brief Initializes the weights of the neuron to a given size. The weights 53 : * are randomized to break symmetry. 54 : * 55 : * @param size_x The new size in X of the weights vector. 56 : * @param size_y The new size in Y of the weights vector. 57 : */ 58 123 : void initWeights(size_t size_x, size_t size_y) { 59 123 : weights = cv::Mat((int)size_y, (int)size_x, CV_32FC4); 60 : 61 : // Random initialization 62 123 : cv::randn(weights, cv::Vec4f::all(0), cv::Vec4f::all(1)); 63 123 : } 64 : 65 60 : std::string toStringCsv(size_t max_weights) const { 66 60 : std::ostringstream oss; 67 180 : for (int y = 0; y < weights.rows; y++) { 68 432 : for (int x = 0; x < weights.cols; x++) { 69 1560 : for (int i = 0; i < 4; i++) { 70 1248 : oss << weights.at<cv::Vec4f>(y, x)[i] << ","; 71 : } 72 : } 73 : }; 74 : 75 : // fill the lasts columns with empty ",RGBA" 76 108 : for (size_t i = weights.total(); i < max_weights; ++i) { 77 48 : oss << ",,,,"; 78 : } 79 60 : std::string str = oss.str(); 80 60 : if (!str.empty()) { 81 60 : str.pop_back(); // remove the extra comma 82 : } 83 120 : return str; 84 60 : } 85 : 86 60 : std::string toNeighborsStringCsv(size_t max_weights) const { 87 60 : std::ostringstream oss; 88 212 : for (const auto &neighbor : neighbors) { 89 760 : for (int i = 0; i < 4; i++) { 90 608 : oss << neighbor.weight[i] << ","; 91 : } 92 : } 93 : // fill the lasts columns with empty ",RGBA" 94 268 : for (size_t i = neighbors.size(); i < max_weights; ++i) { 95 208 : oss << ",,,,"; 96 : } 97 60 : std::string str = oss.str(); 98 60 : if (!str.empty()) { 99 60 : str.pop_back(); // remove the extra comma 100 : } 101 120 : return str; 102 60 : } 103 : }; 104 : } // namespace sipai