Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cmath>
- #include <fstream>
- #include<time.h>
- using namespace std;
- struct neuron
- {
- double value;
- double error;
- void sig() {
- value = (1 / (1 + pow(2.7182818, -value)));
- }
- };
- struct Mydata
- {
- double info[4096];
- char answer;
- };
- class Network {
- public:
- int layers;
- neuron** neurons;
- double*** weight;
- int* size;
- double derivative(double x) {
- double res = x * (1.0 - x);
- return res;
- }
- int predikt(double x) {
- if (x > 0.8) {
- return 1;
- }
- else
- {
- return 0;
- }
- }
- void setLayers(int n, int* sizeNetwork, string fileName) {
- ifstream fin;
- neurons = new neuron * [n];
- weight = new double** [n];
- size = new int[n];
- fin.open(fileName);
- for (int i = 0; i < n; i++) {
- neurons[i] = new neuron [sizeNetwork[i]];
- size[i] = sizeNetwork[i];
- if (i != n -1) {
- weight[i] = new double* [sizeNetwork[i]];
- for (int j = 0; j < sizeNetwork[i]; j++)
- {
- weight[i][j] = new double [sizeNetwork[i + 1]];
- for (int k = 0; k < sizeNetwork[i + 1]; k++)
- {
- fin >> weight[i][j][k];
- }
- }
- }
- }
- }
- void setLayers(int n, int* sizeNetwork) {//метод для заполнения весов и создания сетки
- layers = n;
- neurons = new neuron * [n];
- weight = new double** [n - 1];
- size = new int[n];
- srand(time(0));
- for (int i = 0; i < n; i++)
- {
- size[i] = sizeNetwork[i];
- neurons[i] = new neuron[sizeNetwork[i]];//необходимо проверить(т.к у первого нейрона нет ошибки соит ли создавать neurons[n - 1])
- if (i < n - 1)//т.к. у последнего cлоя нет связей
- {
- weight[i] = new double* [sizeNetwork[i]];//size[i] количество нейронов в каждом слое
- for (int j = 0; j < sizeNetwork[i]; j++)
- {
- weight[i][j] = new double[sizeNetwork[i + 1]];//у каждого нейрона будет size[i + 1] весов
- for (int k = 0; k < sizeNetwork[i + 1]; k++)
- {
- weight[i][j][k] = (rand() % 100) * 0.01 / sizeNetwork[i];//заполняем веса рандомными числами < 1(делю на size[i] что бы веса были не такие большие )
- }
- }
- }
- }
- }
- void setInput(double input[]) {
- for (int i = 0; i < size[0]; i++)
- neurons[0][i].value = input[i];//т.к мы заполняем первый слой(0)
- }
- void cleanNeuronValue(int layer, int n)
- {
- for (int i = 0; i < n; i++) {
- neurons[layer][i].value = 0;
- }
- }
- void forNeuronValuePack(int LayerNumber, int n) {
- for (int j = 0; j < n; j++) {
- for (int k = 0; k < size[LayerNumber - 1]; k++) {
- neurons[LayerNumber][j].value += neurons[LayerNumber - 1][k].value * weight[LayerNumber - 1][k][j];
- }
- neurons[LayerNumber][j].sig();
- }
- }
- double neuralValue() {
- for (int i = 1; i < layers; i++)
- {
- cleanNeuronValue(i, size[i]);
- forNeuronValuePack(i, size[i]);
- }
- double max = 0;
- double predic = 0;
- for (int i = 1; i < size[layers - 1]; i++) {
- if (neurons[layers - 1][i].value > max) {
- max = neurons[layers - 1][i].value;
- predic = i;
- }
- }
- return predic;
- }
- void backPropagation(double prediction, double rresult, double lr) {
- double error;
- for (int i = layers - 1; i > 0; i--) {
- if (i == layers - 1) {//т.к ошибка для последнего нейрона считатется иначе
- for (int j = 0; j < size[i]; j++) {
- if (j != int(rresult)) {
- neurons[i][j].error = -pow((neurons[i][j].value), 2);
- }
- else {
- neurons[i][j].error = pow(1.0 - neurons[i][j].value, 2);
- }
- }
- }
- else {
- for (int j = 0; j < size[i]; j++) {
- error = 0.0;
- for (int k = 0; k < size[i + 1]; k++) {
- error += neurons[i + 1][k].error * weight[i][j][k];
- }
- neurons[i][j].error = error;
- }
- }
- }
- for (int i = 0; i < layers - 1; i++) {
- for (int j = 0; j < size[i]; j++) {
- for (int k = 0; k < size[i + 1]; k++) {
- weight[i][j][k] += lr * neurons[i + 1][k].error * derivative(neurons[i + 1][k].value) * neurons[i][j].value;//пересчет весов
- }
- }
- }
- }
- void safeWeights() {
- ofstream fout;
- fout.open("weights.txt");
- for (int i = 0; i < layers; i++) {
- if (i < layers - 1) {
- for (int j = 0; j < size[i]; j++) {
- for (int k = 0; k < size[i + 1]; k++) {
- fout << weight[i][j][k] << " ";
- }
- }
- }
- }
- fout.close();
- }
- };
- int main()
- {
- srand(time(0));
- setlocale(LC_ALL, "Russian");
- ifstream fin;
- ofstream fout;
- fout.open("out.text");
- Network nn;
- bool to_study;
- int n = 83;
- int sizeNetwork[4] = { 4096, 256, 32, 26 };
- double countRightAnswers = 0;//количество верных ответов в эпохе
- char rightResult;//для хранения правильного ответа который записан в файле
- double input[4096];//для хранения исходных данных о символе
- double result;//для хранения ответа который получили
- int maxRightAnswers = 0;
- cin >> to_study;
- Mydata* data = new Mydata[n];//для считывания с файла
- if (to_study)
- {
- fin.open("lib.txt");
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < 4096; j++) {
- fin >> data[i].info[j];
- }
- fin >> data[i].answer;
- data[i].answer -= 65;
- }
- nn.setLayers(4, sizeNetwork);
- for (int i = 0; countRightAnswers / n * 100 < 90; i++) {
- fout << "Epoch # " << i << endl;
- countRightAnswers = 0;
- for (int k = 0; k < n; k++)
- {
- for (int j = 0; j < 4096; j++) {
- input[j] = data[k].info[j];
- }
- rightResult = data[k].answer;
- nn.setInput(input);
- result = nn.neuralValue();
- if (result == rightResult) {
- cout << "Угадал букву " << char(rightResult + 65) << "\t\t\t****" << endl;
- countRightAnswers++;
- }
- else
- {
- nn.backPropagation(result, rightResult, 0.3);
- }
- }
- cout << "Right answers: " << countRightAnswers / n * 100 << "% \t Max RA: " << double(maxRightAnswers) / n * 100 << endl;
- if (countRightAnswers > maxRightAnswers) {
- maxRightAnswers = countRightAnswers;
- }
- nn.safeWeights();
- }
- fin.close();
- }
- else
- {
- nn.layers = 4;
- nn.size = new int[4];
- nn.size[0] = sizeNetwork[0];
- nn.size[0] = sizeNetwork[1];
- nn.size[0] = sizeNetwork[2];
- nn.size[0] = sizeNetwork[3];
- nn.setLayers(4, sizeNetwork, "weights.txt");
- /*for (int i = 0; i < 3; i++) {
- for (int j = 0; j < sizeNetwork[i]; j++) {
- for (int k = 0; k < sizeNetwork[i + 1]; k++)
- {
- cout << nn.weight[i][j][k]<< " ";
- }
- }
- }*/
- }
- bool forToStart;
- cin >> forToStart;
- if (forToStart) {
- fin.open("test.txt");
- for (int i = 0; i < 4096; i++) {
- fin >> input[i];
- }
- nn.setInput(input);
- cout << char(nn.neuralValue() + 65);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement