Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.72/47: Рейтинг темы: голосов - 47, средняя оценка - 4.72
0 / 0 / 0
Регистрация: 19.08.2019
Сообщений: 2
1

Нейронная сеть на c++

19.08.2019, 20:09. Показов 9650. Ответов 7
Метки нет (Все метки)

Уважаемые форумчане нужна ваша помощь с нейронной сетью на c++!
На днях захотел написать прогу - многослойный перцептрон на c++, вроде информации много и пытался менять код, но всё одинаково, прога выдаёт ответ который с увеличением колличества иттераций приближается к единице, но одинаков для всех входных значений, входа, кстати 3.
Вот код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include <iostream>
#include <vector>
#include <cmath>
#include <ctime>
 
const int input_amount = 3;
const int hiden_deep = 2;
const int hiden_amount = 2;
const float learning_rate = 0.001;
const int itteration_amount = 1000;
const std::vector<std::vector<float>> inputs {{0.00, 0.00, 0.00}, {0.00, 0.00, 1.00}, {0.00, 1.00, 0.00}, {0.00, 1.00, 1.00}, {1.00, 0.00, 0.00}, {1.00, 0.00, 1.00}, {1.00, 1.00, 0.00}, {1.00, 1.00, 1.00}};
const std::vector<float> right { 0.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00};
 
int random_input() {
    return rand() % 8;
}
 
float sigmoid(float number) {
    return 1 / (1 + pow(2.71, -number));
}
 
float random_number() {
    float number = rand() % 50 + 1;
    float a = (float)((1 / (number)) - 0.5);
    return a;
}
 
float end_error(float actual, float right) {
    return (actual - right)*(actual - right)*100;
}
 
void weights_random_filling(std::vector<std::vector<float>> &input_weights, std::vector<std::vector<std::vector<float>>> &hiden_weights, std::vector<float> &output_weights) {
for(int a = 0; a < input_amount; a++) {
for(int b = 0; b < hiden_amount; b++) {
input_weights.at(a).at(b) = random_number();
}
}
if(hiden_deep > 1) {
for(int a = 0; a < hiden_deep - 1; a++) {
for(int b = 0; b < hiden_amount; b++) {
for(int c = 0; c < hiden_amount; c++) {
hiden_weights.at(a).at(b).at(c) = random_number();
}
}
}
}
for(int a = 0; a < hiden_amount; a++) {
output_weights.at(a) = random_number();
}
}
 
void new_weights(std::vector<std::vector<float>> &hiden_deltas, std::vector<std::vector<float>> &input_weights, std::vector<std::vector<std::vector<float>>> &hiden_weights, std::vector<float> &output_weights,std::vector<std::vector<float>> hiden_data, std::vector<float> input_data, const float &output_data, const float &right_answer) {
float weights_delta = (output_data - right_answer) * output_data * (1 - output_data);
for(int a = hiden_amount - 1; a >= 0;a--) {
output_weights.at(a) -= hiden_data.at(hiden_deep - 1).at(a) * learning_rate * weights_delta;
hiden_deltas.at(hiden_deep - 1).at(a) = (weights_delta * output_weights.at(a)) * (hiden_data.at(hiden_deep - 1).at(a) * (1 - hiden_data.at(hiden_deep - 1).at(a)));
}
if(hiden_deep > 1) {
for(int a = hiden_deep - 2; a >= 0; a--) {
for(int b = hiden_amount - 1; b >= 1; b--){
for(int c = hiden_amount - 1; c >= 0; c--) {
hiden_weights.at(a).at(b).at(c) -= hiden_data.at(a).at(b)* learning_rate * hiden_deltas.at(a + 1).at(c);
hiden_deltas.at(a).at(b) += ((hiden_deltas.at(a + 1).at(c) * hiden_weights.at(a).at(b).at(c)) * (hiden_data.at(a).at(b) * (1 - hiden_data.at(a).at(b)))/hiden_amount);
}
}
}
}
for(int a = input_amount - 1; a >= 0; a--){
for(int b = hiden_amount - 1; b >= 0; b--){
input_weights.at(a).at(b) -= input_data.at(a) * learning_rate * hiden_deltas.at(0).at(b);
}
}
}
 
void neuron(std::vector<std::vector<float>> &hiden_data, std::vector<float> &input_data, float &output_data, std::vector<std::vector<float>> &input_weights, std::vector<std::vector<std::vector<float>>> &hiden_weights, std::vector<float> &output_weights) {
for(int a = 1; a < hiden_amount; a++) {
   for(int b = 0; b < input_amount; b++) {
       hiden_data.at(0).at(a) +=input_weights.at(b).at(a) * input_data.at(b);
       }
   hiden_data.at(0).at(a) = sigmoid(hiden_data.at(0).at(a));
}
if(hiden_deep > 1) {
for(int a = 1; a < hiden_deep ; a++) {
    for(int b = 1; b < hiden_amount; b++) {
       for(int c = 0; c < hiden_amount; c++) {
          hiden_data.at(a).at(b) += hiden_data.at(a - 1).at(c) * hiden_weights.at(a - 1).at(b).at(c);
                
        }
     hiden_data.at(a).at(b) = sigmoid(hiden_data.at(a).at(b));
      }
   }
}
for(int a = 0; a < hiden_amount; a++) {
    output_data += hiden_data.at(hiden_amount - 1).at(a) * output_weights.at(a);
    }
    output_data = sigmoid(output_data); 
}
 
int main() {
srand( time(0));
std::vector<std::vector<float>> hiden_data(hiden_deep, std::vector<float>(hiden_amount,0.00));
std::vector<float> input_data(input_amount, 0.00);
float output_data = 0.00;
for(int a = 0; a < hiden_deep; a++) {
   hiden_data.at(a).at(0) = 1.00;
}
std::vector<std::vector<float>> hiden_deltas (hiden_deep, std::vector<float> (hiden_amount,0.00));
 
std::vector<std::vector<float>> input_weights (input_amount, std::vector<float>(hiden_amount,0.00));
std::vector<std::vector<std::vector<float>>> hiden_weights (hiden_deep - 1, std::vector<std::vector<float>> (hiden_amount, std::vector<float> (hiden_amount, 0.00)));
std::vector<float> output_weights (hiden_amount, 0.00);
 
weights_random_filling(input_weights, hiden_weights, output_weights);
for(int a = 0; a < itteration_amount; a++) {
    int index = random_input();
    for(int b = 0; b < input_amount; b++) {
    input_data.at(b) = inputs.at(index).at(b);
    std::cout << "input at " << b + 1 << "is : " << input_data.at(b) << "\n";
       }
   neuron(hiden_data, input_data, output_data, input_weights, hiden_weights, output_weights);
    std::cout << "answer is : " << output_data << " and error is : " << end_error(output_data, right.at(index)) << " %  \n";
    new_weights(hiden_deltas, input_weights, hiden_weights, output_weights, hiden_data, input_data, output_data, right.at(index));
  }
return 0;
}
0

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
19.08.2019, 20:09
Ответы с готовыми решениями:

Нейронная сеть на с++
Ребята, словом, это программа составлена на borland c++ builder 5. Я её попытался реализовать на...

Понятие нейронная сеть
У меня возникли некоторые недопонимания в процессе изучения нейронной сети. 1) Как я понял...

Линейная нейронная сеть
Доброго времени суток! Можете скинуть пример простейшей нейронной сети на Си/С++, Матлабе, или...

Элементарная нейронная сеть
Всем доброго времени суток, уважаемые программисты. Хочу попросить у вас помощи в понимании...

7
Модератор
Эксперт С++
11071 / 9128 / 5485
Регистрация: 18.12.2011
Сообщений: 24,399
19.08.2019, 20:45 2
Посмотрите ссылки внизу страницы
0
1145 / 1052 / 165
Регистрация: 19.02.2010
Сообщений: 3,179
20.08.2019, 12:36 3
Цитата Сообщение от Eternal_void Посмотреть сообщение
pow(2.71,
Намекаю, что в сишной библиотеке стандартных мат.функций функция exp() присутствовала всегда

Цитата Сообщение от Eternal_void Посмотреть сообщение
float number = rand() % 50 + 1;
* * float a = (float)((1 / (number)) - 0.5);
((float)rand())/RAND_MAX сразу даёт число в пределах [0,1] - дальше сдвигайте на 0.5.
2 арифм. операции вместо Ваших четырёх.

Дальше код с пропавшими отступами не читабелен - и мне лень ломать глаза.
0
0 / 0 / 0
Регистрация: 19.08.2019
Сообщений: 2
21.08.2019, 14:20  [ТС] 4
Ох, я не заметил, что пропуски отсутствуют, просто с телефона скопировал(
В общем код слегка исправил, по советам VTsaregorodtsev, и добавил уточнеий, что смог, уж.
Вот код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include <iostream>
#include <vector>
#include <cmath>
#include <ctime>
 
const int input_amount = 3;
const int hiden_deep = 2;
const int hiden_amount = 2;
const float learning_rate = 0.01;
const int itteration_amount = 1000;
const std::vector<std::vector<float>> inputs {{0.00, 0.00, 0.00}, {0.00, 0.00, 1.00}, {0.00, 1.00, 0.00}, {0.00, 1.00, 1.00}, {1.00, 0.00, 0.00}, {1.00, 0.00, 1.00}, {1.00, 1.00, 0.00}, {1.00, 1.00, 1.00}};
const std::vector<float> right { 0.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00};
 
int random_input() {
    return rand() % 8;
}
 
float sigmoid(float number) {
    return 1 / (1 + exp(-number));
}
 
float random_number() {
    return (((float)rand())/RAND_MAX) - 0.5;
}
 
// средняя квадратичная ошибка, будет выводится в конце каждой итеррации:
 
float end_error(float actual, float right) {
    return (actual - right)*(actual - right)*100;
}
 
 
 
// функция занолнения случайными весами нейроны в начале : 
 
void weights_random_filling(std::vector<std::vector<float>> &input_weights, std::vector<std::vector<std::vector<float>>> &hiden_weights, std::vector<float> &output_weights) {
for(int a = 0; a < input_amount; a++) {
    for(int b = 0; b < hiden_amount; b++) {
    input_weights.at(a).at(b) = random_number();
    }
}
if(hiden_deep > 1) {
   for(int a = 0; a < hiden_deep - 1; a++) {
       for(int b = 0; b < hiden_amount; b++) {
           for(int c = 0; c < hiden_amount; c++) {
           hiden_weights.at(a).at(b).at(c) = random_number();
           }
       }
   }
}
for(int a = 0; a < hiden_amount; a++) {
   output_weights.at(a) = random_number();
   }
}
 
 
 
// регулировка весов в процессе обучения (обратное распостранение) : 
 
void new_weights(std::vector<std::vector<float>> &hiden_deltas, std::vector<std::vector<float>> &input_weights, std::vector<std::vector<std::vector<float>>> &hiden_weights, std::vector<float> &output_weights,std::vector<std::vector<float>> hiden_data, std::vector<float> input_data, const float &output_data, const float &right_answer) {
float weights_delta = (output_data - right_answer) * output_data * (1 - output_data);
for(int a = hiden_amount - 1; a >= 0;a--) {
   output_weights.at(a) -= hiden_data.at(hiden_deep - 1).at(a) * learning_rate * weights_delta;
   hiden_deltas.at(hiden_deep - 1).at(a) = (weights_delta * output_weights.at(a)) * (hiden_data.at(hiden_deep - 1).at(a) * (1 - hiden_data.at(hiden_deep - 1).at(a)));
}
for(int a = hiden_deep - 2; a >= 0; a--) {
   for(int b = hiden_amount - 1; b >= 1; b--){
       for(int c = hiden_amount - 1; c >= 0; c--) {
       hiden_weights.at(a).at(b).at(c) -= hiden_data.at(a).at(b)* learning_rate * hiden_deltas.at(a + 1).at(c);
       hiden_deltas.at(a).at(b) += ((hiden_deltas.at(a + 1).at(c) * hiden_weights.at(a).at(b).at(c)) * (hiden_data.at(a).at(b) * (1 - hiden_data.at(a).at(b)))/hiden_amount);
         }
    }
}
for(int a = input_amount - 1; a >= 0; a--){
   for(int b = hiden_amount - 1; b >= 0; b--){
      input_weights.at(a).at(b) -= input_data.at(a) * learning_rate * hiden_deltas.at(0).at(b);
      }
   }
}
 
 
 
// цикл обновления весов, умножение предыдущих значений на веса и их сумма :
 
void neuron(std::vector<std::vector<float>> &hiden_data, std::vector<float> &input_data, float &output_data, std::vector<std::vector<float>> &input_weights, std::vector<std::vector<std::vector<float>>> &hiden_weights, std::vector<float> &output_weights) {
for(int a = 1; a < hiden_amount; a++) {
   for(int b = 0; b < input_amount; b++) {
       hiden_data.at(0).at(a) +=input_weights.at(b).at(a) * input_data.at(b);
       }
   hiden_data.at(0).at(a) = sigmoid(hiden_data.at(0).at(a));
}
if(hiden_deep > 1) {
for(int a = 1; a < hiden_deep; a++) {
    for(int b = 1; b < hiden_amount; b++) {
       for(int c = 0; c < hiden_amount; c++) {
          hiden_data.at(a).at(b) += hiden_data.at(a - 1).at(c) * hiden_weights.at(a - 1).at(b).at(c);
                
        }
     hiden_data.at(a).at(b) = sigmoid(hiden_data.at(a).at(b));
      }
   }
}
for(int a = 0; a < hiden_amount; a++) {
    output_data += hiden_data.at(hiden_amount - 1).at(a) * output_weights.at(a);
    }
    output_data = sigmoid(output_data); 
}
 
 
 
// главная функция : 
 
int main() {
srand( time(0));
    
// заполнение всего нулями для стабильной работы std::vector :
     
std::vector<std::vector<float>> hiden_data(hiden_deep, std::vector<float>(hiden_amount,0.00));
std::vector<float> input_data(input_amount, 0.00);
float output_data = 0.00;
// нейрон смещения : 
for(int a = 0; a < hiden_deep; a++) {
   hiden_data.at(a).at(0) = 1.00;
}
std::vector<std::vector<float>> hiden_deltas (hiden_deep, std::vector<float> (hiden_amount,0.00));
 
std::vector<std::vector<float>> input_weights (input_amount, std::vector<float>(hiden_amount,0.00));
std::vector<std::vector<std::vector<float>>> hiden_weights (hiden_deep - 1, std::vector<std::vector<float>> (hiden_amount, std::vector<float> (hiden_amount, 0.00)));
std::vector<float> output_weights (hiden_amount, 0.00);
 
//
 
weights_random_filling(input_weights, hiden_weights, output_weights);
 
//цикл обучения :
 
for(int a = 0; a < itteration_amount; a++) {
    int index = random_input();
    for(int b = 0; b < input_amount; b++) {
    input_data.at(b) = inputs.at(index).at(b);
    std::cout << "input at " << b + 1 << "is : " << input_data.at(b) << "\n";
       }
   neuron(hiden_data, input_data, output_data, input_weights, hiden_weights, output_weights);
    std::cout << "answer is : " << output_data << " and error is : " << end_error(output_data, right.at(index)) << " %  \n";
    new_weights(hiden_deltas, input_weights, hiden_weights, output_weights, hiden_data, input_data, output_data, right.at(index));
}
 
return 0;
}
0
1145 / 1052 / 165
Регистрация: 19.02.2010
Сообщений: 3,179
21.08.2019, 20:38 5
Основное замеченное:

1) Дельты по нейронам предыдущего слоя надо считать ДО ТОГО, как корректируете веса текущего слоя. Т.е. нельзя будет просто переставить местами строки в паре (63-64, и 69-70 в последней версии кода) - надо будет раскладывать эти расчёты по двум отдельным циклам двойной вложенности.

2) Смещения у нейронов первого скрытого слоя - желательны. У Вас же их, вроде бы, нет (я на шаблонах и просто в Вашем стиле никогда нейронки не писал и писать не буду, поэтому лень внимательно вглядываться в совершенно не совместимый с моими мозгами код).

3) Желание впихнуть смещения прямо в вектор сигналов - добавляет Вам лишнего геморроя (со счётчиками циклов и т.д.). Лучше бы сигналы +1 явно не вводить - т.е. после цикла по синапсам нейрона просто добавить (если это прямое функционирование) вес смещения к получившейся сумме, и аналогично (отдельная строка=операция вне цикла по синапсам) при коррекции весов нейрона. Т.е. веса смещений МОЖНО держать отдельными векторами (по вектору на слой), чтобы названия этих векторов тоже помогали обеспечивать правильность кода (например, если будет цикл по входным сигналам нейрона - то там имя массива смещений НИКАК фигурировать не должно).

4) Есть возможность сэкономить одно умножение на коррекции каждого веса нейросетки, если применить известное со средней школы правило вынесения общего множителя за скобки. Но этот совет уже совсем посторонний к Вашей текущей задаче реализации успешной обучаемости сетки.
0
0 / 0 / 0
Регистрация: 14.03.2021
Сообщений: 2
16.08.2021, 14:37 6
Можешь посмотреть данный видос, там как раз нейросеть на C++
https://www.youtube.com/watch?v=gBYQWvz13Ds
0
51 / 3 / 1
Регистрация: 06.10.2020
Сообщений: 73
16.08.2021, 19:58 7
Правильный способ написания нейронной сети:
C++
1
2
3
4
5
6
if(...)
{ if(...)
 { if(...)
  { if(...)
   { if(...)
 {//...
0
552 / 401 / 141
Регистрация: 29.06.2020
Сообщений: 1,542
16.08.2021, 20:37 8
Цитата Сообщение от Aleksey_1024 Посмотреть сообщение
Правильный способ написания нейронной сети:
если хочешь потроллить тебе на другой форум !
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
16.08.2021, 20:37

Нейронная сеть Кохонена
Применить нейронную сеть Кохонена с самообучением для задачи кластеризации. На первом этапе...

Нейронная сеть, обучение с нуля
Нужен совет экспертов с чего начать. Бегло читала про библиотеки ИИ и остановилась на двух...

Нейронная сеть, прогнозирование, электроэнергия?!
Здравствуйте, форумчане! Помогите, пожалуйста, написать в кратчайшие сроки программу) Надо...

Нейронная сеть для функции
Как написать нейронную сеть для решения такой задачи: У меня есть нейронная сеть. Я хочу ее...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.