С Новым годом! Форум программистов, компьютерный форум, киберфорум
Искусственный интеллект
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.90/21: Рейтинг темы: голосов - 21, средняя оценка - 4.90
11 / 9 / 3
Регистрация: 16.06.2019
Сообщений: 57
1

Простая нейросеть XOR

30.12.2019, 17:39. Показов 3976. Ответов 12

Author24 — интернет-сервис помощи студентам
Всем доброго времени суток! Недавно начал затрагивать тему нейронных сетей и попробовал реализовать сетку, которая бы решала задачу исключающего или. Что-то думал, решал, составлял, в итоге захардкодил и закостылил ниже представленный листинг, который, к сожалению, не робит (. Может, кто-то поможет подскажет?
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
#include <iostream>
#include <ctime>
#include <cmath>
#include <vector>
 
class cXOR
{
public:
    cXOR()
    {
        /* Начальное рандомное заполнение весов между слоями */
        srand(time(NULL));
        for(short i = 0; i < inputCount; ++i)
            for(short j = 0; j < hiddenCount; ++j)
            {
                weightsInputHidden[i][j] =
                        static_cast<double>(((rand() % 100) / 100.0) - 0.5);
            }
        for(short i = 0; i < hiddenCount; ++i)
            for(short j = 0; j < outputCount; ++j)
            {
                weightsHiddenOutput[i][j] =
                        static_cast<double>(((rand() % 100) / 100.0) - 0.5);
            }
    }
 
    short query(short x1, short x2)
    {
        /* Входные сигналы * вес */
        double inputSignIH[hiddenCount];
        /* Заполнение входных сигналов */
        for(short i = 0; i < hiddenCount; ++i)
        {
            inputSignIH[i] = x1 * weightsInputHidden[0][i] +
                    x2 * weightsInputHidden[1][i];
        }
        /* Выходные сигналы скрытого слоя */
        double outputSignIH[hiddenCount];
        for(short i = 0; i < hiddenCount; ++i)
        {
            /* Пропускаем результат произведения через функцию активации */
            outputSignIH[i] = sigma(inputSignIH[i]);
        }
 
        /* Входные сигналы в выходной слой */
        double inputSignHO[hiddenCount];
        /* Умножаем на веса */
        for(short i = 0; i < outputCount; ++i)
        {
            inputSignHO[i] = outputSignIH[0] * weightsHiddenOutput[0][i] +
                    outputSignIH[1] * weightsHiddenOutput[1][i];
        }
        /* Если после активации >= 0.5 возвращаем 1
         * иначе 0 */
        if(sigma(inputSignHO[0]) >= 0.5)
        {
            return 1;
        }
        else
        {
            return 0;
        }
    }
 
    /* Тренировка нейросети
     * 1 - ошибка
     * 0 - успех */
    bool train(unsigned int size, std::vector<int> x1, std::vector<int> x2,
            std::vector<int> answer, double learningrate)
    {
        if((size != x1.size()) || (size != x2.size()))
        {
            return 1;
        }
        else
        {
            /* Прогнать 999999 раз */
            for(long count = 0; count < 999999; ++count)
            /* Повторить столько раз, сколько различных
             * комплектов значений передано */
            for(size_t i = 0; i < size; ++i)
            {
                /* Если опрос неуспешен, то учим */
                if((query(x1[i], x2[i]) != answer[i]))
                {
                    /* Входные сигналы * вес */
                    double inputSignIH[hiddenCount];
                    /* Заполнение входных сигналов */
                    for(short inp = 0; inp < hiddenCount; ++inp)
                    {
                        inputSignIH[inp] = x1[inp] * weightsInputHidden[0][inp] +
                                x2[inp] * weightsInputHidden[1][inp];
                    }
                    /* Выходные сигналы скрытого слоя */
                    double outputSignIH[hiddenCount];
                    for(short outh = 0; outh < hiddenCount; ++outh)
                    {
                        /* Пропускаем результат произведения через функцию активации */
                        outputSignIH[outh] = sigma(inputSignIH[outh]);
                    }
 
                    /* Входные сигналы в выходной слой */
                    double inputSignHO[hiddenCount];
                    /* Умножаем на веса */
                    for(short inpo = 0; inpo < outputCount; ++inpo)
                    {
                        inputSignHO[inpo] = outputSignIH[0] * weightsHiddenOutput[0][inpo] +
                                outputSignIH[1] * weightsHiddenOutput[1][inpo];
                    }
 
                    ////////////////////////////////////////////////////////////////////
 
                    /* Настройка весов м/ду скрытым и выходными слоями */
                    for(int ho = 0; ho < hiddenCount; ++ho)
                    {
                        weightsHiddenOutput[ho][0] += -1 * -learningrate * sigma(inputSignHO[ho]) *
                                (1 - sigma(inputSignHO[ho])) * weightsHiddenOutput[ho][0];
                    }
                    /* Настройка весов м/ду входным и скрытым слоями */
                    for(int ho = 0; ho < hiddenCount; ++ho)
                        for(int io = 0; io < inputCount; ++io)
                        {
                            int temp = 0;
                            io == 0 ? temp = x1[io] : temp = x2[io];
                            weightsInputHidden[ho][io] += -1 * -learningrate * sigma(temp)
                                        * (1 - sigma(temp) * weightsInputHidden[ho][io]);
                        }
                }
                /* Иначе перейти к следующему комплекту для тренировки */
                else
                {
                    continue;
                }
            }
            return 0;
        }
    }
 
    /* Вывести на экран значения весов */
    void print()
    {
        std::cout << "IH:\n";
        for(int i = 0; i < inputCount; ++i)
        {
            for(int j = 0; j < hiddenCount; ++j)
            {
                std::cout << weightsInputHidden[i][j] << " ";
            }
            std::cout << std::endl;
        }
        std::cout << std::endl << "HO:\n";
        for(int i = 0; i < hiddenCount; ++i)
        {
            for(int j = 0; j < outputCount; ++j)
            {
                std::cout << weightsHiddenOutput[i][j] << " ";
            }
            std::cout << std::endl;
        }
    }
 
private:
    /* Количество нейронов  в каждом слое */
    const short inputCount = 2;
    const short hiddenCount = 2;
    const short outputCount = 1;
    /* Массивы, хранящие веса */
    double weightsInputHidden[2][2];
    double weightsHiddenOutput[2][1];
    /* Сигмоидная функция активации */
    double sigma(double x)
    {
        return 1 / (1 + pow(M_E, -x));
    }
};
 
 
 
 
int main()
{
    cXOR obj;
 
    std::cout << "Before train :\n"
            << "1 - 1 = " << obj.query(1, 1) << '\n'
            << "1 - 0 = " << obj.query(1, 0) << '\n'
            << "0 - 1 = " << obj.query(0, 1) << '\n'
            << "0 - 0 = " << obj.query(1, 1) << '\n';
    std::cout << "\n Weights:\n";
    obj.print();
 
    std::vector<int> x1 = {1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1};
    std::vector<int> x2 = {0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0};
    std::vector<int> ans = {1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1};
 
    std::cout << "Train...\n";
 
    for(int i = 0; i < 100; ++i)
    obj.train(x1.size(), x1, x2, ans, 0.3) == 0 ?
                (std::cout << "Sucsess train #" << i + 1 << "!\n") :
                (std::cout << "Error train\n");
 
    std::cout << "After train :\n"
            << "1 - 1 = " << obj.query(1, 1) << '\n'
            << "1 - 0 = " << obj.query(1, 0) << '\n'
            << "0 - 1 = " << obj.query(0, 1) << '\n'
            << "0 - 0 = " << obj.query(1, 1) << '\n';
    std::cout << "\n Weights:\n";
    obj.print();
    return 0;
}
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
30.12.2019, 17:39
Ответы с готовыми решениями:

Простая нейросеть
Доброго времени суток! Передо мной стоит задача создать простую нейросеть. Вот начальный код: ...

Простая нейросеть
Привет всем! Есть задача: Научить нейросеть ставить диагноз. 1 диагноз - 1 сеть. Сеть 3 слоя:...

Простая нейросеть для новичков
Здравствуйте уважаемые программисты Python. Я - новичок. Напишите мне, пожалуйста простую...

Нужна простая функция шифровки и фича дешифровки XOR
У кого есть дайте, но чтобы было очень просто сразу вставить не думая. Неохота как-то вникать в...

12
673 / 547 / 74
Регистрация: 20.09.2014
Сообщений: 3,560
30.12.2019, 20:54 2
1. В строчке 126 закрывающая скобка не там вроде.
2. Уменьшить лернинг-рейт до 0,001.
1
11 / 9 / 3
Регистрация: 16.06.2019
Сообщений: 57
31.12.2019, 12:48  [ТС] 3
Спасибо за скобку, исправил, + исправил learningrate, но, к сожалению, не помогло
Изображения
  
0
673 / 547 / 74
Регистрация: 20.09.2014
Сообщений: 3,560
31.12.2019, 16:53 4
Лучший ответ Сообщение было отмечено Жозе_Алехандро как решение

Решение

Еще:
1. С чего взяли, что не нужно вычислять OutputSignHO? Надо еще одну сигмоиду в query()!
2. Почему (1 - sigm(x))? Там же разница между правильным и фактическим ответом должна быть. Тогда и проверка по условию с строке 84 не нужна.
3. В тех же формулах надо еще на сигнал соответствующего синапса умножать.

Итоговая формула вычисления дельты веса:
dw = learningrate * (d - y) * sigm(z) * (1-sigm(z)) * x

То есть не хватает у вас d и x.
0
1471 / 826 / 140
Регистрация: 12.10.2013
Сообщений: 5,456
01.01.2020, 12:44 5
Смотрите график ошибки от эпохи. Может обучения вообще нет.
1
11 / 9 / 3
Регистрация: 16.06.2019
Сообщений: 57
03.01.2020, 00:48  [ТС] 6
Спасибо, еще немного покурю матчасть и, учитывая ваши поправки, попробую снова
0
11 / 9 / 3
Регистрация: 16.06.2019
Сообщений: 57
03.01.2020, 04:35  [ТС] 7
Думал, что все понял, все исправил, уже был готов вкушать плоды победы, но нет, снова что-то не так и снова непонятно где это берется
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
#include <iostream>
#include <ctime>
#include <cmath>
#include <vector>
 
class cXOR
{
public:
    cXOR()
{
        /* Начальное рандомное заполнение весов между слоями */
        srand(time(NULL));
        double temp;
        for(int i = 0; i < 3; ++i)
        {
            /* Чтобы вес не равнялся нулю ибо все слетит */
            while(!(temp = ((rand() % 100) - 50.0) / 100.0));
            weightHO[i] = temp;
            for(int j = 0; j < 2; ++j)
            {
                /* Чтобы вес не равнялся нулю ибо все слетит */
                while(!(temp = ((rand() % 100) - 50.0) / 100.0));
                weightIH[i][j] = temp;;
            }
        }
 
        /* Установка выходных сигналов и ошибок в 0 по умолчанию */
        for(int j = 0; j < 2; ++j)
        {
            signIn[j] = 0;
            signHid[j] = 0;
            errHO[j] = 0;
            errIH[j] = 0;
        }
        signOut = 0;
        errO = 0;
 
        /* Установка шага в 0 просто, чтобы не было неинициализированной */
        learningrate = 0.1;
}
 
    /* Опрос
     * 0 - ошибка */
    double query(double x1, double x2)
    {
        /* Проверка на корректность ввода 0.1 или 0.9 */
        if((x1 != 0.1 && x1 != 0.9) || (x2 != 0.1 && x2 != 0.9))
        {
            return 0.0;
        }
        else
        {
            /* Установка сигналов входного слоя */
            signIn[0] = x1;
            signIn[1] = x2;
 
            /* Вычисление сигналов скрытого слоя
             * Последним всегда складывается смещение */
            signHid[0] = signIn[0] * weightIH[1][0] +
                    signIn[1] * weightIH[2][0] +
                    1 * weightIH[0][0];
            signHid[1] = signIn[0] * weightIH[1][1] +
                    signIn[1] * weightIH[2][1] +
                    1 * weightIH[0][1];
 
            /* Вычисление выходного сигнала
             * Поседним складывается смещение */
            signOut = sigma(sigma(signHid[0]) * weightHO[1] +
                    sigma(signHid[1]) * weightHO[2] +
                    sigma(1 * weightHO[0]));
 
            if(signOut > 0.4)
            {
                return 0.9;
            }
            else
            {
                return 0.1;
            }
        }
    }
 
    /* Тренировка
     * 0 - ошибка */
    bool train(std::vector<double> x1, // вектор 1-ых входных значений
            std::vector<double> x2, // вектор 2-ых входных значений
            std::vector<double> answer, // вектор эталонных ответов
            double learningrate) // шаг обучения
    {
        if(x1.size() != x1.size() || x1.size() != answer.size())
        {
            return false;
        }
        else
        {
            this->learningrate = learningrate;
 
            /* Будет хранить реальные выходные значения */
            double temp = 0.0;
 
            /* На каждый переданный комплект */
            for(size_t i = 0; i < x1.size(); ++i)
            {
                /* Получить текущий оезультат */
                temp = query(x1[i], x2[i]);
 
                /* Рассчет выходной ошибки */
                errO = (answer[i] - temp) * temp * (1.0 - temp);
 
                /* Рассчет ошибок Скрытый-Выходной */
                for(int j = 0; j < 2; ++j)
                {
                    errHO[j] = signHid[j] * (1 - signHid[j]) * errO * weightHO[j+1];
                }
 
                /* Подстройка весов Скрытый-Выходной */
                for(int j = 0; j < 3; ++j)
                {
                    /* Смещение */
                    if(!j)
                    {
                        weightHO[j] += this->learningrate * errO * 1.0;
                    }
                    else
                    {
                        weightHO[j] += this->learningrate * errO * signHid[j];
                    }
                }
 
                /* Рассчет ошибок Входной-Скрытый */
                for(int j = 0; j < 2; ++j)
                {
                    errIH[j] = signIn[j] * (1 - signIn[j]) * errHO[j] * weightIH[j+1][j];
                }
 
                /* Подстройка весов Входной-Скрытый */
                for(int j = 0; j < 3; ++j)
                    for(int k = 0; k < 2; ++k)
                    {
                        if(!j)
                        {
                            weightIH[j][k] += this->learningrate * errHO[k] * 1.0;
                        }
                        else
                        {
                            weightIH[j][k] += this->learningrate * errHO[k] * signIn[k];
                        }
                    }
            }
        }
    return true;
    }
 
    /* Вывести веса на экран */
    void print()
    {
        std::cout << "IH:\n";
        for(int i = 0; i < 3; ++i)
        {
            for(int j = 0; j < 2; ++j)
            {
                std::cout << weightIH[i][j] << " ";
            }
            std::cout << std::endl;
        }
 
        std::cout << "\n HO\n";
        for(int i = 0; i < 3; ++i)
        {
            std::cout << weightHO[i] << " ";
        }
        std::cout << std::endl;
    }
 
private:
    /* Выходные сигналы: Входного слоя
     *                  Скрытого слоя
     *                  Выходного слоя */
    double signIn[2], signHid[2], signOut;
 
    /* Веса: Входные-Скрытые и Скрытые-Выходные
     * Первый [0] всегда сдвиг*/
    double weightIH[3][2], weightHO[3];
 
    /* Шаг обучения */
    double learningrate;
 
    /* Ошибки на слоях: Выходного сигала
     *                  Скрытого слоя
     *                  Входного слоя */
    double errO, errHO[2], errIH[2];
 
    /* Сигмоидная функция активации */
    double sigma(double x)
    {
        return 1 / (1 + pow(M_E, -x));
    }
};
 
 
 
 
int main()
{
    std::vector<double> x1 =        {0.1, 0.1, 0.9, 0.1, 0.9, 0.1, 0.9, 0.9, 0.1, 0.1, 0.9, 0.9, 0.9, 0.1};
    std::vector<double> x2 =        {0.1, 0.9, 0.9, 0.1, 0.9, 0.1, 0.1, 0.1, 0.1, 0.9, 0.9, 0.1, 0.1, 0.1};
    std::vector<double> answer =    {0.1, 0.9, 0.1, 0.1, 0.1, 0.1, 0.9, 0.9, 0.1, 0.9, 0.1, 0.9, 0.9, 0.1};
 
    cXOR xr;
    std::cout << "Before\n";
    xr.print();
    std::cout << "1 - 1 = " << xr.query(0.9, 0.9) << std::endl
            << "1 - 0 = " << xr.query(0.9, 0.1) << std::endl
            << "0 - 1 = " << xr.query(0.1, 0.9) << std::endl
            << "0 - 0 = " << xr.query(0.1, 0.1) << std::endl;
 
    for(int i = 0; i < 25; ++i)
    {
    //  std::cout << i << std::endl;
        xr.train(x1, x2, answer, 0.3);
    }
    std::cout << std::endl;
 
    std::cout << "After\n";
    xr.print();
    std::cout << "1 - 1 = " << xr.query(0.9, 0.9) << std::endl
            << "1 - 0 = " << xr.query(0.9, 0.1) << std::endl
            << "0 - 1 = " << xr.query(0.1, 0.9) << std::endl
            << "0 - 0 = " << xr.query(0.1, 0.1) << std::endl;
    return 0;
}
Помогите)
Миниатюры
Простая нейросеть XOR  
0
673 / 547 / 74
Регистрация: 20.09.2014
Сообщений: 3,560
03.01.2020, 05:09 8
1. Сопоставьте строки 113 и 133. Двойной счет.

2. В строке 108 сигмоида заменена на temp?
1
41 / 20 / 3
Регистрация: 12.10.2015
Сообщений: 126
03.01.2020, 14:32 9
Как люди не понимают что искать ошибки в чужом коде Mlp задача не на 2 минуты, особенно в таком говнокоде как у топикстартера, при всём уважении. Здесь на форуме уже не раз выкладывались исходники Mlp на С#, С++, С и Python, даже видел матлаб . В интернете полно исходников например. Имейте уважение к собеседникам, ну или предлагайте за труд по поиску ошибки премию, сотню баксов, да хотя бы символическую двадцатку, если вы сами не можете\ленитесь сопоставить совой код и чужой и найти ошибку.
0
11 / 9 / 3
Регистрация: 16.06.2019
Сообщений: 57
03.01.2020, 20:15  [ТС] 10
Цитата Сообщение от Mikhaylo Посмотреть сообщение
1. Сопоставьте строки 113 и 133. Двойной счет.
Нет, там идет рассчет ошибок между разными слоями

Цитата Сообщение от Mikhaylo Посмотреть сообщение
2. В строке 108 сигмоида заменена на temp?
temp, как оконечный результат сам является результатом необходимой сигмоиды же, поэтому, полагаю, можно взять и его

И да, я все-таки сделал ее, даже выдает более менее корректные результаты) До совсем удовлетворительных, конечно же далеко, теперь "плясать" отсюда будет легче, всем спасибо, отдельное большое Mikhaylo.

Как-то так, как результат:
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
#include <iostream>
#include <ctime>
#include <cmath>
#include <vector>
 
class cXOR
{
public:
    cXOR()
{
        /* Начальное рандомное заполнение весов между слоями */
        srand(time(NULL));
        double temp;
        for(int i = 0; i < 3; ++i)
        {
            /* Чтобы вес не равнялся нулю ибо все слетит */
            while(!(temp = ((rand() % 100) - 50.0) / 100.0));
            weightHO[i] = temp;
            for(int j = 0; j < 2; ++j)
            {
                /* Чтобы вес не равнялся нулю ибо все слетит */
                while(!(temp = ((rand() % 100) - 50.0) / 100.0));
                weightIH[i][j] = temp;;
            }
        }
 
        /* Установка выходных сигналов и ошибок в 0 по умолчанию */
        for(int j = 0; j < 2; ++j)
        {
            signIn[j] = 0;
            signHid[j] = 0;
            errHO[j] = 0;
            errIH[j] = 0;
        }
        signOut = 0;
        errO = 0;
 
        /* Установка шага в 0 просто, чтобы не было неинициализированной */
        learningrate = 0.1;
}
 
    /* Опрос
     * 0 - ошибка */
    double query(double x1, double x2)
    {
        /* Проверка на корректность ввода 0.1 или 0.9 */
        if((x1 != 0.1 && x1 != 0.9) || (x2 != 0.1 && x2 != 0.9))
        {
            return 0.0;
        }
        else
        {
            /* Установка сигналов входного слоя */
            signIn[0] = sigma(x1);
            signIn[1] = sigma(x2);
 
            /* Вычисление сигналов скрытого слоя
             * Последним всегда складывается смещение */
            signHid[0] = sigma(signIn[0] * weightIH[1][0] +
                    signIn[1] * weightIH[2][0] +
                    1 * weightIH[0][0]);
 
            signHid[1] = sigma(signIn[0] * weightIH[1][1] +
                    signIn[1] * weightIH[2][1] +
                    1 * weightIH[0][1]);
 
            /* Вычисление выходного сигнала
             * Поседним складывается смещение */
            signOut = sigma(signHid[0] * weightHO[1] +
                    signHid[1] * weightHO[2] +
                    sigma(1 * weightHO[0]));
            return signOut;
        }
    }
 
    /* Тренировка
     * 0 - ошибка */
    bool train(std::vector<double> x1, // вектор 1-ых входных значений
            std::vector<double> x2, // вектор 2-ых входных значений
            std::vector<double> answer, // вектор эталонных ответов
            double learningrate) // шаг обучения
    {
        if(x1.size() != x1.size() || x1.size() != answer.size())
        {
            return false;
        }
        else
        {
            this->learningrate = learningrate;
 
            /* Будет хранить реальные выходные значения */
            double temp = 0.0;
 
            /* На каждый переданный комплект */
            for(size_t i = 0; i < x1.size(); ++i)
            {
                /* Получить текущий оезультат */
                temp = query(x1[i], x2[i]);
 
                /* Рассчет выходной ошибки */
                errO = (answer[i] - temp) * temp * (1.0 - temp);
 
                /* Рассчет ошибок Скрытый-Выходной */
                for(int j = 0; j < 2; ++j)
                {
                    errHO[j] = signHid[j] * (1 - signHid[j]) * errO * weightHO[j+1];
                }
 
                /* Подстройка весов Скрытый-Выходной */
                for(int j = 0; j < 3; ++j)
                {
                    /* Смещение */
                    if(!j)
                    {
                        weightHO[j] += this->learningrate * errO * 1.0;
                    }
                    else
                    {
                        weightHO[j] += this->learningrate * errO * signHid[j-1];
                    }
                }
 
                /* Рассчет ошибок Входной-Скрытый */
                for(int j = 0; j < 2; ++j)
                {
                    errIH[j] = signIn[j] * (1 - signIn[j]) *
                            (errHO[0] * weightIH[j+1][0] + errHO[1] * weightIH[j+1][1]);
                }
 
                /* Подстройка весов Входной-Скрытый */
                for(int j = 0; j < 3; ++j)
                    for(int k = 0; k < 2; ++k)
                    {
                        if(!j)
                        {
                            weightIH[j][k] += this->learningrate * errHO[k] * 1.0;
                        }
                        else
                        {
                            weightIH[j][k] += this->learningrate * errHO[k] * signIn[k];
                        }
                    }
            }
        }
    return true;
    }
 
    /* Вывести веса на экран */
    void print()
    {
        std::cout << "IH:\n";
        for(int i = 0; i < 3; ++i)
        {
            for(int j = 0; j < 2; ++j)
            {
                std::cout << weightIH[i][j] << " ";
            }
            std::cout << std::endl;
        }
 
        std::cout << "\n HO\n";
        for(int i = 0; i < 3; ++i)
        {
            std::cout << weightHO[i] << " ";
        }
        std::cout << std::endl;
    }
 
private:
    /* Выходные сигналы: Входного слоя
     *                  Скрытого слоя
     *                  Выходного слоя */
    double signIn[2], signHid[2], signOut;
 
    /* Веса: Входные-Скрытые и Скрытые-Выходные
     * Первый [0] всегда сдвиг*/
    double weightIH[3][2], weightHO[3];
 
    /* Шаг обучения */
    double learningrate;
 
    /* Ошибки на слоях: Выходного сигала
     *                  Скрытого слоя
     *                  Входного слоя */
    double errO, errHO[2], errIH[2];
 
    /* Сигмоидная функция активации */
    double sigma(double x)
    {
        return 1 / (1 + pow(M_E, -x));
    }
};
 
 
int main()
{
    std::vector<double> x1 =        {0.1, 0.1, 0.9, 0.1, 0.9, 0.1, 0.9, 0.9, 0.9, 0.1, 0.9, 0.9, 0.9, 0.1, 0.1, 0.9, 0.1};
    std::vector<double> x2 =        {0.1, 0.9, 0.9, 0.1, 0.9, 0.1, 0.9, 0.1, 0.1, 0.9, 0.9, 0.1, 0.1, 0.9, 0.1, 0.9, 0.9};
    std::vector<double> answer =    {0.1, 0.9, 0.1, 0.1, 0.1, 0.1, 0.0, 0.9, 0.9, 0.9, 0.1, 0.9, 0.9, 0.9, 0.1, 0.1, 0.9};
 
    cXOR xr;
    std::cout << "Before\n";
    xr.print();
    std::cout << "1 - 1 = " << xr.query(0.9, 0.9) << std::endl
            << "1 - 0 = " << xr.query(0.9, 0.1) << std::endl
            << "0 - 1 = " << xr.query(0.1, 0.9) << std::endl
            << "0 - 0 = " << xr.query(0.1, 0.1) << std::endl;
 
    for(int i = 0; i < 99999; ++i)
    {
        xr.train(x1, x2, answer, 0.36);
    }
    std::cout << std::endl;
 
    std::cout << "After\n";
    xr.print();
    std::cout << "1 - 1 = " << xr.query(0.9, 0.9) << std::endl
            << "1 - 0 = " << xr.query(0.9, 0.1) << std::endl
            << "0 - 1 = " << xr.query(0.1, 0.9) << std::endl
            << "0 - 0 = " << xr.query(0.1, 0.1) << std::endl;
    return 0;
}
Миниатюры
Простая нейросеть XOR  
0
673 / 547 / 74
Регистрация: 20.09.2014
Сообщений: 3,560
03.01.2020, 21:42 11
В формуле 126 единичный сигнал разве не нужен? И синапсы не те взял, надо те, которые к одному нейрону относятся. Не?
1
11 / 9 / 3
Регистрация: 16.06.2019
Сообщений: 57
04.01.2020, 17:24  [ТС] 12
Цитата Сообщение от Mikhaylo Посмотреть сообщение
В формуле 126 единичный сигнал разве не нужен?
Я где-то вычитывал, что ошибки на сдвиг не нужно вычислять, вроде бы как.

Цитата Сообщение от Mikhaylo Посмотреть сообщение
И синапсы не те взял, надо те, которые к одному нейрону относятся.
Даа, спасибо в очередной раз) Перепутал синапсы Поставил правильные - результат много лучше
0
673 / 547 / 74
Регистрация: 20.09.2014
Сообщений: 3,560
04.01.2020, 20:32 13
Цитата Сообщение от Жозе_Алехандро Посмотреть сообщение
Я где-то вычитывал, что ошибки на сдвиг не нужно вычислять, вроде бы как.
Да, все верно, ошибку на константу 1.0 не надо вычислять, но в других формулах эти величины должны быть также как при прямом вычислении.
0
04.01.2020, 20:32
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.01.2020, 20:32
Помогаю со студенческими работами здесь

Исключающее ИЛИ (XOR). Нужен пример операции побайтного XOR
Может кто-нибудь привести пример операции побайтного XOR?что-то вроде: есть данные,считанные из...

Простая авторизация на php и mysql, очень простая!
В базе данных таблица с двумя строками: id, user, password. На странице есть два поля для ввода...

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

Нейросеть
using System; using System.IO; using System.Runtime.InteropServices; namespace...


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru