0 / 0 / 0
Регистрация: 06.10.2020
Сообщений: 27
1

Обучение сети персептронов для решения xor проблемы

09.09.2022, 18:29. Показов 950. Ответов 4

Author24 — интернет-сервис помощи студентам
Здравствуйте, я реализовал класс Perceptron. Создал первый слой из 3 персептронов и второй слой из 1 персептрона. Когда запускаю обучение, сеть изменяется (ее веса изменяются), но на выходе она дает вообще другой результат, не который нужен мне. Подскажите, пожалуйста, в чем проблема?
perceptron - реализация класса, main - обучение

perceptron.h
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
#pragma once
#include <vector>
#include <cmath>
#include <ctime>
class Perceptron {
private:
    std::vector<double> weights; //веса персептрона
    double learning_rate; //скорость обучения
    double output; //последнее выходное значение
    double local_derivative; //локальный градиент
public:
    //конструктор по умолчанию
    Perceptron(int w_number, double l_r = 0.1) {
        srand(time(NULL));
        this->learning_rate = l_r;
        for (int i = 0; i < w_number; i++) {
            this->weights.push_back(-0.5 + (double)rand() / RAND_MAX); //записываем случайное число от -0.5 до 0.5
        }
    }
    double activate(std::vector<double> input);
    double predict(std::vector<double> input);
    std::vector<double>get_weights();
    void set_weights(std::vector<double> weights);
    void learn(std::vector<double> input, double error);
    //void learn(std::vector<double> input, double loc_der);
    std::vector<double> get_local_derivatives();
};


perceptron.cpp
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
#include "perceptron.h"
 
double func(double x) {
    return 1. / (1. + exp(x));
}
 
double derivative(double x) {
    double y = func(x);
    return y * (1. - y);
}
//производная f(x)(1-f(x))
 
 
 
//функция активации
double Perceptron::activate(std::vector<double> input) {
    double out = 0;
    int size = this->weights.size();
    for (int i = 0; i < size; i++) {
        out += input[i] * this->weights[i];
    }
    return out;
}
 
//логистическая функция предсказания 
double Perceptron::predict(std::vector<double> input) {
    double out = this->activate(input);
    out = func(out);
    this->output = out;
    return out;
}
 
 
//обучение (изменение весов) на основе ошибки и входных данных
void Perceptron::learn(std::vector<double> input, double error) {
    this->local_derivative = error * derivative(this->output);
    int size = this->weights.size();
    for (int i = 0; i < size; i++) {
        this->weights[i] -= this->learning_rate * this->local_derivative * input[i];
    }
     
}
 
//получить локальные градиенты
std::vector<double> Perceptron::get_local_derivatives() {
    std::vector<double> loc_der;
    int size = this->weights.size();
    for (int i = 0; i < size; i++) {
        loc_der.push_back(this->weights[i] * this->local_derivative);
    }
    return loc_der;
}
 
 
//получить веса
std::vector<double> Perceptron::get_weights() {
    return this->weights;
}
 
 
//установить веса
void Perceptron::set_weights(std::vector<double> weights) {
    this->weights = weights;
}

main.cpp
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
#include <iostream>
#include "perceptron.h"
 
using namespace std;
 
int main() {
    setlocale(LC_ALL, "rus");
    //таблица истинности
    //исключающее или из 2 входов
    
    vector<vector<double>> inputs(4);
    inputs[0] = { 0,0 };
    inputs[1] = { 0,1 };
    inputs[2] = { 1,0 };
    inputs[3] = { 1,1 };
 
    vector<double> answers(4, 0);
    answers[1] = answers[2] = 1;
 
    int N_1 = 3;
    srand(time(NULL));
    vector<Perceptron> first_layer(N_1, Perceptron(2));
    for (int i = 0; i < N_1; i++) {
        vector<double> weights(2);
        for (int j = 0; j < 2; j++) {
            weights[j] = -0.5 + (double)rand() / RAND_MAX;
        }
        first_layer[i].set_weights(weights);
    }
 
    //последний персептрон имеет 3 входа
    Perceptron last_layer = Perceptron(N_1);
 
 
    cout << "Веса сети" << endl;
    for (int i = 0; i < N_1; i++) {
        cout << "Веса нейрона №" << i << endl;
        vector<double> weights = first_layer[i].get_weights();
        for (int j = 0; j < 2; j++) {
            cout << weights[j] << ' ';
        }
        cout << endl;
    }
    cout << "Веса выходного нейрона" << endl;
 
    vector<double> weights = last_layer.get_weights();
    for (int j = 0; j < 2; j++) {
        cout << weights[j] << ' ';
    }
    cout << endl;
 
    //начинаем обучение
    //первая итерация
    //прямое распространение
    for (int i = 0; i < 1000; i++) {
        for (int j = 0; j < 4; j++) {
 
            vector<double> out_first_layer;
            for (int i = 0; i < N_1; i++) {
                out_first_layer.push_back(first_layer[i].predict(inputs[j]));
            }
            double output = last_layer.predict(out_first_layer);
            double error = output - answers[j];
            cout << " Ответ сети: " << output << " Нужный ответ " << answers[j] << " итерация №" << i * 4 + j << endl;
 
            //обратное распространение
            last_layer.learn(out_first_layer, error);
            vector<double> loc_der = last_layer.get_local_derivatives();
            for (int i = 0; i < N_1; i++) {
                first_layer[i].learn(inputs[j], loc_der[i]);
            }
        }
    }
    
 
    cout << "Веса сети" << endl;
    for (int i = 0; i < N_1; i++) {
        cout << "Веса нейрона №" << i << endl;
        vector<double> weights = first_layer[i].get_weights();
        for (int j = 0; j < 2; j++) {
            cout << weights[j] << ' ';
        }
        cout << endl;
    }
    cout << "Веса выходного нейрона" << endl;
 
    weights = last_layer.get_weights();
    for (int j = 0; j < 2; j++) {
        cout << weights[j] << ' ';
    }
    cout << endl;
    
    return 0;
}
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
09.09.2022, 18:29
Ответы с готовыми решениями:

Обучение двухслойного персептрона для решения XOR задачи исползуя дельта правило
Здравстуйте, возникла такая проблема при изучении персептронов: сеть обучается только при удачном...

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

Подбор данных для обучение нейронный сети
Решил немного заняться нейронными сетями, попробовал написать XOR, затем с sin попробовал. В...

Обучение и применение нейронной сети для прохождения игры
я написал Flappy Bird на HTML5 теперь хочу сделать простенькую нейронную сеть на JS... (движется...

Обучение нейронной сети для получения аппроксимирующей модели зависимости
Помогите написать код программы, а то плохо понимаю тему, да и сети в принципе... Задание: По...

4
1609 / 1511 / 251
Регистрация: 19.02.2010
Сообщений: 4,078
09.09.2022, 19:39 2
Цитата Сообщение от Nikis0715 Посмотреть сообщение
в чем проблема?
В строках 67-68 в main.cpp. В завышенном на 2-3 порядка значении скорости обучения.
Дальше мне лень ломать глаза.
0
0 / 0 / 0
Регистрация: 06.10.2020
Сообщений: 27
09.09.2022, 21:09  [ТС] 3
Даже с маленьким learning_rate в 0.01 или 0.001 сеть не учится. В 67 строчке main в чем ошибка? Я изменяю веса персептрона, передав ему входные значения и итоговую ошибку. А в 68 строчке я получаю вектор локальных градиентов, чтобы потом их передать первому слою персептронов для изменения весов
0
1609 / 1511 / 251
Регистрация: 19.02.2010
Сообщений: 4,078
09.09.2022, 22:43 4
Цитата Сообщение от Nikis0715 Посмотреть сообщение
В 67 строчке main в чем ошибка? Я изменяю веса персептрона, передав ему входные значения и итоговую ошибку. А в 68 строчке я получаю вектор локальных градиентов, чтобы потом их передать первому слою персептронов для изменения весов
А с какого перепугу "вектор локальных градиентов" (и, затем, производные и, далее, изменения весов слоя) должен зависеть от только что изменённых весов следующего слоя? Да ещё и от величины learning rate, задавшей амплитуду изменения тех весов?
0
0 / 0 / 0
Регистрация: 06.10.2020
Сообщений: 27
09.09.2022, 22:52  [ТС] 5
Точно, поменял строчки местами. Но проблема не решилась. Может быть дело в функции предсказания? Я выбрал логистическую функцию, может, он не подходит?
0
09.09.2022, 22:52
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
09.09.2022, 22:52
Помогаю со студенческими работами здесь

Проблемы с XOR и двоичный кодом
Доброго времени суток, есть задание &quot;Хэширование сообщения по стандарту МККТТ Х.509&quot; и программа...

Подскажите библиотеку/способ для решения проблемы
from time import sleep smbls = 'qwerty' indx = 0 for x in range(1000): print(f'----&gt;...

Весовые коэффициенты в нейронной сети XOR
Здравствуйте. Стоит задача написать нейронную сеть для реализации XOR(см. Приложение). net =...

Нейронные сети. Решение XOR задачи на C#
Всем доброго времени суток! Вот начал изучать нейронные сети, и решил начать с XOR-задачи(сумма по...

Нужны искушённые добровольцы для решения серьёзной проблемы государственной важности
Добрый день. Есть одна центральноевропейская страна, в которой власти упорно скрывают реальную...

Какие технологии предложите для решения проблемы создания приложения путеводителя?
Допустим, есть магазин, нужно создать приложение с отображением карты магазина и поиска товаров на...


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

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

Новые блоги и статьи
Как написать микросервис на Go/Golang
InfoMaster 14.01.2025
Определение микросервиса, преимущества использования Go/ Golang Микросервис – это архитектурный подход к разработке программного обеспечения, при котором приложение состоит из небольших, независимо. . .
Как написать микросервис с нуля на C#
InfoMaster 14.01.2025
В современном мире разработки программного обеспечения микросервисная архитектура стала стандартом де-факто для создания масштабируемых и гибких приложений. Этот архитектурный подход предполагает. . .
Как создать интернет-магазин на PHP и JavaScript
InfoMaster 14.01.2025
В современном мире электронная коммерция стала неотъемлемой частью бизнеса. Создание собственного интернет-магазина открывает широкие возможности для предпринимателей, позволяя достичь большей. . .
Как написать Тетрис на Ассемблере
InfoMaster 14.01.2025
Тетрис – одна из самых узнаваемых и популярных компьютерных игр, созданная в 1984 году советским программистом Алексеем Пажитновым. За прошедшие десятилетия она завоевала симпатии миллионы людей по. . .
Как создать игру "Танчики" на Unity3d и C#
InfoMaster 14.01.2025
Разработка игр – это увлекательный процесс, сочетающий в себе творчество и технические навыки. В этой статье мы рассмотрим создание классической игры "Танчики" с использованием Unity3D и языка. . .
Организую платный онлайн микро-курс по доработке Android-клиента Telegram
_Ivana 14.01.2025
Официальная версия и распространенные форки не полностью устраивают? Сделай свою кастомную версию клиента! 4 занятия по 2 часа (2 недели пн, ср 19:00-21:00 по Москве). Первое вводное занятие. . .
Как создать приложение для фитнеса для iOS/iPhone на Kotlin
InfoMaster 14.01.2025
Создание собственного фитнес-приложения — это не только захватывающий, но и полезный процесс, ведь оно может стать вашим верным помощником на пути к здоровому и активному образу жизни. В современных. . .
Как создать приложение магазина для iOS/iPhone на Swift
InfoMaster 14.01.2025
Введение в разработку iOS-приложений Разработка приложений для iPhone и других устройств на базе iOS открывает огромные возможности для создания инновационных мобильных решений. В данной статье мы. . .
Это работает. Скорость асинхронной логики велика. Вопрос видимо останется в стабильности. Плата - огонь!
Hrethgir 13.01.2025
По прошлому проекту в Logisim Evolution https:/ / www. cyberforum. ru/ blogs/ 223907/ blog8781. html прилагаю файл архива проекта в Gowin Eda. Восьмибитный счётчик из сумматора+ генератор сигнала. . .
UserScript для подсветки кнопок языков программировани­­­­я в зависимости от текущего раздела
volvo 13.01.2025
В результате работы этого скрипта подсвечиваются нужные кнопки не только в форме быстрого ответа, но и при редактировании сообщения: / / ==UserScript== / / @name CF_DefaultLangSelect / / . . .
Введение в модели и алгоритмы машинного обучения
InfoMaster 12.01.2025
Машинное обучение представляет собой одну из наиболее динамично развивающихся областей искусственного интеллекта, которая фокусируется на разработке алгоритмов и методов, позволяющих компьютерам. . .
Как на Python создать нейросеть для решения задач
InfoMaster 12.01.2025
В контексте стремительного развития современных технологий особое внимание уделяется таким инструментам, как нейросети. Эти структуры, вдохновленные биологическими нейронными сетями, используются для. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru