Форум программистов, компьютерный форум, киберфорум
ИИ, нейросети, LLM, ML, Data Science, ИИ-агенты
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.71/21: Рейтинг темы: голосов - 21, средняя оценка - 4.71
0 / 0 / 0
Регистрация: 15.06.2019
Сообщений: 33

Нейронная сеть направленная на распознавание рукописных цифр с картинки, после обучения выдает примерно примерно один и

22.10.2019, 13:09. Показов 4704. Ответов 39

Студворк — интернет-сервис помощи студентам
И так я написал нейронку которая распознает рукописные цифр от 0-9, после обучения получаются примерно одинаковыми, при этом не возможно отличить правильный от неправильного. Нужна помощь, что это может быть?! Что делать?! Что не так?!
[вот что получилось после обучения]()

ВОТ КОД!
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#define _CRT_SECURE_NO_WARNINGS
//#include <opencv2/opencv.hpp> 
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include <iostream> 
#include <time.h>
#include <omp.h>
#include <math.h>
#include <conio.h>
#include <Windows.h>
#include <string>
#include <vector>
#include <fstream>
#include <conio.h>
using namespace std;
using namespace cv;
 
const int kolPercNeurons[3] = { 784,196,10 };
const int kolLearningImages = 10;//Кол-во обучающих изображений
const long double baseLearnPercRate = 0.083;
long double PercLearningRate = baseLearnPercRate;
vector<vector<vector<long double>>> percWeights(2);//Веса переходов между слоями в персептроне 
vector<long double> neuralOut(kolPercNeurons[2]);//Результат работы нейронной сети 
vector<vector<long double>> percLvls(3);//Персептрон
//vector<vector<vector<long double>>> percErrors;//Матрица ошибок персептрона 
vector<vector<long double>> percErrors(3, vector<long double>(kolPercNeurons[0]));//ошибки для данного слоя перцептрона
vector<vector<long double>> trueAns(kolPercNeurons[2], vector<long double>(1));
vector<vector<long double>> listImage(1);//Текущее изображение
vector<int> orderImage(kolLearningImages, 0);
 
void LoadImg(int Num) {
    stringstream ss;
    ss << orderImage[Num - 1];
    //cout << orderImage[Num-1] << endl;
    string name = ss.str();
    string name1 = ss.str();
    name += ".png";
    name1 += ".txt";
    name = "tr2/" + name;
    name1 = "txt1/" + name1;
    //cout << name;
    Mat img = imread(name, CV_LOAD_IMAGE_GRAYSCALE);
    //resize(img, img, Size(480, 480), 0, 0, INTER_CUBIC);
    //cout << img.rows << " " << img.cols;
    for (int iRead = 0; iRead < img.rows; iRead++) {
        for (int jRead = 0; jRead < img.cols; jRead++) {
            percLvls[0][iRead+jRead] = img.at<uchar>(iRead, jRead);
            //cout<< percLvls[0][jRead+iRead] << " ";
            // listStartImageBGR[1][iRead][jRead] = img.at<Vec3b>(iRead, jRead)[1];
        //    listStartImageBGR[2][iRead][jRead] = img.at<Vec3b>(iRead, jRead)[2];
            //cout << listStartImageBGR[0][iRead][jRead] << " " << listStartImageBGR[1][iRead][jRead] << " " << listStartImageBGR[2][iRead][jRead] << endl;
        }
    }
    //cout << 1;
    img.release();
    ifstream file(name1);
    for (int iRead = 0; iRead < kolPercNeurons[2]; iRead++) {
        file >> trueAns[iRead][0];
        //cout << trueAns[iRead][0];
        //trueAns[iRead][0] = trueAns[iRead][0] / 100;
       // cout << trueAns[iRead][0]<<endl;
    }
    //cout << endl;
    file.close();
};
 
long double activateFunction(long double x) {
    //return (x <= 0) ? ((long double)(rand() % 5) / 100) : x;
    return 1.0 - 2.0 / (exp(2 * x) + 1);
}
 
long double activateFunctionDX(long double x) {
    return 1 - x * x;
}
 
long double sigm(long double x) {
    return 1 / (1 + exp(-x));
}
 
long double sigmDX(long double x) {
    return x * (1 - x);
}
 
void percToNextLvl(vector<long double>& curLvl, int curNeroAmt, vector<long double>& succLvl, int succNeroAmt, vector<vector<long double>>& curWeights)
{
    for (int i = 0; i < curNeroAmt; i++) {
#pragma omp parallel for schedule(guided, succNeroAmt / flows)
        for (int j = 0; j < succNeroAmt; j++)
            succLvl[j] += curLvl[i] * curWeights[i][j];
    }//тут
#pragma omp parallel for schedule(guided, succNeroAmt / flows)
    for (int j = 0; j < succNeroAmt; j++)
        succLvl[j] = sigm(succLvl[j]);
 
}
 
void learningPerc(vector<vector<long double>>& Errors, int percLvl, int amtNerous, int curImage) {
        if (percLvl == 2) {
            for (int i = 0; i < amtNerous; i++) {
#pragma omp parallel for schedule(guided, kolPercNeurons[percLvl] / flows)
                Errors[percLvl][i] = sigmDX(percLvls[percLvl][i]) * Errors[percLvl][i];
                //cout << Errors[percLvl][i] << " ";
            }
        }
        else {
            for (int i = 0; i < amtNerous; i++) {
#pragma omp parallel for schedule(guided, kolPercNeurons[percLvl] / flows)
                for (int j = 0; j < kolPercNeurons[percLvl + 1]; j++) {
                    Errors[percLvl][i] += percWeights[percLvl][i][j] * Errors[percLvl + 1][j];
                }
                Errors[percLvl][i] *= sigmDX(percLvls[percLvl][i]);
                //cout << Errors[percLvl][i]<<" ";
            }
        }
        for (int i = 0; i < kolPercNeurons[percLvl - 1]; i++) {
#pragma omp parallel for schedule(guided, kolPercNeurons[percLvl] / flows)
            for (int j = 0; j < kolPercNeurons[percLvl]; j++) {
                long double delta = PercLearningRate * Errors[percLvl][j] * percLvls[percLvl - 1][i];
                //cout << delta<<" ";
                percWeights[percLvl - 1][i][j] += delta;
            }
        }
 
        if (percLvl-1 == 0) {
            return;
        }
        else learningPerc(Errors, percLvl - 1, kolPercNeurons[percLvl - 1], curImage);
}
 
void mixImage() {
    for (int i = 0; i < kolLearningImages; i++) {
        orderImage[i] = i + 1;
    }
    for (int i = 0; i < kolLearningImages; i++) {
        swap(orderImage[i], orderImage[rand() % kolLearningImages]);
    }
    //    for (int i = 0; i < kolLearningImages; i++) {
    //        cout << orderImage[i] << endl;
    //    }
}
 
void fillWeight() {
    percLvls.assign(3, vector<long double>(kolPercNeurons[0]));
    percWeights[0].assign(kolPercNeurons[0], vector<long double>(kolPercNeurons[1]));
    percWeights[1].assign(kolPercNeurons[1], vector<long double>(kolPercNeurons[2]));
    for (int i = 0; i < percWeights[0].size(); i++) {
        for (int j = 0; j < percWeights[0][0].size(); j++) {
            percWeights[0][i][j] = (long double)(rand() % 10001 - 5000) / 10000;
        }
    }
    for (int i = 0; i < percWeights[1].size(); i++) {
        for (int j = 0; j < percWeights[1][0].size(); j++) {
            percWeights[1][i][j] = (long double)(rand() % 10001 - 5000) / 10000;
        }
    }
}
 
int main(int argc, char** argv)
{
    mixImage();
    fillWeight();
    for (int epoch = 0; epoch < 10; epoch++) {
        mixImage();
        for (int num = 1; num < 11; num++) {
            LoadImg(num);
            percToNextLvl(percLvls[0], kolPercNeurons[0], percLvls[1], kolPercNeurons[1], percWeights[0]);
            percToNextLvl(percLvls[1], kolPercNeurons[1], percLvls[2], kolPercNeurons[2], percWeights[1]);
            percErrors[0].assign(kolPercNeurons[0], 0);
            percErrors[1].assign(kolPercNeurons[1], 0);
            percErrors[2].assign(kolPercNeurons[2], 0);
            for (int i = 0; i < kolPercNeurons[2]; i++) {
                percErrors[2][i] = trueAns[i][0] - percLvls[2][i];
                //percErrors[2][i + 1] = trueAns[i + 1][0] - percLvls[2][i + 1];
                //cout << perc[2][i] << " " << percErrors[2][i + 1] << " ";
            }
            learningPerc(percErrors, 2, kolPercNeurons[2], 0);
 
                cout << "Time: " << clock() << ", " << "Number: " << epoch << ";"<<orderImage[num-1]<<" " << endl;
                cout << "True:" << trueAns[0][0] << " " << trueAns[1][0] << " " << trueAns[2][0] << " " << trueAns[3][0] << " " << trueAns[4][0] << " " << trueAns[5][0] << " " << trueAns[6][0] << " "
                    << trueAns[7][0] << " " << trueAns[8][0] << " " << trueAns[9][0] << endl;
                cout << "Ans:" << percLvls[2][0] << " " << percLvls[2][1] << " " << percLvls[2][2] << " " << percLvls[2][3] << " " << percLvls[2][4] << " " << percLvls[2][5] << " " << percLvls[2][6] << " "
                    << percLvls[2][7] << " " << percLvls[2][8] << " " << percLvls[2][9] << endl;
        }
    }
    return 0;
}
Так же вот ссылка на папку с проектом где лежит выборка и все что нужно (почти)
Если нужно будет по обучать вот ссылка на все что нужно для того чтобы запустить в visual studio

https://yadi.sk/d/6MFYnQRR0BmZBQ

Папку opencv нужно поместить в папку c:\Project\opencv_3.4.6\

Папку RaspoznCifr нужно поместить c:\Пользователь\ваш пользователь\source\repos\

Папку opencv2 нужно поместить в c:\Пользователь\ваш пользователь\source\repos\RaspoznCifr\Ra spoznCifr\

И после запусти visual Studio там открыть файл или проект и там найти файл RaspoznCifr.sln
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
22.10.2019, 13:09
Ответы с готовыми решениями:

Связь между домами (Примерно 60-70 метров). Кабели отпадают, нужна беспроводная сеть.
Здравствуйте! У меня такая проблема, нужно реализовать сеть между домами, чтобы передавать интернет (Примерно 60-70 метров). Кабели...

В игре SAMP с промежутком примерно в 5-10 минут (по разному всегда) происходит залипание картинки и звука
Здравствуйте, формучане. Недавно собрал новый компьютер без видеокарты, на базе I5 4670, и поставил затычку GTS 450. Во всех играх все...

Начинает гудеть сабвуфер после примерно 4-5 часов работы
Система TDE 262. Система поключена к ЖК-телевизору. В работе около 5 лет и все это время была подключена к телевизору. Колонки исправны....

39
0 / 0 / 0
Регистрация: 15.06.2019
Сообщений: 33
25.10.2019, 19:36  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от danila_zaytcev Посмотреть сообщение
Суровый текст однако, разобраться в таком ахтунге будет не просто даже вузовскому преподу по цпп

Рекомендую для начала подсмотреть в https://www.codeproject.com/sc... ?aid=13582 это не зазорно, так все делают, но молчат об этом, ну или поищите мой код Mlp, который в пятеро превосходит NeuroPro, я уже не раз выкладывал, по просьбам страждущих, поищите.
А в чем суровость? Код как код.
0
821 / 580 / 75
Регистрация: 20.09.2014
Сообщений: 3,827
25.10.2019, 20:06
Цитата Сообщение от Vene Посмотреть сообщение
то есть получается так что изменения каждого веса колеблются после каждого обучения примерно в одном диапазоне, это около +-0.3.
Ааа, ну, блин, Вам, видимо, надо софтмакс реализовать, только и всего. Ваша нейросеть должна выдавать не один выход от 0 до 1, а 10 выходов от 0 до 1. Каждый выход - это вероятность для каждой из цифр. Потом берете максимальную вероятность из 10 - вот Вам и ответ. Это софтмакс.
1
3141 / 1742 / 274
Регистрация: 19.02.2010
Сообщений: 4,550
25.10.2019, 21:10
Цитата Сообщение от Mikhaylo Посмотреть сообщение
Ваша нейросеть должна выдавать не один выход от 0 до 1, а 10 выходов
Бред не несите:
Цитата Сообщение от Vene Посмотреть сообщение
const int kolPercNeurons[3] = { 784,196,10 };
...
vector<long double> neuralOut(kolPercNeurons[2]);//Результат работы нейронной сети
Где там один выход?


Хотя, это только начальные декларации, а что там потом будет далее в коде в счётчиках циклов - лень проверять.
1
0 / 0 / 0
Регистрация: 15.06.2019
Сообщений: 33
25.10.2019, 21:42  [ТС]
Цитата Сообщение от Mikhaylo Посмотреть сообщение
Ааа, ну, блин, Вам, видимо, надо софтмакс реализовать, только и всего. Ваша нейросеть должна выдавать не один выход от 0 до 1, а 10 выходов от 0 до 1. Каждый выход - это вероятность для каждой из цифр. Потом берете максимальную вероятность из 10 - вот Вам и ответ. Это софтмакс.
Понимаю, ну я не знаю где вы там увидели один выход). Ну да ладно спасибо что хоть посмотрели)

Добавлено через 43 секунды
VTsaregorodtsev, Mikhaylo, Только все равно не в этом ошибка заключается, а где не понятно
0
1472 / 827 / 140
Регистрация: 12.10.2013
Сообщений: 5,456
25.10.2019, 23:33
Цитата Сообщение от Vene Посмотреть сообщение
что это может быть?! Что делать?!
Упростить задачу и начать отладку.

Попробуйте обучить узнавать для начала одно и тоже число на одной картинке. Переобучить сеть. Так подтвердиться что она вообще учиться. Где графики loss\эпоха? Без графиков никак.Подбирайте скорость обучения\устройство сети и смотрите на поведения графика ошибки. Если не выучит одно число ищите алгоритмические ошибки в коде.
1
821 / 580 / 75
Регистрация: 20.09.2014
Сообщений: 3,827
26.10.2019, 03:30
В прямом распространении забыл обнулить succLvl. Кто тебе гарантирует выделение обнуленного массива? Никто.
1
1472 / 827 / 140
Регистрация: 12.10.2013
Сообщений: 5,456
26.10.2019, 11:59
Vene, ИМХО рано взялись за мнист подобное…
Насилуйте параболу. Два нейрона…
Простейшая нейронная сеть для аппроксимации параболы
0
47 / 15 / 1
Регистрация: 26.08.2017
Сообщений: 162
26.10.2019, 14:26
Цитата Сообщение от Vene Посмотреть сообщение
А в чем суровость? Код как код.
Excalibur921 вам верно советует, мнист вам пока рано, вы только запутаетесь, начните с XOR и 3 нейронов, в таком "кишки наружу" коде, будет хорошо работать, потом пригламурите, вот здесь самая эле ментарная логика Mlp
0
0 / 0 / 0
Регистрация: 15.06.2019
Сообщений: 33
26.10.2019, 22:56  [ТС]
Цитата Сообщение от Mikhaylo Посмотреть сообщение
В прямом распространении забыл обнулить succLvl. Кто тебе гарантирует выделение обнуленного массива? Никто.
Там передается ссылка на на percLvls который уже обнуляется.

Добавлено через 25 минут
Цитата Сообщение от Excalibur921 Посмотреть сообщение
Vene, ИМХО рано взялись за мнист подобное…
Насилуйте параболу. Два нейрона…
Простейшая нейронная сеть для аппроксимации параболы
я уже писал xor и простые нейронки на подобие, они все работаюdanila_zaytcev, Excalibur921,
0
0 / 0 / 0
Регистрация: 15.06.2019
Сообщений: 33
26.10.2019, 23:05  [ТС]
Цитата Сообщение от Excalibur921 Посмотреть сообщение
Упростить задачу и начать отладку.

Попробуйте обучить узнавать для начала одно и тоже число на одной картинке. Переобучить сеть. Так подтвердиться что она вообще учиться. Где графики loss\эпоха? Без графиков никак.Подбирайте скорость обучения\устройство сети и смотрите на поведения графика ошибки. Если не выучит одно число ищите алгоритмические ошибки в коде.
Вообщем получается что ошибка где-то в алгоритме... Потому что я сейчас попробовал пообучать на одной картинке и как получилось что почему-то она подтягивает все выходы, то есть все почему-то она считает все выходы нужно подтягивать в большую сторону. Вот картинка
0
1472 / 827 / 140
Регистрация: 12.10.2013
Сообщений: 5,456
26.10.2019, 23:27
И что это за каша в консоли? Как вы обучали простые нейросети без построения графиков? 0_0
Нужны графики ошибка\эпоха. Тут может плавать алгоритм обучения или теряться.
Попадались такие
Простейшая нейронная сеть для аппроксимации параболы
1
0 / 0 / 0
Регистрация: 15.06.2019
Сообщений: 33
26.10.2019, 23:38  [ТС]
Цитата Сообщение от Excalibur921 Посмотреть сообщение
И что это за каша в консоли? Как вы обучали простые нейросети без построения графиков? 0_0
Нужны графики ошибка\эпоха. Тут может плавать алгоритм обучения или теряться.
Попадались такие
Простейшая нейронная сеть для аппроксимации параболы
а как строить графики?) в с++
он не плавает он просто фигачит все выходы вверх, хотя увеличиваться должен только один а другие уменьшаться, а работает так что все увеличиваются.
0
47 / 15 / 1
Регистрация: 26.08.2017
Сообщений: 162
27.10.2019, 00:23
Цитата Сообщение от Vene Посмотреть сообщение
а как строить графики?) в с++
в QT как то так:

C++
1
2
3
4
5
6
7
    QLineSeries *series = new QLineSeries();
    for (int i = 0; i < 1000; ++i)series->append(i, sum+= 2.0*rand()/RAND_MAX - 1.0);
    QChart *chart = new QChart();
    chart->addSeries(series);
    QChartView *chartView = new QChartView();
    QtChartTest w;
    w.show();
1
821 / 580 / 75
Регистрация: 20.09.2014
Сообщений: 3,827
27.10.2019, 07:57
Цитата Сообщение от Vene Посмотреть сообщение
Там передается ссылка на на percLvls который уже обнуляется.
Ссылку увидел, но я не вижу нигде внешнего обнуления. Пусть даже percLvls.assign() обнуляет массив, но она делает это только один раз - в самом начале. А Вам надо после каждого прямого прохода обнулять массив.
1
1472 / 827 / 140
Регистрация: 12.10.2013
Сообщений: 5,456
27.10.2019, 10:25
Цитата Сообщение от Vene Посмотреть сообщение
как строить графики?)
Наверно самое простое в гугле “рисуем отрезок С++”
Да хоть ломанной постройте. Ну и пару палок осей…для наглядности.
Нужно увидеть тенденцию графика ошибки после обновления весов из например 100 изменений весов.

Как вы вообще что либо отлаживали и проверяли хоть одну НС без построения графиков ошибки?
1
0 / 0 / 0
Регистрация: 15.06.2019
Сообщений: 33
27.10.2019, 14:32  [ТС]
Цитата Сообщение от Vene Посмотреть сообщение
вот новый код,
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
#define _CRT_SECURE_NO_WARNINGS
//#include <opencv2/opencv.hpp> 
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include <iostream> 
#include <time.h>
#include <omp.h>
#include <math.h>
#include <conio.h>
#include <Windows.h>
#include <string>
#include <vector>
#include <fstream>
#include <conio.h>
using namespace std;
using namespace cv;
 
const int kolPercNeurons[3] = { 784,196,10 };
const int kolLearningImages = 3;//Кол-во обучающих изображений
const long double baseLearnPercRate = 0.1;
long double PercLearningRate = baseLearnPercRate;
vector<vector<vector<long double>>> percWeights(2);//Веса переходов между слоями в персептроне 
vector<long double> neuralOut(kolPercNeurons[2]);//Результат работы нейронной сети 
vector<vector<long double>> percLvls(3);//Персептрон
//vector<vector<vector<long double>>> percErrors;//Матрица ошибок персептрона 
vector<vector<long double>> percErrors(3, vector<long double>(kolPercNeurons[0]));//ошибки для данного слоя перцептрона
vector<vector<long double>> trueAns(kolPercNeurons[2], vector<long double>(1));
vector<vector<long double>> listImage(1);//Текущее изображение
vector<int> orderImage(kolLearningImages, 0);
vector<vector<vector<long double>>> deltas(2, vector<vector<long double>>(kolPercNeurons[0], vector<long double>(kolPercNeurons[1])));
vector<vector<long double>> deltasBias(2, vector<long double>(kolPercNeurons[1]));
//int bias[2] = { 1,1 };
long double weightBias[2][196];
 
 
void LoadImg(int Num) {
    stringstream ss;
    ss << orderImage[Num];
    //cout << orderImage[Num-1] << endl;
    string name = ss.str();
    string name1 = ss.str();
    name += ".png";
    name1 += ".txt";
    name = "tr2/" + name;
    name1 = "txt1/" + name1;
    //cout << name;
    Mat img = imread(name, CV_LOAD_IMAGE_GRAYSCALE);
    //resize(img, img, Size(480, 480), 0, 0, INTER_CUBIC);
    //cout << img.rows << " " << img.cols;
    for (int iRead = 0; iRead < img.rows; iRead++) {
        for (int jRead = 0; jRead < img.cols; jRead++) {
            percLvls[0][iRead+jRead] = img.at<uchar>(iRead, jRead) /255;
            //cout<< percLvls[0][jRead+iRead] << " ";
            // listStartImageBGR[1][iRead][jRead] = img.at<Vec3b>(iRead, jRead)[1];
        //  listStartImageBGR[2][iRead][jRead] = img.at<Vec3b>(iRead, jRead)[2];
            //cout << listStartImageBGR[0][iRead][jRead] << " " << listStartImageBGR[1][iRead][jRead] << " " << listStartImageBGR[2][iRead][jRead] << endl;
        }
    }
    //cout << 1;
    img.release();
    ifstream file(name1);
    for (int iRead = 0; iRead < kolPercNeurons[2]; iRead++) {
        file >> trueAns[iRead][0];
        //cout << trueAns[iRead][0];
        //trueAns[iRead][0] = trueAns[iRead][0] / 100;
       // cout << trueAns[iRead][0]<<endl;
    }
    //cout << endl;
    file.close();
};
 
long double activateFunction(long double x) {
    //return (x <= 0) ? ((long double)(rand() % 5) / 100) : x;
    return 1.0 - 2.0 / (exp(2 * x) + 1);
}
 
long double activateFunctionDX(long double x) {
    return 1 - x * x;
}
 
long double sigm(long double x) {
    return 1 / (1 + exp(-x));
    //return 1 / (1 + pow(2.71828, -x));
}
 
//long double sigmDX(long double x) {
//  return x * (1 - x);
//}
long double sigmDX(long double x) {
    //return x * (1 - x);
    return exp(-x) / ((1 + exp(-x)) * (1 + exp(-x)));
    /*if ((fabs(x - 1) < 1e-9) || (fabs(x) < 1e-9)) return 0.0;
    double res = x * (1.0 - x);
    return res;*/
}
void percToNextLvl(vector<long double>& curLvl, int curNeroAmt, vector<long double>& succLvl, int succNeroAmt, vector<vector<long double>>& curWeights, int numOfLayer)
{
    for (int i = 0; i < curNeroAmt; i++) {
#pragma omp parallel for schedule(guided, succNeroAmt / flows)
        for (int j = 0; j < succNeroAmt; j++)
            succLvl[j] += curLvl[i] * curWeights[i][j];
    }//тут
    for (int i = 0; i < succNeroAmt; i++) {
        succLvl[i] += 1. * weightBias[numOfLayer][i];
    }
#pragma omp parallel for schedule(guided, succNeroAmt / flows)
    for (int j = 0; j < succNeroAmt; j++)
        succLvl[j] = sigm(succLvl[j]);
 
}
 
void learningPerc(vector<vector<long double>>& Errors, int percLvl, int amtNerous, int curImage) {
        if (percLvl == 2) {
            for (int i = 0; i < amtNerous; i++) {
#pragma omp parallel for schedule(guided, kolPercNeurons[percLvl] / flows)
                Errors[percLvl][i] = sigmDX(percLvls[percLvl][i]) * Errors[percLvl][i];
                //cout << Errors[percLvl][i] << " ";
            }
        }
        else {
            for (int i = 0; i < amtNerous; i++) {
#pragma omp parallel for schedule(guided, kolPercNeurons[percLvl] / flows)
                for (int j = 0; j < kolPercNeurons[percLvl + 1]; j++) {
                    Errors[percLvl][i] += percWeights[percLvl][i][j] * Errors[percLvl + 1][j];
                }
                Errors[percLvl][i] *= sigmDX(percLvls[percLvl][i]);
                //cout << Errors[percLvl][i]<<" ";
            }
        }
        for (int i = 0; i < kolPercNeurons[percLvl - 1]; i++) {
#pragma omp parallel for schedule(guided, kolPercNeurons[percLvl] / flows)
            for (int j = 0; j < kolPercNeurons[percLvl]; j++) {
                deltas[percLvl - 1][i][j] = PercLearningRate * Errors[percLvl][j] * percLvls[percLvl - 1][i]; //= PercLearningRate * Errors[percLvl][j] * percLvls[percLvl - 1][i];
                //percWeights[percLvl - 1][i][j] += delta;
            }
        }
        for (int i = 0; i < kolPercNeurons[percLvl]; i++) {
            //long double delta = PercLearningRate * Errors[percLvl][i];
            deltasBias[percLvl - 1][i]=PercLearningRate* Errors[percLvl][i];
            //weightBias[percLvl - 1][i] += delta;
        }
 
        if (percLvl-1 == 0) {
            return;
        }
        else learningPerc(Errors, percLvl - 1, kolPercNeurons[percLvl - 1], curImage);
}
 
void mixImage() {
//  for (int i = 0; i < kolLearningImages; i++) {
//      orderImage[i] = i + 1;
//  }
//  for (int i = 0; i < kolLearningImages; i++) {
//      swap(orderImage[i], orderImage[rand() % kolLearningImages]);
    //}
        for (int i = 0; i < kolLearningImages; i++) {
            //cout << orderImage[i] << endl;
            orderImage[i] = i;
        }
}
 
void fillWeight() {
    percLvls.assign(3, vector<long double>(kolPercNeurons[0]));
    percWeights[0].assign(kolPercNeurons[0], vector<long double>(kolPercNeurons[1]));
    percWeights[1].assign(kolPercNeurons[1], vector<long double>(kolPercNeurons[2]));
    for (int i = 0; i < percWeights[0].size(); i++) {
        for (int j = 0; j < percWeights[0][0].size(); j++) {
            percWeights[0][i][j] = ((long double)(rand() % 10001-5000)) / 30000;
        }
    }
    for (int i = 0; i < percWeights[1].size(); i++) {
        for (int j = 0; j < percWeights[1][0].size(); j++) {
            percWeights[1][i][j] = ((long double)(rand() % 10001 - 5000)) / 30000;
        }
    }
    for (int i = 0; i < kolPercNeurons[1]; i++) {
        weightBias[0][i] = ((long double)(rand() % 10001 - 5000)) / 30000;
    }
    for (int i = 0; i < kolPercNeurons[2]; i++) {
        weightBias[1][i] = ((long double)(rand() % 10001 - 5000)) / 30000;
    }
}
 
int main(int argc, char** argv)
{
    srand(time(0));
    mixImage();
    fillWeight();
    for (int epoch = 0; epoch < 50; epoch++) {
        mixImage();
        for (int num = 0; num < 3; num++) {
            LoadImg(num);
            for (int i = 0; i < 196; i++) {
                percLvls[1][i] = 0;
            }
            for (int i = 0; i < 10; i++) {
                percLvls[2][i] = 0;
            }
            percToNextLvl(percLvls[0], kolPercNeurons[0], percLvls[1], kolPercNeurons[1], percWeights[0], 0);
            percToNextLvl(percLvls[1], kolPercNeurons[1], percLvls[2], kolPercNeurons[2], percWeights[1], 1);
            percErrors[0].assign(kolPercNeurons[0], 0);
            percErrors[1].assign(kolPercNeurons[1], 0);
            percErrors[2].assign(kolPercNeurons[2], 0);
            for (int i = 0; i < kolPercNeurons[2]; i++) {
                percErrors[2][i] = trueAns[i][0] - percLvls[2][i];
                //percErrors[2][i + 1] = trueAns[i + 1][0] - percLvls[2][i + 1];
                //cout << perc[2][i] << " " << percErrors[2][i + 1] << " ";
            }
            learningPerc(percErrors, 2, kolPercNeurons[2], 0);
            for (int i = 0; i < kolPercNeurons[0]; i++) {
#pragma omp parallel for schedule(guided, kolPercNeurons[1] / flows)
                for (int j = 0; j < kolPercNeurons[1]; j++) {
                    percWeights[0][i][j] += deltas[0][i][j];
                }
            }
            for (int i = 0; i < kolPercNeurons[1]; i++) {
#pragma omp parallel for schedule(guided, kolPercNeurons[2] / flows)
                for (int j = 0; j < kolPercNeurons[2]; j++) {
                    percWeights[1][i][j] += deltas[1][i][j];
                }
            }
            for (int i = 0; i < kolPercNeurons[2]; i++) weightBias[1][i] += deltasBias[1][i];  for (int i = 0; i < kolPercNeurons[1]; i++) weightBias[0][i] += deltasBias[0][i];
 
            cout << "Time: " << clock() << ", " << "Number: " << epoch << ";"<<orderImage[num]<<" " << endl;
            cout << "True:" << trueAns[0][0] << " " << trueAns[1][0] << " " << trueAns[2][0] << endl;//" " << trueAns[3][0] << " " << trueAns[4][0] << " " << trueAns[5][0] << " " << trueAns[6][0] << " "
            //  << trueAns[7][0] << " " << trueAns[8][0] << " " << trueAns[9][0] << endl;
            cout << "Ans:" << percLvls[2][0] << " " << percLvls[2][1] << " " << percLvls[2][2] << endl;//" " << percLvls[2][3] << " " << percLvls[2][4] << " " << percLvls[2][5] << " " << percLvls[2][6] << " "
            //  << percLvls[2][7] << " " << percLvls[2][8] << " " << percLvls[2][9] << endl;
        }
    }
 
    cout << endl; cout << endl; cout << endl;
 
    LoadImg(0);
    percToNextLvl(percLvls[0], kolPercNeurons[0], percLvls[1], kolPercNeurons[1], percWeights[0], 0);
    percToNextLvl(percLvls[1], kolPercNeurons[1], percLvls[2], kolPercNeurons[2], percWeights[1], 1);
    cout << "True:" << trueAns[0][0] << " " << trueAns[1][0] << " " << trueAns[2][0] << endl;//" " << trueAns[3][0] << " " << trueAns[4][0] << " " << trueAns[5][0] << " " << trueAns[6][0] << " "
                //  << trueAns[7][0] << " " << trueAns[8][0] << " " << trueAns[9][0] << endl;
    cout << "Ans:" << percLvls[2][0] << " " << percLvls[2][1] << " " << percLvls[2][2] << endl;//" " << percLvls[2][3] << " " << percLvls[2][4] << " " << percLvls[2][5] << " " << percLvls[2][6] << " "
    //  << percLvls[2][7] << " " << percLvls[2][8] << " " << percLvls[2][9] << endl;
    LoadImg(1);
    percToNextLvl(percLvls[0], kolPercNeurons[0], percLvls[1], kolPercNeurons[1], percWeights[0], 0);
    percToNextLvl(percLvls[1], kolPercNeurons[1], percLvls[2], kolPercNeurons[2], percWeights[1], 1);
    cout << "True:" << trueAns[0][0] << " " << trueAns[1][0] << " " << trueAns[2][0] << endl;//" " << trueAns[3][0] << " " << trueAns[4][0] << " " << trueAns[5][0] << " " << trueAns[6][0] << " "
                //  << trueAns[7][0] << " " << trueAns[8][0] << " " << trueAns[9][0] << endl;
    cout << "Ans:" << percLvls[2][0] << " " << percLvls[2][1] << " " << percLvls[2][2] << endl; //" " << percLvls[2][3] << " " << percLvls[2][4] << " " << percLvls[2][5] << " " << percLvls[2][6] << " "
    //  << percLvls[2][7] << " " << percLvls[2][8] << " " << percLvls[2][9] << endl;
    return 0;
}
Добавлено через 57 секунд
Mikhaylo, VTsaregorodtsev, помогайте без вас найти ошибку не получается!

Добавлено через 31 минуту
то есть получается так что изменения каждого веса колеблются после каждого обучения примерно в одном диапазоне, это около +-0.3. Я не понимаю с чем это связанно. Ну вот если кто-то вдруг не понимает в чем ошибка: скажем первый правильный ответ 1 подтягивает этот вес на +0.3 а остальные занижает -0.3, следующие обучение второй выход правильный она подтягивает этот вес на +0.3 а все другие занижает на -0.3, и следующий правильный выход третий она поднимает его на +0.3 а все остальные занижает на -0.3, и получается что после одной эпохи веса остаются примерно одними и тежеми ну кроме тех что обучались последними. Как это пофиксить, что с этим делать?Mikhaylo, VTsaregorodtsev, ?
Извините, надо было код в топике обновить, а я просто сообщением отправил

Добавлено через 35 секунд
Цитата Сообщение от Mikhaylo Посмотреть сообщение
Ссылку увидел, но я не вижу нигде внешнего обнуления. Пусть даже percLvls.assign() обнуляет массив, но она делает это только один раз - в самом начале. А Вам надо после каждого прямого прохода обнулять массив.
Вот вверху новый код

Добавлено через 2 минуты
Excalibur921, Mikhaylo, danila_zaytcev, я нашел не большую ошибку которая возможно сильно влияла на обучение, попробую поправить если не получиться то к вечеру скину новый код и построю графики.

Добавлено через 13 минут
Цитата Сообщение от Excalibur921 Посмотреть сообщение
Упростить задачу и начать отладку.

Попробуйте обучить узнавать для начала одно и тоже число на одной картинке. Переобучить сеть. Так подтвердиться что она вообще учиться. Где графики loss\эпоха? Без графиков никак.Подбирайте скорость обучения\устройство сети и смотрите на поведения графика ошибки. Если не выучит одно число ищите алгоритмические ошибки в коде.
В общем, я протестировал пока не убрав ошибку которую я нашел, и получается так что на одной картинке она обучается прекрасно, примерно за 8 картинок она обучилась до 98% правильных ответов.

Добавлено через 7 минут
Excalibur921, danila_zaytcev, Mikhaylo, а вот трем картинкам она не обучается вовсе, три первых выхода получается примерно равны и отличить правильный от не правильного не возможно, а что будет с увеличением кол-во картинок я думаю и так понятно. И вопрос где что как?
0
821 / 580 / 75
Регистрация: 20.09.2014
Сообщений: 3,827
27.10.2019, 17:39
Перед тем как многократно использовать операцию приращения "+=" надо сделать, чтобы в переменной изначально был 0.
1
0 / 0 / 0
Регистрация: 15.06.2019
Сообщений: 33
27.10.2019, 18:37  [ТС]
Mikhaylo, Excalibur921, danila_zaytcev, VTsaregorodtsev, господа всем спасибо огромное что не кинули одного на произвол. Все заработало, ошибка была наиглупейшая(не правильно записывал в вход нейросети)
0
1472 / 827 / 140
Регистрация: 12.10.2013
Сообщений: 5,456
28.10.2019, 21:12
Цитата Сообщение от Vene Посмотреть сообщение
Все заработало
Я думал график ошибки позволяет:
1) понять что обучение вообще идет
2)подбирать параметры для наискорейшего обучения и вообще его запуска
3)контролировать обучение визуально
4) смотреть нет ли переобучения.
5)график ошибки единственная инфа которую можно малой кровью вытянуть из этой многомерной нелинейной дряни называемой нейросеть…

Но вам все это не нужно и работает…вот как это так… Глянуть пару скаляров в консольке и норм.
0
3141 / 1742 / 274
Регистрация: 19.02.2010
Сообщений: 4,550
28.10.2019, 22:13
Цитата Сообщение от Excalibur921 Посмотреть сообщение
1) понять что обучение вообще идет
2)подбирать параметры для наискорейшего обучения и вообще его запуска
3)контролировать обучение визуально
Данные проблемы возникают только при пользовании SGD (в т.ч. и в минибатч-режиме) и его адаптивными вариантами (AdaGrad, RMSrop, Adam, AdaMax,..) - т.е. там, где не гарантируется, что от эпохи к эпохе будет идти снижение суммарной (по обуч.выборке) ошибки обучения, и/или где какие-то параметры надо выбирать руками.

При батч-обучении с добавочным алгоритмом оптимизации шага вдоль направления градиента - график не обязателен. Ибо обучение гарантированно идёт и гарантированно сходится. Проблемы ручной настройки величины шага тоже нет (да и других параметров обучения нет - только лишь размеры/структура сети). А если взять вместо суммарного градиента более эффективное направление спуска - то улучшится и скорость сходимости обучения. В общем, теория градиентной оптимизации тут рулит и позволяет добиться полной автоматизации.
Я себе чуть больше 20 лет назад такое делал - и обходился без графиков Если значение ошибки на новой эпохе выводится поверх прежнего (что можно сделать и в консольке - CR без LF) - то прогресс обучения виден без графиков (ибо просто видно, как от эпохи к эпохе суммарная ошибка уменьшается во второй-третьей значащей цифре).

Правда, за применение полноразмерного батч-обучения с автоматизирующими фишками - приходится расплачиваться повышенной вероятностью переобучения (набор алгоритмов выжимает из нейронки на обуч.выборке всё, и если не при обучении не применяем регуляризацию - то есть риск запомнить много шума и очепяток в данных). Т.е. единственное, что Вы правильно написали - это
Цитата Сообщение от Excalibur921 Посмотреть сообщение
смотреть нет ли переобучения.
Ибо по поводу же единственности/неединственности вытаскиваемой из сетки инфы - таки есть (вопрос этот поднимался недавно в теме tur9, ЕМНИП) индюкаторы, основанные на весах и/или на производных в нейронке, которые дают дополнительную/иную информацию. В т.ч. они позволяют выбирать более предпочтительную (из нескольких обученных) нейронку в случае отсутствия тестовой выборки.

В общем, график ошибок обучения/обобщения - просто инструмент. Иногда - необязательный И понятно, что он не все баги в проге позволит выловить (прога может оставаться с ошибками - но обучение может как-то идти, и график покажется субъективно приемлемым для самоуспокоения насчёт якобы правильности проги).
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
28.10.2019, 22:13

После примерно 1-2 суток безглючной работы, ASP валится.
После примерно 1-2 суток безглючной работы, ASP валится. Выглядит это как ошибка (ф-ция не определена) при первом встретившимся вызове...

После переустановки Windows XP картинка уменьшилась примерно на четверть
Похожая ситуация.После переустановки Windows XP картинка уменьшилась примерно на четверть... Диспетчер устройств кажет,что отсутствует...

Как сделать чтобы цикл while выполнялся один раз и выводил примерно такой текст из формы?
как сделать чтобы цикл while выполнялся один раз и выводил примерно такой текст из формы тест: 1111 тест: 2222 тест: 3333 тест:...

Выключается монитор примерно через 10 минут после начала игры
(так просходит как с &quot;GTA 5&quot;, так и с &quot;Call of Duty Modern Warfare 2&quot;, раньше эти игры шли прекрасно, совсем не тормозили) При вылете...

После подключения интернета, примерно в течении 3-5 мин. перестает работать
Ув. Программисты, такая проблема: После подключения интернета, примерно в течении 3-5 мин. перестает работать!!! то-есть: грузить...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
GitHub Copilot в JetBrains: модель по умолчанию, Fix и контроль MCP
and_y87 12.10.2026
10 октября 2026 года GitHub обновил Copilot для JetBrains: добавил настройки стартовой модели, исправления из диагностики и управление автозапуском MCP. Поддержка IDE 2025. 1 прекращена — требуется. . .
GitHub Copilot в JetBrains: модель по умолчанию, Fix и контроль MCP
and_y87 12.10.2026
10 октября 2026 года GitHub обновил Copilot для JetBrains: добавил настройки стартовой модели, исправления из диагностики и управление автозапуском MCP. Поддержка IDE 2025. 1 прекращена — требуется. . .
День 5 из 28: Codex подсказывает следующий запрос
and_y87 12.10.2026
9 октября 2026 года OpenAI запустила бету Composer predictions — подсказок следующего сообщения в текущем диалоге Codex. Это помощь с формулировкой запроса, а не автоматическое продолжение задачи. . . .
Запустил конкурс "тем и промптов для текстовых квестов созданных почти чисто ИИ"
Adler 06.10.2026
Всем привет! За последние три-четыре дня я создал более 16 текстовых квестовых игр используя преимущественно по одному запросу к ИИ на игру. Мне так понравилось смотреть все ветки/ сцены во всех. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru