Не обучается Нейронная сеть

main.cpp

#include <iostream>
#include "Neuron.h"
const uint size = 10;
void getImage(std::vector<std::vector<double>>& image, lint& d) {
  double x;
  for (uint i = 0; i < size; i++) {
    image.push_back(std::vector<double>());
    for (uint j = 0; j < size; j++) {
      std::cin >> x; // матрица изображения
      image[i].push_back(x);
    }
  }
  std::cin >> d; // что на изображении (0-9)
}
int main() {
  srand(time(0));
  std::vector<Neuron> net;
  lint d;
  for (uint i = 0; i < 10; i++) {
    std::vector<std::vector<double>> vec(1); // 0-255 или 0.01-0.99
    net.push_back(Neuron(vec));
  }
  
  for (uint r = 0; r < 100; r++) {
    std::vector<std::vector<double>> image;
    getImage(image, d);
    double sum = 0;
    for (uint i = 0; i < 10; i++) {
      net[i] = Neuron(image);
    }
    for (uint i = 0; i < 10; i++) {
      lint tmp = net[i].activate();
      net[max(net)].outweight(max(net), d);
    }
    std::cout << "\n---  " << max(net) << "  ---\n";
  }
  
  return 0;
}

Neuron.h

#include <iostream>
#include <vector>
#include <cmath>
typedef unsigned int uint;
typedef long long int lint;
#define e 2.718281
class Neuron {
public:
  int countInput;
  std::vector<std::vector<double>> input;
  std::vector<std::vector<double>> weight;
  double output = 0;
  double res = 0;

  Neuron() {}
  Neuron(std::vector<std::vector<double>>&);

  void setInput(std::vector<std::vector<double>>);
  void norm();
  double activate();
  void outweight(lint y, lint d);
};


Neuron::Neuron(std::vector<std::vector<double>>& inp):
    countInput(inp.size()),
    input(inp),
    weight(inp.size(), std::vector<double>(inp[0].size(), (rand() % 100 + 1) / 100.0f)) {}

void Neuron::norm(){
  for (uint i = 0; i < input[0].size(); i++) {
    for (uint j = 0; j < input[0].size(); j++) {
      if (input[i][j] > 1) input[i][j] /= 255;
      input[i][j] = ((input[i][j] == 0)? 0.01 : ((input[i][j] == 1)? 0.99 : input[i][j]));
    }
  }
}
double f(double x) {
  return 1 / (1 - pow(e, -x));
}
double f_(double x) {
  return f(x) * (1 - f(x));
}
double Neuron::activate() {
  output = 0;
  for (uint i = 0; i < countInput; i++) {
    for (uint j = 0; j < countInput; j++) {
      output += input[i][j] * weight[i][j];
    }
  }
  res = f(output);
  return res;
}
void Neuron::outweight(lint y, lint d) {
  for (uint i = 0; i < countInput; i++) {
    for (uint j = 0; j < countInput; j++) {
      weight[i][j] += 0.01 * (d - y) * output * f_(output);
    }
  }
}


lint max(std::vector<Neuron>& net) {
  lint max = 0;
  lint r = 0;
  for (uint i = 0; i < 10; i++) {
    double tmp = net[i].activate();
    r = (net[i].res > max)? i : r;
    max = (net[i].res > max)? net[i].res : max;
  }
  return r;
}

По идее, нейронка должна определять цифры (0-9) в матрице. Веса вроде верно изменяю.


Ответы (0 шт):