Не обучается Нейронная сеть
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) в матрице. Веса вроде верно изменяю.