Пытаемся построить сетку для идентификации птицы: входы - 1я строка таблицы, выходы 7-й столбец.
Получаем исходник:
double getResult(double x1, double x2, double x3, double x4, double x5, double x6) { double result = 0d; if (x2 > 0d) { if (x4 > 0d) { result = -0.250415 * x2 + 0.249829 * x3 - 0.24926 * x4 + 0.250496 * x5; } else { result = 0.333583 * x3 + 0.332958 * x5 - 0.333459 * x6; } } else { result = -1.0; } return (result); }
Сначала кластеризация идет по признаку "Хвост" - x2. Отсутствие хвоста однозначно выдаст на выходе -1, т.е. объект не может быть птицей. Единственный объект в обучающей выборке без хвоста - муха. Муха - не птица.
Далее, если хвост в наличии, то делается попытка идентифицировать объект по признаку двигатель - x4. Двигателя у птицы явно быть не может. Но здесь, мы не получаем однозначного ответа и результат вычисляется с помощью перцептрона.
result = -0.250415 * x2 + 0.249829 * x3 - 0.24926 * x4 + 0.250496 * x5;
Двигатель в обучающей выборке имеют два объекта: самолет и ракета. Если значения их признаков подставить в уравнение перцептрона, то получим -1.
При наличии хвоста и отсутствии двигателя, решение тоже выдается перцептроном:
result = 0.333583 * x3 + 0.332958 * x5 - 0.333459 * x6;
Хвостатых объектов без двигателя всего два: птица и планер. Если значения их признаков подставить в уравнение перцептрона, то получим 1 для птицы и -1 для планера.
Следующий распознаваемый объект - муха
Получаем сетку:
double getResult(double x1, double x2, double x3, double x4, double x5, double x6) { double result = 0d; if (x1 > 0d) { result = -1.0 * x2; } else { result = -1.0; } return (result); }
Сначала кластеризация идет по признаку крылья - x1. Крылья отсутствуют только у ракеты. Ракета - не муха. Для бескрылого варианта получаем однозначную -1.
Далее получаем небольшое уравнение:
result = -1.0 * x2;
x2 - признак хвоста. А следовательно любой бесхвостый объект даст нам на выходе 1, а хвостатый -1. В этом кластере бесхвостой является только муха.
Распознаем самолет.
double getResult(double x1, double x2, double x3, double x4, double x5, double x6) { double result = 0d; if (x3 > 0d) { result = -1.0; } else { result = 0.4998169454497442 * x3 + 1.0000000000000002 * x4 + 0.5006301877959634 * x5 + 1.0004471332457074 * x6; } return (result); }
Кластеризация по признаку x3 - клюв. Клюв есть только у птицы, птица - не самолет, а соответственно для этого кластера однозначная -1.
Для всех остальных объектов, кроме птицы получаем уравнение перцептрона:
result = 0.4998169454497442 * x3 + 1.0000000000000002 * x4 + 0.5006301877959634 * x5 + 1.0004471332457074 * x6;
Подставив в него значения признаков бесклювных объектов, получим 1 для самолета и -1 для остальных.
Предъявляем на опознание планер:
double getResult(double x1, double x2, double x3, double x4, double x5, double x6) { double result = 0d; if (x3 > 0d) { result = -1.0; } else { result = 0.5015607179302479 * x3 - 1.0001710786962001 * x4 + 0.498958520919623 * x5 + 1.000690317546071 * x6; } return (result); }Очень похож на самолет. За исключением одного знака у x4 - признак двигателя с отрицательным весом. Что совершенно верно, ведь планер отличается от самолета только наличием двигателя.
Теперь распознаем ракету:
double getResult(double x1, double x2, double x3, double x4, double x5, double x6) { double result = 0d; result = -1.0 * x1; return (result); }Самая короткая функция. Сразу без кластеризации, умножаем значение признака x1 (крыльz) на -1. Ведь у ракеты единственное отличие от всех остальных объектов - отсутствие крыльев.
Попробуем отличить биологические объекты от механических:
double getResult(double x1, double x2, double x3, double x4, double x5, double x6) { double result = 0d; if (x3 > 0d) { result = 1.0; } else { if (x1 > 0d) { result = -0.500137 * x2 - 0.499863 * x6; } else { result = -1.0; } } return (result); }
Начальная кластеризация по наличию клюва - x3. Клюв есть только у птицы, значит в этом кластере только ее обучающий пример, а следовательно и однозначная 1 на выходе.
Далее кластеризация по наличию крыльев. В кластер бескрылых и бесклювных попадает только ракета, поэтому там однозначная -1.
В оставшемся кластере бесклювых и крылатых: муха, планер и самолет. Биологической является только муха и отличить ее от механики можно по отсутствию хвоста - x2 и шасси - x6.
result = -0.500137 * x2 - 0.499863 * x6;
Попробуем отличить биологические объекты от механических:
Биологической является только муха и отличить ее от механики можно по отсутствию хвоста - x2 и шасси - x6.
Дополнительная информация:
Обучение перцептронов проводится своим весьма шустрым алгоритмом. Но даже если предположить, что скорость вычислений при кластеризации и обучении перцептронов не превышает скорости обучения какой-либо другой сетки, то все равно, за счет предварительной кластеризации, каждый отдельный перцептрон попадает в отдельный кластер. Следовательно вычислительные ресурсы можно распараллеливать. Параллельные вычисления пока не реализованы.
Что касается точности обучения сети. Если в обучающей выборке нет противоречивых примеров, как в вышеприведенной презентации, то и проблем не будет. Т.е. в таких случаях нет никакой разницы по точности результатов между R-Net и каким нибудь другим приличным нейропакетом. Другое дело при наличии противоречивых примеров в обучающей выборке. Тогда, скорее всего R-Net даст "худшие" результаты, по сравнению с большинством нейросетевых пакетов. Причина проста: R-Net не умеет заниматься подгонкой. Кластеризация ограничена. Т.е. как только значимые входные признаки на очередном этапе кластеризации закончатся (станут пренебрежительно незначительными), то кластер будет полностью сформирован. После этого начнется обучение перцептрона для кластера. А обучение проводится таким образом, чтобы для значительной части примеров веса перцептрона были решением системы линейных уравнений. Т.е. алгоритм самостоятельно автоматически способен выискивать противоречия в процессе обучения и отсеивать мусор. Соответственно, после того, как перцептрон будет обучен, для непротиворечивых примеров в кластере результаты на выходе сети будут совпадать с результатами в обучающей выборке, а для мусора различаться. В лучшем случае, примеры с противоречиями окажутся линейно сепарабельными, т.е. у них совпадет знак на выходе сети и в выборке, в худшем: сами знаете. Т.е. зерна от плевел отделяются. Естественно, что при таком подходе подгонки быть не может, т.е. отпадает даже необходимость разбивать выборку на обучающую и тестовую. В будущем планируется все противоречивые примеры выводить в какой нибудь отдельный список, чтобы пользователь при желании мог его посмотреть и даже подкорректировать (ведь вполне возможно ошибки в обучающую выборку попали по причине человеческого фактора, например, оператор набивал их в электронной таблице под диктовку или же в результате недостоверного сканирования и последующего распознавания текста с бумажных или иных неэлектронных носителей?).
Что касаемо недостатков, то они тоже имеются. Ниже список тех, что удалось выявить:
1. В обучающей выборке не может быть на выходах 0-е значение. Это обусловлено алгоритмом обучения перцептрона - получается математическая неопределенность.
2. Хотя сигмоиды не применяются, но все же иногда необходимо проводить принудительное масштабирование диапазонов на входах. Дело в том, что автоматическое масштабирование диапазонов уже заложено в алгоритм. Но, здесь диапазон на входе чаще всего обратно пропорционален весу, этого самого входа после обучения. На самом деле вес зависит в большей степени от значимости входа. Но при одинаковой значимости нескольких входов проявится разность диапазонов значений на них в обучающей выборке. Поэтому при значительном отличии диапазонов отдельных входных данных, может получится так, что веса обученного перцептрона для них станут пренебрежительно малы. Это может сказаться на результатах, особенно при кластеризации.
3. Алгоритм обучения перцептрона хотя и быстрый, но не точный - метод итерационный с высокой сходимостью. Поэтому для небольших матриц в кластере, возможно придется решать системы линейных уравнений дополнительным алгоритмами с высокой точностью по отсеянным непротиворечивым примерам. В данный момент дополнительные алгоритмы решения систем линейных уравнений не встроены.
Вполне не исключено, что имеют место и другие недостатки, которые пока выявить не удалось.
Reshetov:
Вполне не исключено, что имеют место и другие недостатки, которые пока выявить не удалось.
А как быть с информацией от производителей нейропакетов о том, что не все оные программы предназначены для работы на финрынках?
А как быть с информацией от производителей нейропакетов о том, что не все оные программы предназначены для работы на финрынках?
Сударыня, Вы не туда обратились. Спросите у производителей тех самых нейропакетов. Я за них за всех отвечать никак не могу.
От себя могу только констатировать:
1. Понятие финрынки - настолько обширная область человеческой меркантильной деятельности, да еще и по значительной части закрытая от лишних глаз и ушей коммерческой тайной, что о них вообще невозможно что либо сказать конкретное.
2. Скорее всего подстраховываются на всякий случай? Иначе потом дерьма в саппорте не оберешься, типа: "Купил сетку, спрогнозировал цену, слил депо. Возмещайте ущерб, не то в суд подам. Копии справок от брокера и логов сетки прилагаются.".
![MQL5 - Язык торговых стратегий для клиентского терминала MetaTrader 5](https://c.mql5.com/i/registerlandings/logo-2.png)
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Сетку делал под себя. Основные задачи, которые она решает:
1. Автоматический подбор архитектуры под обучающие примеры. То бишь нет необходимости выбирать архитектуру сети вручную "на глазок".
2. Отсутствие сигмоидов. Тоже не надо настраивать, а следовательно избавляет от лишней ручной работы.
Входные и выходные данные в выборке должны плясать вокруг нулевого значения - осцилляторы.
Принцип действия. Сначала идет кластеризация, т.е. разбиение задачи на подзадачи по наиболее значимым входным данным. Тоже самое что и в экспертных системах: задаем наводящие вопросы и в зависимости от полученных ответов, либо получаем решение, либо продолжаем формулировать задачу. Кластеризация идет до тех пор, пока значимых входных данных не останется. Если кластеризация завершена, а ответ не однозначен, решаем задачу с помощью обычного перцептрона (формулировка задачи).
В общем, принцип начальной кластеризации используется не только в экспертных системах, но и в многослойных нейросетях. В сетках слои, которые расположены ближе к входам занимаются кластеризацией. А те, что ближе к выходам, уже более детально решают задачу, если с помощью кластеризации ответа получить не удалось. Суть в том, что в обычной нейросети мы заведомо не знаем сколько нейронов понадобится в том или ином слое для решения задачи.
Внешне интерфейс очень простой. Нажимаем кнопку "Start" и в диалоговом окне выбираем файл с обучающей выборкой в формате *.csv (можно создать в Excel или получить в эксперте MetaTrader, например, в MQL4 есть предусмотренная функция FileWrite, для записи строк в формате *.csv).
После этого кнопка "Start" становится неактивной и начинается построение нейросети. Как только сетка построена, кнопка "Start" активируется и в интерфейсном текстовом поле появляется исходный код функции нейросети для языков совместимых с С, например, для Java, MQL* и проч.
Недоработкой на данный момент является временное отсутствие внутреннего интерпретатора нейросети, чтобы прогнать обучающую выборку и сравнить результаты на выходах сетки с результатами выборки.
Чтобы впустую не тратить время, покажу, как решить пример распознавания образов для летающих объектов.
Нам нужно построить нейросетки, для того чтобы отличить птицу, муху, самолет, планер и некрылатую ракету, а также является ли объект биологическим или механическим. Для этого задаются входные признаки объектов: крылья, хвост, клюв, двигатель, оперение и шасси. Зададим все это в таблице. Первые шесть колонок: признаки объктов - входы нейросети, остальные колонки - распознаваемые объекты - выходы нейросети. Наличие признака на входе задается 1, отсутствие -1. Распознаваемый объект на выходе задается 1, неверный -1.
Для функции нейросети GetResult() входные значения распределятся так:
x1 - крылья
x2 - хвост
x3 - клюв
x4 - двигатель
x5 - оперение
x6 - шасси