Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.85/13: Рейтинг темы: голосов - 13, средняя оценка - 4.85
novocain
0 / 0 / 0
Регистрация: 09.01.2013
Сообщений: 19
1

Нейронные сети обратного распространения

31.10.2014, 00:36. Просмотров 2437. Ответов 1
Метки нет (Все метки)

Здравствуйте. Пытаюсь обучить сеть таблице умножения. Обучает до 1*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
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
class neur{
public:
    double input_v[5];
    int in_v_size;
    double input_w[5];
    double act_f;
    double pr_act_f;
    double summ;
    double err_n;
 
    neur(int Size_in_v){
        summ=0;
        err_n=0;
        pr_act_f=0;
        act_f=0;
        in_v_size=Size_in_v;
        /*double **input_v=new double*[Size_in_v];
        double **input_w=new double*[Size_in_v];
        for(int i=0;i<Size_in_v;i++){
        input_v[i]=new double[Size_in_v];
        input_w[i]=new double[Size_in_v];
        }*/
    }
    neur(){
        summ=0;
        err_n=0;
        pr_act_f=0;
        act_f=0;
        in_v_size=0;
    }
    ~neur(){};
    /*  ~neur(){
    for(int i=0;i<in_v_size;i++){
    delete[](input_v[i]);
    delete[](input_w[i]);
    }
    delete[](input_v);
    delete[](input_w);
    }*/
    double Sum_n(){
        summ=0;
        for(int i=0;i<in_v_size;i++){
            summ=summ+(input_v[i])*(input_w[i]);
        }
        return summ;
    }
    double Activ_f(){
        act_f=1./(1+exp((-1)*summ));
        return act_f;
    }
 
    void pr_activ_f(){
        pr_act_f=act_f*(1.-act_f);
        //pr_act_f =pow(E, -summ)/pow( ( 1 + pow(E, -summ)), 2);
    }
 
    void err_count_y(double z){
        err_n=z-summ;
    }
 
 
    void weight_correct(double h){
        for(int i=0;i<in_v_size;i++){
            input_w[i]=(input_w[i])+h*(err_n)*(pr_act_f)*(input_v[i]);
        }
    }
    /*  void def_to_dinamic(int Size_in_v){
    in_v_size=Size_in_v;
    double **input_v=new double*[Size_in_v];
    double **input_w=new double*[Size_in_v];
    for(int i=0;i<Size_in_v;i++){
    input_v[i]=new double[Size_in_v];
    input_w[i]=new double[Size_in_v];
    }
    }*/
};
 
neur neur_h[5];
 
void err_count(neur W){
    for(int i=0;i<5;i++){
        neur_h[i].err_n=W.err_n*(W.input_w[i]);
    }
}
 
 
int _tmain(int argc, _TCHAR* argv[])
{
    srand(time(NULL));
    double **mass = new double* [9];
    for (int count = 0; count < 9; count++)
        mass[count] = new double [9]; 
    int k=0;
    for(int i=0;i<9;i++)
        for(int j=0;j<9;j++)
            mass[i][j]=(i+1)*(j+1);
 
    for (int i=0;i<5;i++){
        neur_h[i]=*new neur(2);
for(int j=0;j<2;j++){
            neur_h[i].input_w[j]=(rand()%100)/(100*1.0);
    //neur_h[i].input_w[j]=1;
        }
    }
 
    neur Y=*new neur(5);
 
    for(int i=0;i<5;i++){
        Y.input_w[i]=(rand()%100)/(100*1.0);
        //Y.input_w[i]=1;
    }
    double **mass_r = new double* [9];
    for (int count = 0; count < 9; count++)
        mass_r[count] = new double [9]; 
    for(int i=0;i<9;i++)
        for(int j=0;j<9;j++)
            mass_r[i][j]=0;
    double step=0.1;
 
    for(int i=0;i<9;i++){
        for(int j=0;j<9;j++){
 
            while (1){
                
                for (int k = 0; k < 5; k++)
                {
                    neur_h[k].input_v[0]=i+1;
                    neur_h[k].input_v[1]=j+1;
                    neur_h[k].Sum_n();
                    neur_h[k].Activ_f();
                    neur_h[k].pr_activ_f();
                    Y.input_v[k]=neur_h[k].pr_act_f;
                }
                Y.Sum_n();
                Y.err_count_y(mass[i][j]);
                err_count(Y);
                Y.weight_correct(step);
                for (int q = 0; q < 5; q++)
                {
                    neur_h[q].weight_correct(step);
                }
                Y.weight_correct(step);
 
                for (int k = 0; k < 5; k++)
                {
                    neur_h[k].Sum_n();
                    neur_h[k].Activ_f();
                    neur_h[k].pr_activ_f();
                    Y.input_v[k]=neur_h[k].act_f;
                }
                Y.Sum_n();
                //if((step<1)||(step>0))
                    //step=0.1;
                if (Y.summ>mass[i][j])
                {
                    step=step-0.1;
                }
                if (Y.summ<mass[i][j])
                {
                    step=step+0.1;
                }
                getchar();
                Y.err_count_y(mass[i][j]);
                cout<<i+1<<"*"<<j+1<<"="<<Y.summ<<" "<<Y.err_n<<" "<<mass[i][j]<<" "<<Y.summ<<" "<<step<<endl;
                if(abs(Y.err_n)<0.1){
                //cout<<i+1<<"*"<<j+1<<"="<<Y.summ<<" "<<Y.err_n<<" "<<mass[i][j]<<" "<<Y.summ<<" "<<step<<endl;
                    mass_r[i][j]=Y.summ;
                    getchar();
                    step=0.1;
                    break;
                }
                
            
            }   
        }
    }
    system("pause");
    return 0;
}
Добавлено через 35 секунд
getchar ставил для отслеживания хода обучения

Добавлено через 7 минут
в сети 2 входа, 1 скрытый слой из 5 нейронов

Добавлено через 5 часов 51 минуту
Ошибку нашел и исправил. Все обучает, но долго, как можно ускорить процесс обучения?

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
// Bin_Test.cpp : Defines the entry point for the console application.
// 
#include <math.h>
#include "stdafx.h"
#include <windows.h>
#include <cstdlib> 
#include <ctime>
#include <stdio.h>
#include <tchar.h>
#include <iostream>
#include <conio.h>
#define E 2.7182818284590452354
 
using namespace std;
class neur{
public:
    double input_v[5];
    int in_v_size;
    double input_w[5];
    double input_w_old;
    double act_f;
    double pr_act_f;
    double summ;
    double err_n;
 
    neur(int Size_in_v){
        summ=0;
        err_n=0;
        pr_act_f=0;
        act_f=0;
        input_w_old=0;
        in_v_size=Size_in_v;
        /*double **input_v=new double*[Size_in_v];
        double **input_w=new double*[Size_in_v];
        for(int i=0;i<Size_in_v;i++){
        input_v[i]=new double[Size_in_v];
        input_w[i]=new double[Size_in_v];
        }*/
    }
    neur(){
        summ=0;
        err_n=0;
        pr_act_f=0;
        act_f=0;
        in_v_size=0;
        input_w_old=0;
    }
    ~neur(){};
    /*  ~neur(){
    for(int i=0;i<in_v_size;i++){
    delete[](input_v[i]);
    delete[](input_w[i]);
    }
    delete[](input_v);
    delete[](input_w);
    }*/
    double Sum_n(){
        summ=0;
        for(int i=0;i<in_v_size;i++){
            summ=summ+(input_v[i])*(input_w[i]);
        }
        return summ;
    }
    double Activ_f(){
        act_f=1./(1+exp((-1)*summ));
        return act_f;
    }
 
    void pr_activ_f(){
        pr_act_f=act_f*(1.-act_f);
        //pr_act_f =pow(E, -summ)/pow( ( 1 + pow(E, -summ)), 2);
    }
 
    double err_count_y(double z){
        err_n=(z-summ)*1.0;
        return err_n;
    }
 
 
    void weight_correct(double h){
        for(int i=0;i<in_v_size;i++){
            input_w[i]=(input_w[i])+h*(err_n)*(pr_act_f)*(input_v[i]);
        }
    }
    void close_enough(double h){
        input_w_old=0;
        for(int i=0;i<in_v_size;i++){
            input_w_old=pow(input_w[i],2)+input_w_old;
        }
        input_w_old=sqrt(input_w_old);
    }
    /*  void def_to_dinamic(int Size_in_v){
    in_v_size=Size_in_v;
    double **input_v=new double*[Size_in_v];
    double **input_w=new double*[Size_in_v];
    for(int i=0;i<Size_in_v;i++){
    input_v[i]=new double[Size_in_v];
    input_w[i]=new double[Size_in_v];
    }
    }*/
};
 
neur neur_h[5];
neur Y;
 
void err_count(neur W){
    for(int i=0;i<5;i++){
        neur_h[i].err_n=W.err_n*(W.input_w[i]);
    }
}
 
double random(double min,double max){
    return (double)(rand())/RAND_MAX*(max-min)+min;
}
 
int _tmain(int argc, _TCHAR* argv[])
{
    float b=0.7*pow(5,1/2);
    srand((unsigned int)time(NULL));
    double **mass = new double* [9];
    for (int count = 0; count < 9; count++)
        mass[count] = new double [9]; 
    int k=0;
    for(int i=0;i<9;i++)
        for(int j=0;j<9;j++)
            mass[i][j]=(i+1)*(j+1);
 
    for (int i=0;i<5;i++){
        neur_h[i]=*new neur(2);
        for(int j=0;j<2;j++){
        neur_h[i].input_w[j]=(rand()%100)/(100*1.0)-0.5;
        }
    }
 
    Y=*new neur(5);
 
    for(int i=0;i<5;i++){
        Y.input_w[i]=(rand()%100)/(100*1.0)-0.5;
    }
    double **mass_r = new double* [9];
    for (int count = 0; count < 9; count++)
        mass_r[count] = new double [9]; 
    for(int i=0;i<9;i++)
        for(int j=0;j<9;j++)
            mass_r[i][j]=0;
    double step=1;
 
    for(int i=0;i<9;i++){
        for(int j=0;j<9;j++){
            int sch=0;
            while (1){
 
                for (int k = 0; k < 5; k++)
                {
                    if (sch==0){
                        neur_h[k].input_v[0]=i+1;
                        neur_h[k].input_v[1]=j+1;
                //      for (int s = 0; s  < 2; s ++)
            //          {
 
            //              neur_h[k].input_w[s]=(b*neur_h[k].input_w[s])/neur_h[k].input_w_old;
            //          }
                        
                    }
 
                    neur_h[k].Sum_n();
                    neur_h[k].Activ_f();
                    neur_h[k].pr_activ_f();
                    Y.Activ_f();
                    Y.pr_activ_f();
                    Y.input_v[k]=neur_h[k].act_f;
                }
 
                Y.Sum_n();
 
                Y.err_count_y(mass[i][j]);
                err_count(Y);
                    Y.weight_correct(step);
 
                for (int q = 0; q < 5; q++)
                {
                    neur_h[q].weight_correct(step);
                }
                //Y.weight_correct(step);
 
                for (int k = 0; k < 5; k++)
                {
                    neur_h[k].Sum_n();
                    neur_h[k].Activ_f();
                    neur_h[k].pr_activ_f();
                    Y.input_v[k]=neur_h[k].act_f;
                    //  cout<<"Second Input r_weight_"<<k<<" "<<Y.input_w[k]<<" "<<Y.input_v[k]<<endl;
                }
                Y.Sum_n();
                //if((step<1)||(step>0))
                //step=0.1;
                if (Y.summ>mass[i][j])
                {
                step=step-0.1;
                }
                if (Y.summ<mass[i][j])
                {
                step=step+0.1;
                }
 
            //  getchar();
                Y.err_count_y(mass[i][j]);
                cout<<i+1<<"*"<<j+1<<"="<<Y.summ<<" "<<Y.err_n<<" "<<mass[i][j]<<" "<<Y.summ<<" "<<step<<endl;
            //  for (int i = 0; i < 5; i++)
            //  {
                //  for (int j = 0; j < 2; j++)
                //  {
                //      cout<<" Input neur_"<<i<<" Input weight_"<<j<<" "<<neur_h[i].input_w[j]<<endl;
                //  }
 
                //  cout<<" Input r_weight_"<<i<<" "<<Y.input_w[i];
                //  cout<<" Input r_value_"<<i<<" "<<Y.input_v[i];
                //  cout<<endl;
            //  }
                if(abs(Y.err_n)<0.1){
                    //cout<<i+1<<"*"<<j+1<<"="<<Y.summ<<" "<<Y.err_n<<" "<<mass[i][j]<<" "<<Y.summ<<" "<<step<<endl;
                    mass_r[i][j]=Y.summ;
                    //getchar();
                    step=1;
                    sch=0;
                for (int i = 0; i < 5; i++)
                    {
                        for (int j = 0; j < 2; j++)
                        {
                            neur_h[i].input_w[j]=(rand()%100)/(100*1.0)-0.5;
                        }
 
                        Y.input_w[i]=(rand()%100)/(100*1.0)-0.5;
                }
 
                    break;
                }
 
 
            }   
        }
    }
    system("pause");
    return 0;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
31.10.2014, 00:36
Ответы с готовыми решениями:

Алгоритм обратного распространения ошибки. Нейронные сети
Прошу помощи с реализацией алгоритма обратного распространения ошибки. Написал...

Метод обратного распространения ошибки
Здравствуйте! Решил попробовать свои силы по программированию нейронных сетей и...

Метод обратного распространения ошибки
Всем доброго времени суток. Прошу не удалять тему, она больше к теории...

Нейронные сети (адаптивные сети)
нужен исходник 3д или 2д адаптивной сетки для небольшого использования в своей...

Нейронные сети
Добрый вечер! Можете подсказать где есть много примеров по нейронным сетям...?...

1
VTsaregorodtsev
534 / 489 / 68
Регистрация: 19.02.2010
Сообщений: 1,786
12.11.2014, 22:32 2
Цитата Сообщение от novocain Посмотреть сообщение
Все обучает, но долго, как можно ускорить процесс обучения?
Оптимизация кода, переход к аппроксимации нелинейности (exp считается относительно долго), переход к симметричной относительно нуля нелинейности (т.е. к "центрированной), поиграть с величиной шага обучения,..
Лень полностью смотреть код - может, и нормировка входных данных тоже неоптимальна (если данные не центрированы получаются).

Ну и задача - относительно бредовая. Для таблицы умножения, если уж так её хочется, надо брать квадратичный=полиномиальный сумматор (описан в числе "стандартных" для искусственных нейросетей в двухтомном талмуде PDP 1986г - в том самом, где был и метод обратного распространения опубликован).
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.11.2014, 22:32

Нейронные сети
Добрый вечер, товарищи. Прошу у вас помощи по нейронным сетям. Есть...

Нейронные сети
Недавно открыл для себя тему нейросетей, и хотел бы спросить ресурс где бы я...

Книги по С++ и нейронные сети
Уважаемые форумчане, может кто посоветовать книги (или статьи в интернете) по...


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

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

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