Advertisement
Guest User

Untitled

a guest
Dec 15th, 2019
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.02 KB | None | 0 0
  1. #include <iostream>
  2. #include <cmath>
  3. #include <fstream>
  4. #include<time.h>
  5.  
  6. using namespace std;
  7.  
  8.  
  9. struct neuron
  10. {
  11.     double value;
  12.     double error;
  13.     void sig() {
  14.         value = (1 / (1 + pow(2.7182818, -value)));
  15.     }
  16. };
  17.  
  18. struct Mydata
  19. {
  20.     double info[4096];
  21.     char answer;
  22. };
  23.  
  24. class Network {
  25. public:
  26.     int layers;
  27.     neuron** neurons;
  28.     double*** weight;
  29.     int* size;
  30.  
  31.     double derivative(double x) {
  32.         double res = x * (1.0 - x);
  33.         return res;
  34.     }
  35.  
  36.     int predikt(double x) {
  37.         if (x > 0.8) {
  38.             return 1;
  39.         }
  40.         else
  41.         {
  42.             return 0;
  43.         }
  44.     }
  45.  
  46.     void setLayers(int n, int* sizeNetwork, string fileName) {
  47.  
  48.         ifstream fin;
  49.         neurons = new neuron * [n];
  50.         weight = new double** [n];
  51.         size = new int[n];
  52.  
  53.         fin.open(fileName);
  54.  
  55.         for (int i = 0; i < n; i++) {
  56.  
  57.             neurons[i] = new neuron [sizeNetwork[i]];
  58.             size[i] = sizeNetwork[i];
  59.             if (i != n -1) {
  60.                 weight[i] = new double* [sizeNetwork[i]];
  61.                 for (int j = 0; j < sizeNetwork[i]; j++)
  62.                 {
  63.                     weight[i][j] = new double [sizeNetwork[i + 1]];
  64.                     for (int k = 0; k < sizeNetwork[i + 1]; k++)
  65.                     {
  66.                         fin >> weight[i][j][k];
  67.                     }
  68.                 }
  69.             }
  70.         }
  71.  
  72.  
  73.     }
  74.  
  75.     void setLayers(int n, int* sizeNetwork) {//метод для заполнения весов и создания сетки
  76.  
  77.         layers = n;
  78.         neurons = new neuron * [n];
  79.         weight = new double** [n - 1];
  80.         size = new int[n];
  81.         srand(time(0));
  82.  
  83.         for (int i = 0; i < n; i++)
  84.         {
  85.             size[i] = sizeNetwork[i];
  86.             neurons[i] = new neuron[sizeNetwork[i]];//необходимо проверить(т.к у первого нейрона нет ошибки соит ли создавать neurons[n - 1])
  87.             if (i < n - 1)//т.к. у последнего cлоя нет связей
  88.             {
  89.                 weight[i] = new double* [sizeNetwork[i]];//size[i] количество нейронов в каждом слое
  90.                 for (int j = 0; j < sizeNetwork[i]; j++)
  91.                 {
  92.                     weight[i][j] = new double[sizeNetwork[i + 1]];//у каждого нейрона будет size[i + 1] весов
  93.                     for (int k = 0; k < sizeNetwork[i + 1]; k++)
  94.                     {
  95.                         weight[i][j][k] = (rand() % 100) * 0.01 / sizeNetwork[i];//заполняем веса рандомными числами < 1(делю на size[i] что бы веса были не такие большие )
  96.                     }
  97.                 }
  98.             }
  99.         }
  100.     }
  101.  
  102.     void setInput(double input[]) {
  103.         for (int i = 0; i < size[0]; i++)
  104.             neurons[0][i].value = input[i];//т.к мы заполняем первый слой(0)
  105.     }
  106.  
  107.     void cleanNeuronValue(int layer, int n)
  108.     {
  109.         for (int i = 0; i < n; i++) {
  110.             neurons[layer][i].value = 0;
  111.         }
  112.     }
  113.  
  114.     void forNeuronValuePack(int LayerNumber, int n) {
  115.         for (int j = 0; j < n; j++) {
  116.             for (int k = 0; k < size[LayerNumber - 1]; k++) {
  117.                 neurons[LayerNumber][j].value += neurons[LayerNumber - 1][k].value * weight[LayerNumber - 1][k][j];
  118.             }
  119.             neurons[LayerNumber][j].sig();
  120.         }
  121.     }
  122.  
  123.     double neuralValue() {
  124.         for (int i = 1; i < layers; i++)
  125.         {
  126.             cleanNeuronValue(i, size[i]);
  127.             forNeuronValuePack(i, size[i]);
  128.         }
  129.  
  130.         double max = 0;
  131.         double predic = 0;
  132.         for (int i = 1; i < size[layers - 1]; i++) {
  133.             if (neurons[layers - 1][i].value > max) {
  134.                 max = neurons[layers - 1][i].value;
  135.                 predic = i;
  136.             }
  137.         }
  138.         return predic;
  139.     }
  140.  
  141.     void backPropagation(double prediction, double rresult, double lr) {
  142.         double error;
  143.         for (int i = layers - 1; i > 0; i--) {
  144.             if (i == layers - 1) {//т.к ошибка для последнего нейрона считатется иначе
  145.                 for (int j = 0; j < size[i]; j++) {
  146.                     if (j != int(rresult)) {
  147.                         neurons[i][j].error = -pow((neurons[i][j].value), 2);
  148.                     }
  149.                     else {
  150.                         neurons[i][j].error = pow(1.0 - neurons[i][j].value, 2);
  151.                     }
  152.                 }
  153.             }
  154.             else {
  155.                 for (int j = 0; j < size[i]; j++) {
  156.                     error = 0.0;
  157.                     for (int k = 0; k < size[i + 1]; k++) {
  158.                         error += neurons[i + 1][k].error * weight[i][j][k];
  159.                     }              
  160.                     neurons[i][j].error = error;
  161.                 }
  162.             }
  163.         }
  164.         for (int i = 0; i < layers - 1; i++) {
  165.             for (int j = 0; j < size[i]; j++) {
  166.                 for (int k = 0; k < size[i + 1]; k++) {
  167.                     weight[i][j][k] += lr * neurons[i + 1][k].error * derivative(neurons[i + 1][k].value) * neurons[i][j].value;//пересчет весов
  168.                 }
  169.             }
  170.         }
  171.     }
  172.  
  173.     void safeWeights() {
  174.         ofstream fout;
  175.         fout.open("weights.txt");
  176.         for (int i = 0; i < layers; i++) {
  177.             if (i < layers - 1) {
  178.                 for (int j = 0; j < size[i]; j++) {
  179.                     for (int k = 0; k < size[i + 1]; k++) {
  180.                         fout << weight[i][j][k] << " ";
  181.                     }
  182.                 }
  183.             }
  184.         }
  185.         fout.close();
  186.     }
  187.    
  188. };
  189.  
  190.  
  191.  
  192. int main()
  193. {
  194.     srand(time(0));
  195.     setlocale(LC_ALL, "Russian");
  196.     ifstream fin;
  197.     ofstream fout;
  198.     fout.open("out.text");
  199.     Network nn;
  200.     bool to_study;
  201.     int n = 83;
  202.     int sizeNetwork[4] = { 4096, 256, 32, 26 };
  203.  
  204.     double countRightAnswers = 0;//количество верных ответов в эпохе
  205.     char rightResult;//для хранения правильного ответа который записан в файле
  206.     double input[4096];//для хранения исходных данных о символе
  207.     double result;//для хранения ответа который получили
  208.     int maxRightAnswers = 0;
  209.     cin >> to_study;
  210.  
  211.     Mydata* data = new Mydata[n];//для считывания с файла
  212.  
  213.     if (to_study)
  214.     {
  215.         fin.open("lib.txt");
  216.         for (int i = 0; i < n; i++) {
  217.             for (int j = 0; j < 4096; j++) {
  218.                 fin >> data[i].info[j];
  219.             }
  220.             fin >> data[i].answer;
  221.             data[i].answer -= 65;
  222.         }
  223.  
  224.         nn.setLayers(4, sizeNetwork);
  225.  
  226.         for (int i = 0; countRightAnswers / n * 100 < 90; i++) {
  227.  
  228.             fout << "Epoch # " << i << endl;
  229.             countRightAnswers = 0;
  230.  
  231.             for (int k = 0; k < n; k++)
  232.             {
  233.                 for (int j = 0; j < 4096; j++) {
  234.                     input[j] = data[k].info[j];
  235.                 }
  236.  
  237.                 rightResult = data[k].answer;
  238.                 nn.setInput(input);
  239.  
  240.                 result = nn.neuralValue();
  241.  
  242.                 if (result == rightResult) {
  243.                     cout << "Угадал букву " << char(rightResult + 65) << "\t\t\t****" << endl;
  244.                     countRightAnswers++;
  245.                 }
  246.                 else
  247.                 {
  248.                     nn.backPropagation(result, rightResult, 0.3);
  249.                 }
  250.             }
  251.  
  252.             cout << "Right answers: " << countRightAnswers / n * 100 << "% \t Max RA: " << double(maxRightAnswers) / n * 100 << endl;
  253.             if (countRightAnswers > maxRightAnswers) {
  254.                 maxRightAnswers = countRightAnswers;
  255.             }
  256.             nn.safeWeights();
  257.         }
  258.         fin.close();
  259.     }
  260.     else
  261.     {
  262.         nn.layers = 4;
  263.         nn.size = new int[4];
  264.         nn.size[0] = sizeNetwork[0];
  265.         nn.size[0] = sizeNetwork[1];
  266.         nn.size[0] = sizeNetwork[2];
  267.         nn.size[0] = sizeNetwork[3];
  268.         nn.setLayers(4, sizeNetwork, "weights.txt");
  269.         /*for (int i = 0; i < 3; i++) {
  270.             for (int j = 0; j < sizeNetwork[i]; j++) {
  271.                 for (int k = 0; k < sizeNetwork[i + 1]; k++)
  272.                 {
  273.                     cout << nn.weight[i][j][k]<< " ";
  274.                 }
  275.             }
  276.         }*/
  277.     }
  278.     bool forToStart;
  279.     cin >> forToStart;
  280.     if (forToStart) {
  281.         fin.open("test.txt");
  282.         for (int i = 0; i < 4096; i++) {
  283.             fin >> input[i];
  284.         }
  285.  
  286.         nn.setInput(input);
  287.         cout << char(nn.neuralValue() + 65);
  288.  
  289.     }
  290. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement