Advertisement
Trainlover08

Neural Network Class

May 6th, 2024 (edited)
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 19.18 KB | None | 0 0
  1. #include <iostream>
  2. #include <fstream>
  3. #include <sstream>
  4. #include <vector>
  5. #include <string>
  6. #include <cstdlib>
  7. #include <cmath>
  8. #include <algorithm>
  9. #include <utility>
  10.  
  11. // Function to apply ReLU activation
  12. float ReLU(float x)
  13. {
  14.     return std::max(0.0f, x);
  15. }
  16.  
  17. class LayerDense
  18. {
  19. public:
  20.     void initialize(size_t n_inputs, size_t n_neurons, const std::vector<std::vector<float>> &weights, const std::vector<float> &biases);
  21.     std::vector<std::vector<float>> forward(const std::vector<std::vector<float>> &inputs);
  22.     bool apply_ReLU = true;
  23.  
  24. private:
  25.     std::vector<std::vector<float>> weights;
  26.     std::vector<float> biases;
  27. };
  28.  
  29. void LayerDense::initialize(size_t n_inputs, size_t n_neurons, const std::vector<std::vector<float>> &init_weights, const std::vector<float> &init_biases)
  30. {
  31.     weights = init_weights;
  32.     biases = init_biases;
  33. }
  34.  
  35. std::vector<std::vector<float>> LayerDense::forward(const std::vector<std::vector<float>> &inputs)
  36. {
  37.     std::vector<std::vector<float>> output(inputs.size(), std::vector<float>(biases.size(), 0.0));
  38.     for (size_t i = 0; i < inputs.size(); ++i)
  39.     {
  40.         for (size_t k = 0; k < biases.size(); ++k)
  41.         {
  42.             float sum = 0.0;
  43.             for (size_t j = 0; j < inputs[i].size(); ++j)
  44.             {
  45.                 sum += inputs[i][j] * weights[j][k];
  46.             }
  47.             output[i][k] = sum + biases[k];
  48.             // Apply ReLU activation
  49.             if (apply_ReLU == true)
  50.             {
  51.                 output[i][k] = ReLU(output[i][k]);
  52.             }
  53.         }
  54.     }
  55.     return output;
  56. }
  57.  
  58. class nn
  59. {
  60. public:
  61.     std::string FILENAME = "NNQtable";
  62.     float greedy_start = 1.0f;
  63.     const unsigned char surviving_genetics = 1;
  64.     const unsigned short episodes = 1;
  65.     unsigned short current_epoch = 0;
  66.     float LEARNINGRATE = 1.0f;
  67.  
  68. private:
  69.     float greedy_value()
  70.     {
  71.         float greedy_min = greedy_start * 0.001f;
  72.         float decay_rate = LEARNINGRATE;
  73.         return (greedy_min + (greedy_start - greedy_min)) * std::exp(-decay_rate * current_epoch);
  74.     }
  75.  
  76.     float range_rand(const int range)
  77.     {
  78.         return ((std::rand() % (range * 2)) - range) / static_cast<float>(range / 2);
  79.     }
  80.  
  81.     float greedy_adjusted_value(float inputs, const float greedy_val)
  82.     {
  83.         return inputs + (range_rand(1000) * greedy_val);
  84.     }
  85.  
  86.     std::vector<std::string> file_name(const std::string &base_file_name)
  87.     {
  88.         std::vector<std::string> output;
  89.         for (unsigned char j = 0; j < surviving_genetics; ++j)
  90.         {
  91.             std::string index_str = std::to_string(j + 1);
  92.             std::string file_name = base_file_name + index_str + ".txt";
  93.             output.push_back(file_name);
  94.         }
  95.         return output;
  96.     }
  97.  
  98.     std::vector<std::vector<std::vector<std::vector<float>>>> readTxt(const std::string &file_name, unsigned char iteration_number)
  99.     {
  100.         std::vector<std::vector<std::vector<std::vector<float>>>> output;
  101.  
  102.         std::string line;
  103.         std::ifstream file(file_name);
  104.  
  105.         while (std::getline(file, line))
  106.         {
  107.             std::istringstream iss(line);
  108.             unsigned char i, j, k, l;
  109.             float value;
  110.             if (iss >> i >> j >> k >> l >> value)
  111.             {
  112.                 while (output.size() <= i)
  113.                     output.push_back({});
  114.                 while (output[i].size() <= j)
  115.                     output[i].push_back({});
  116.                 while (output[i][j].size() <= k)
  117.                     output[i][j].push_back({});
  118.                 output[i][j][k].push_back(value);
  119.             }
  120.         }
  121.  
  122.         file.close();
  123.         return output;
  124.     }
  125.  
  126.     std::vector<std::vector<std::vector<std::vector<float>>>> mutated_values(std::vector<std::vector<std::vector<std::vector<float>>>> input_data)
  127.     {
  128.         for (unsigned short index = 0; index < input_data.size(); ++index)
  129.         {
  130.             for (unsigned short k = 0; k < input_data[index].size(); ++k)
  131.             {
  132.                 for (unsigned short j = 0; j < input_data[index][k].size(); ++j)
  133.                 {
  134.                     for (unsigned short a = 0; a < input_data[index][k][j].size(); ++a)
  135.                     {
  136.                         input_data[index][k][j][a] = greedy_adjusted_value(input_data[index][k][j][a], greedy_value());
  137.                     }
  138.                 }
  139.             }
  140.         }
  141.         return input_data;
  142.     }
  143.  
  144.     std::vector<std::vector<std::vector<std::vector<std::vector<float>>>>> generate_batch(const unsigned char n_batch_size)
  145.     {
  146.         std::vector<std::vector<std::vector<std::vector<std::vector<float>>>>> output(n_batch_size);
  147.         std::vector<std::string> names = file_name(FILENAME);
  148.  
  149.         unsigned char actual_batch_size = std::min(n_batch_size, static_cast<unsigned char>(names.size()));
  150.  
  151.         for (char j = 0; j < actual_batch_size; ++j)
  152.         {
  153.             std::string name_gen = names.at(j);
  154.             std::vector<std::vector<std::vector<std::vector<float>>>> input = mutated_values(readTxt(name_gen, j));
  155.             output[j] = input;
  156.         }
  157.         return output;
  158.     }
  159.  
  160.     void creation_cycle(std::ofstream &newFile)
  161.     {
  162.         newFile << 0.001f;
  163.         static bool d = false;
  164.         if (!d)
  165.         {
  166.             newFile << ",";
  167.         }
  168.         else
  169.         {
  170.             newFile << " ";
  171.         }
  172.         d = !d;
  173.     }
  174.  
  175.     void create_model(const std::vector<std::string> &file_names, char n_input, char n_hidden_neurons, char n_hidden_layers, char n_output)
  176.     {
  177.         for (unsigned char i = 0; i < file_names.size(); ++i)
  178.         {
  179.             std::ofstream newFile(file_names[i]);
  180.             for (unsigned char j = 0; j < (n_input * 2); ++j)
  181.             {
  182.                 creation_cycle(newFile);
  183.             }
  184.             newFile << std::endl;
  185.             for (char k = 0; k < n_hidden_layers; ++k)
  186.             {
  187.                 for (unsigned char m = 0; m < (n_hidden_neurons * 2); ++m)
  188.                 {
  189.                     creation_cycle(newFile);
  190.                 }
  191.                 newFile << std::endl;
  192.             }
  193.             for (unsigned char g = 0; g < (n_output * 2); ++g)
  194.             {
  195.                 creation_cycle(newFile);
  196.             }
  197.             newFile << std::endl;
  198.             newFile.close();
  199.         }
  200.     }
  201.  
  202.     void create_multiple_models(char n_input, char n_hidden_neurons, char n_hidden_layers, char n_output)
  203.     {
  204.         for (unsigned char j = 0; j < surviving_genetics; ++j)
  205.         {
  206.             create_model(file_name(FILENAME), n_input, n_hidden_neurons, n_hidden_layers, n_output);
  207.         }
  208.     }
  209.  
  210.     unsigned short total_lines(const std::string &input)
  211.     {
  212.         std::ifstream file(input);
  213.         unsigned int count = 0;
  214.         std::string line;
  215.  
  216.         while (std::getline(file, line))
  217.         {
  218.             ++count;
  219.         }
  220.  
  221.         file.close();
  222.         return count;
  223.     }
  224.  
  225.     unsigned short n_neurons_of_line(const std::string &input, unsigned short target_line)
  226.     {
  227.         std::ifstream file(input);
  228.         unsigned short count = 0;
  229.         std::string line;
  230.         char character;
  231.         unsigned short index = 0;
  232.  
  233.         for (unsigned short i = 0; i < target_line; ++i)
  234.         {
  235.             std::getline(file, line);
  236.             ++count;
  237.         }
  238.  
  239.         while (file.get(character))
  240.         {
  241.             if (character == '\n')
  242.             {
  243.                 return index / 3;
  244.             }
  245.             if (character == ' ' || character == '\t')
  246.             {
  247.                 if (character == ' ')
  248.                 {
  249.                     ++index;
  250.                 }
  251.             }
  252.         }
  253.         file.close();
  254.         return index;
  255.     }
  256.  
  257.     float find_value(const std::string &file_name, unsigned char nn_layer, unsigned short dataset_in_layer, unsigned char weight_or_bias)
  258.     {
  259.         float output;
  260.         std::string outputstr;
  261.         std::ifstream file(file_name);
  262.         std::string line;
  263.         char character;
  264.  
  265.         for (unsigned char i = 0; i < nn_layer;)
  266.         {
  267.             std::getline(file, line);
  268.         }
  269.  
  270.         for (unsigned short k = 0; k < dataset_in_layer; ++k)
  271.         {
  272.             file.get(character);
  273.             if (character == ' ')
  274.             {
  275.                 file.get(character);
  276.                 if (character == ' ')
  277.                 {
  278.                     ++k;
  279.                 }
  280.             }
  281.  
  282.             if (k + 1 == dataset_in_layer)
  283.             {
  284.                 if (weight_or_bias == 0)
  285.                 {
  286.                     file.get(character);
  287.                     while (character != ' ')
  288.                     {
  289.                         file.get(character);
  290.                     }
  291.                     file >> outputstr;
  292.                 }
  293.                 else
  294.                 {
  295.                     file.get(character);
  296.                     while (character != ' ')
  297.                     {
  298.                         file.get(character);
  299.                     }
  300.                     file >> outputstr;
  301.                 }
  302.                 output = std::stof(outputstr);
  303.             }
  304.         }
  305.  
  306.         return output;
  307.     }
  308.  
  309.     std::vector<std::vector<std::vector<std::vector<std::vector<float>>>>> full_read_of_files(const std::string &base_file_name)
  310.     {
  311.         std::vector<std::vector<std::vector<std::vector<std::vector<float>>>>> output;
  312.         std::vector<std::string> names = file_name(base_file_name);
  313.         output.resize(names.size());
  314.  
  315.         for (unsigned char my_file_name = 0; my_file_name < names.size(); my_file_name++)
  316.         {
  317.             std::ifstream file(names[my_file_name]);
  318.             unsigned short total_lines_of_file = total_lines(names[my_file_name]);
  319.             std::string temp_string = "";
  320.  
  321.             for (unsigned short file_lines = 0; file_lines < total_lines_of_file;)
  322.             {
  323.                 char character;
  324.                 bool weight = false;
  325.                 unsigned short set_index = 0;
  326.  
  327.                 if (output[my_file_name].size() <= file_lines)
  328.                 {
  329.                     output[my_file_name].resize(file_lines + 1);
  330.                 }
  331.                 if (output[my_file_name][file_lines].size() <= set_index)
  332.                 {
  333.                     output[my_file_name][file_lines].resize(set_index + 1);
  334.                     output[my_file_name][file_lines][set_index].resize(2);
  335.                 }
  336.  
  337.                 std::vector<char> temp_char_string(50);
  338.                 unsigned short temp_char_string_index = 0;
  339.                 float floatValue;
  340.                 file.get(character);
  341.  
  342.                 switch (character)
  343.                 {
  344.                 case ' ':
  345.                     weight = false;
  346.                     output[my_file_name][file_lines][set_index][weight].push_back(floatValue);
  347.                     set_index++;
  348.                     break;
  349.                 case ',':
  350.                     weight = false;
  351.                     floatValue = std::stof(temp_string);
  352.                     output[my_file_name][file_lines][set_index][weight].push_back(floatValue);
  353.                     temp_string.clear();
  354.                     break;
  355.                 case '\n':
  356.                     file_lines++;
  357.                     break;
  358.                 default:
  359.                     temp_string.push_back(character);
  360.                     break;
  361.                 }
  362.             }
  363.             file.close();
  364.         }
  365.  
  366.         return output;
  367.     }
  368.  
  369.     std::vector<std::vector<std::vector<std::vector<std::vector<float>>>>> create_episodes(std::vector<std::vector<std::vector<std::vector<std::vector<float>>>>> input_vector)
  370.     {
  371.         std::vector<std::vector<std::vector<std::vector<std::vector<float>>>>> output;
  372.  
  373.         int TOTALNETWORKS = input_vector.size() * episodes;
  374.  
  375.         output.resize(TOTALNETWORKS);
  376.  
  377.         for (int currentSet = 0; currentSet < input_vector.size(); ++currentSet)
  378.         {
  379.             int intigralNet = 0;
  380.             for (int currentNetwork = 0; currentNetwork < episodes; ++currentNetwork)
  381.             {
  382.                 output.push_back(input_vector[currentSet]);
  383.                 ++intigralNet;
  384.             }
  385.         }
  386.         return output;
  387.     }
  388.  
  389.     std::vector<std::vector<std::vector<std::vector<std::vector<float>>>>> mutate_batch(std::vector<std::vector<std::vector<std::vector<std::vector<float>>>>> input)
  390.     {
  391.         for (unsigned short a = 0; a < input.size(); ++a)
  392.         {
  393.             for (unsigned short b = 0; b < input[a].size(); ++b)
  394.             {
  395.                 for (unsigned short c = 0; c < input[a][b].size(); ++c)
  396.                 {
  397.                     for (unsigned short d = 0; d < input[a][b][c].size(); ++d)
  398.                     {
  399.                         for (unsigned short e = 0; e < input[a][b][c][d].size(); ++e)
  400.                         {
  401.                             if (input[a][b][c][d].size() > e)
  402.                             {
  403.                                 input[a][b][c][d][e] = greedy_adjusted_value(input[a][b][c][d][e], greedy_value());
  404.                             }
  405.                         }
  406.                     }
  407.                 }
  408.             }
  409.         }
  410.  
  411.         return input;
  412.     }
  413.  
  414.     std::vector<std::vector<std::vector<float>>> run_batch(std::vector<std::vector<std::vector<std::vector<std::vector<float>>>>> input, std::vector<std::vector<std::vector<float>>> input_data)
  415.     {
  416.         LayerDense layer;
  417.         std::vector<std::vector<std::vector<float>>> output(input.size());
  418.  
  419.         for (size_t input_first_index = 0; input_first_index < input.size(); ++input_first_index)
  420.         {
  421.             size_t num_layers = input[input_first_index].size();
  422.             std::vector<std::vector<float>> temp_output;
  423.  
  424.             for (size_t input_second_index = 0; input_second_index < num_layers; ++input_second_index)
  425.             {
  426.                 size_t n_inputs;
  427.                 std::vector<std::vector<float>> weights;
  428.                 std::vector<float> biases;
  429.                 std::vector<std::vector<float>> forward_inputs;
  430.  
  431.                 for (size_t neuron_set_index = 0; neuron_set_index < input[input_first_index][input_second_index].size(); ++neuron_set_index)
  432.                 {
  433.                     weights.push_back(std::vector<float>());
  434.                 }
  435.  
  436.                 for (size_t neuron_set_index = 0; neuron_set_index < input[input_first_index][input_second_index].size(); ++neuron_set_index)
  437.                 {
  438.                     if (input_second_index == 0)
  439.                     {
  440.                         n_inputs = input_data.size();
  441.                         forward_inputs = input_data[neuron_set_index];
  442.                     }
  443.                     else
  444.                     {
  445.                         n_inputs = input[input_first_index][input_second_index][neuron_set_index].size();
  446.                     }
  447.  
  448.                     float temp_weight = input[input_first_index][input_second_index][neuron_set_index][0][0];
  449.                     weights[neuron_set_index].push_back(temp_weight);
  450.                     float temp_biases = input[input_first_index][input_second_index][neuron_set_index][0][1];
  451.                     biases.push_back(temp_biases);
  452.                 }
  453.  
  454.                 layer.initialize(n_inputs, input[input_first_index][input_second_index].size(), weights, biases);
  455.  
  456.                 if (input_second_index != 0)
  457.                 {
  458.                     forward_inputs = temp_output;
  459.                 }
  460.  
  461.                 if (num_layers == input_second_index + 1)
  462.                 {
  463.                     layer.apply_ReLU = false;
  464.                 }
  465.  
  466.                 temp_output = layer.forward(forward_inputs);
  467.                 layer.apply_ReLU = true;
  468.             }
  469.  
  470.             output[input_first_index] = temp_output;
  471.         }
  472.         return output;
  473.     }
  474.  
  475.     std::vector<std::vector<std::vector<std::vector<std::vector<float>>>>> find_best_networks(std::vector<std::vector<std::vector<std::vector<std::vector<float>>>>> vector_of_networks, std::vector<float> vector_of_scores)
  476.     {
  477.         std::vector<std::vector<std::vector<std::vector<std::vector<float>>>>> output;
  478.  
  479.         std::vector<std::pair<float, int>> score_and_index;
  480.  
  481.         for (int index = 0; index < vector_of_scores.size(); ++index)
  482.         {
  483.             score_and_index.push_back(std::make_pair(vector_of_scores[index], index));
  484.         }
  485.  
  486.         std::sort(score_and_index.begin(), score_and_index.end(), std::greater<std::pair<float, int>>());
  487.  
  488.         std::vector<int> top_episodes;
  489.  
  490.         for (int second_index = 0; second_index < surviving_genetics; ++second_index)
  491.         {
  492.             top_episodes.push_back(score_and_index[second_index].second);
  493.         }
  494.  
  495.         for (int a = 0; a < top_episodes.size(); ++a)
  496.         {
  497.             output.push_back(vector_of_networks[top_episodes[a]]);
  498.         }
  499.  
  500.         return output;
  501.     }
  502.  
  503.     void write_data(const std::string &base_file_name, std::vector<std::vector<std::vector<std::vector<std::vector<float>>>>> input)
  504.     {
  505.         for (int a = 0; a < input.size(); ++a)
  506.         {
  507.             std::ofstream newFile((base_file_name + std::to_string(a + 1) + ".txt"));
  508.             for (int b = 0; b < input[a].size(); ++b)
  509.             {
  510.                 for (int c = 0; c < input[a][b].size(); ++c)
  511.                 {
  512.                     for (int d = 0; d < input[a][b][c].size(); ++d)
  513.                     {
  514.                         bool commaSwitch = false;
  515.                         for (int e = 0; e < input[a][b][c][d].size(); ++e)
  516.                         {
  517.                             newFile << input[a][b][c][d][e];
  518.                             if (!commaSwitch)
  519.                             {
  520.                                 newFile << ',';
  521.                                 commaSwitch = true;
  522.                             }
  523.                             else
  524.                             {
  525.                                 newFile << ' ';
  526.                                 commaSwitch = false;
  527.                             }
  528.                         }
  529.                     }
  530.                 }
  531.                 newFile << '\n';
  532.             }
  533.             newFile.close();
  534.         }
  535.     }
  536.  
  537. public:
  538.     void createnewmodel(int input, int neurons, int layers, int output)
  539.     {
  540.         create_multiple_models(input, neurons, layers, output);
  541.     }
  542.  
  543.     std::vector<std::vector<std::vector<std::vector<std::vector<float>>>>> mutate()
  544.     {
  545.         return mutate_batch(create_episodes(full_read_of_files(FILENAME)));
  546.     }
  547.  
  548.     std::vector<std::vector<std::vector<float>>> run(std::vector<std::vector<std::vector<std::vector<std::vector<float>>>>> inputNetworks, std::vector<std::vector<std::vector<float>>> SCORES)
  549.     {
  550.         return run_batch(inputNetworks, SCORES);
  551.     }
  552.  
  553.     std::vector<std::vector<std::vector<std::vector<std::vector<float>>>>> selection(std::vector<std::vector<std::vector<std::vector<std::vector<float>>>>> mutatedData, std::vector<float> testResults)
  554.     {
  555.         return find_best_networks(mutatedData, testResults);
  556.     }
  557.  
  558.     void writeFiles(std::vector<std::vector<std::vector<std::vector<std::vector<float>>>>> data)
  559.     {
  560.         write_data(FILENAME, data);
  561.     }
  562.  
  563.     float ReLU(float input)
  564.     {
  565.         return ReLU(input);
  566.     }
  567. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement