БК-0010 старца

БК-0010 старца

Сообщение Fouras » Пн май 13, 2019 3:05 pm

Идея графического редактора:

В качестве слоёв добавляются слой фактуры и слой графической техники.

На слое материала выбираешь фотографию с материалом, например траву, и рисуешь травой. Но! Этот материал накладывается на рисунок снизу, он не самостоятельный. Просто рисуешь поверх рисунка сегментацией объектов нейросети, а в качестве объектов подсовываем свои фото.

А потом поверх этого слой, на котором рисуем художественной техникой. Например, маслом: наши мазки превращаются в масляные. Пастель, уголь, акварель, монотипия, акватипия и т.д.

Проблема с карандашной графикой: современные нейросети не врубаются как устроен карандашный рисунок. Просто для штриховки нужно знать градиент z-буфера в данной точке. Художники это знают, а программисты - не знают, и им пофигу.
Аватара пользователя
Fouras
Старожил
Старожил
 
Сообщения: 7249
Зарегистрирован: Пн июн 12, 2017 1:23 am
Медали: 11
Пол: Мужской

БК-0010 старца

Сообщение Fouras » Ср май 15, 2019 1:50 am

В конечном счете обычный градиент всех победил на большой выборке.
Код: Выделить всё
function get_weight_delta(lesson, neuron, expRes, rate, outFilter)
{
   let sz = (neuron.length-1)|0, j = 0|0;
   let x = 0.0; // без сегмоиды

   for( j = 0; j<sz; ++j )
      x += lesson[j]*neuron[j];
   x += neuron[sz];

   let seg_x = outFilter.segmoid(x);
   let trueError = (expRes - seg_x)*outFilter.deriv(x);
   let error = trueError/(1+trueError*trueError);

   let weight_delta =error*rate;

   return weight_delta;
}


Особенностей почти нет. Пожалуй, только такая штука: trueError/(1+trueError*trueError);
Это борьба с расколбасом. На среднее значение практически не влияет, около процента, но улучшает худшие. Был вариант чуть получше, но он требовал подсчета среднего квадрата весов нейрона.

Мои эксперименты с заменой производной в среднем чуть похуже, где-то на 4%, и лишь изредка давали удачные решения. Но нас интересуют не удачные, а худшие или средние.

Несколько раз сменил архитектуру и теперь обнаружил, что вычисление нейрона по выборке сломано. Функции там уже довольно большие, с полпинка не восстановлю.

Заметно дала нормализация стартового шума. Лучший вариант дала такая:
просто вычитаем из весов среднее и масштабируем до +-0.7 Можно до 1.0, среднее чуть лучше, но появляются ужасно плохие худшие, с ошибкой 32% на моем тесте, в то время как я экспериментирую в районе 14% Аддидивный член масштабирую +-0.1
Если увеличивать веса, средняя ошибка улучшается, но растет максимальная, все чаще появляются неустойчивые конфигурации.

После нормализации дала прибавку ортогонализация. Победила такая версия: на каждом слое, для каждого нейрона, ищу два ближайших нейрона по среднеквадратичному отклонению. И их покомпонентно растаскиваю:
e = (w0i - w1i)*0.08
w0i += e
w1i -= e

Всю процедуру повторяю 20 раз.

Встряска (shake) при заходе в локальный минимум ничего не даёт. Либо в ней бага, либо применяю криво. Хотя раньше я только ей и оптимизировал сеть. До того как пришел к вычислению глобального минимума.
Аватара пользователя
Fouras
Старожил
Старожил
 
Сообщения: 7249
Зарегистрирован: Пн июн 12, 2017 1:23 am
Медали: 11
Пол: Мужской

БК-0010 старца

Сообщение Fouras » Пт май 17, 2019 3:34 am

Восстановил расчет глобального минимума для нейрона. На реальных данных иногда ему хочется задрать веса до космических величин, что понятно. Пришлось изобретать ограничения, но такие, которые сохраняют монотонность производной, чтобы все не пошло прахом. То есть, сейчас, если ему хочется вес сделать больше 3.0, он превращает функцию веса в гиперболу, которая стремиться в бесконечности к 4. Возможно, это еще не все
Аватара пользователя
Fouras
Старожил
Старожил
 
Сообщения: 7249
Зарегистрирован: Пн июн 12, 2017 1:23 am
Медали: 11
Пол: Мужской

БК-0010 старца

Сообщение Fouras » Сб май 18, 2019 3:36 am

Такая мысль посетила.

Слева-направо не получается обучать поскольку справа от слоя все значения вычислены этим же слоем. Ну, то есть, чему обучать, если мы ему что-то подали на вход и у нас только то что на выходе. Разница только в последнем слое, почему и идет back_propogantion.

Но при этом у нас проблема: обучив последний слой, он практически не пропускает производную.

Практически АРИЗ задача.

А если посчитать поправки и гнать их до первого слоя через все слои? Причем там с запасом нагнать, чтобы первому слою было чему учиться. Получится обучение слева-направо. Но зато девственные правые слои будут прекрасно пропускать ошибку. Есть некоторый избыток счета ошибки, но учитывая число эпох для адекватного обучения это пшик. При условии, разумеется, что дело выгорит.
Аватара пользователя
Fouras
Старожил
Старожил
 
Сообщения: 7249
Зарегистрирован: Пн июн 12, 2017 1:23 am
Медали: 11
Пол: Мужской

БК-0010 старца

Сообщение Fouras » Сб май 18, 2019 4:14 am

Почему плохо работало полное обучение нейронов для обучения всей сети. Реально обучить можно только последний нейрон. Он и перекрывал движение ошибки. То есть, для обучения через вычисление глобального минимума для отдельных нейронов, просто необходимо гнать ошибку в начальные слои без обучения промежуточных результатов.
Аватара пользователя
Fouras
Старожил
Старожил
 
Сообщения: 7249
Зарегистрирован: Пн июн 12, 2017 1:23 am
Медали: 11
Пол: Мужской

БК-0010 старца

Сообщение Fouras » Сб май 18, 2019 5:45 am

Поставил последнюю версию по 10 миллионов эпох 5 раз посчитать
средняя ошибка 0.2%
максимальная 0.8%
Минимальная, понятно, 5 нулей после запятой.

А это получается, что рано или поздно сеть выходит на глобальный минимум?

Шэйк не нужен. Если сеть все равно выкарабкивается. Правда, возможно на сложных данных будет все не так просто.

Ортогонализация если и нужна, то какая-то другая. Текущий вариант не улучшает, после окончательной настройки.
Аватара пользователя
Fouras
Старожил
Старожил
 
Сообщения: 7249
Зарегистрирован: Пн июн 12, 2017 1:23 am
Медали: 11
Пол: Мужской

БК-0010 старца

Сообщение Fouras » Пн май 20, 2019 9:00 am

Импульсные нейросети сейчас обучают генетическими алгоритмами. Решений с обучением на ходу сейчас нет, пока только жесткие встраиваемые решения.

Теперь про обычные сети
Для обучения хоть генетическим алгоритмом, хоть полным решением отдельных нейронов, требуется протаскивать ошибку в самые первые слои, и оптимизировать начиная с них. Эффективно учить выходные слои абсолютно бесполезно: обучившись они перекрывают движение ошибки.

Пишу по мере сил (во время компиляций и запусков) forward_propogandion

Идея такая: Гоним ошибку с хвоста до самого первого скрытого слоя. Этот слой как-то обучаем. Прослушал лекцию по генетическому программированию, слава богу я хорошо в теме, ничего нового там не нашлось. Зато я сам могу рассказать всякие штуки. С этим у меня была программа которая оптимизировала 3D модели минимизируя кэш-промахи. N-полная задача. Ох уж там я влез по самые уши в тему. Там были и потопы: при захождении в эволюционный тупик, уничтожались все кроме пары лучших и пары случайных. Оказалось выгодно убогих тащить. Достаточно одного убогого из последнего десятка на поколение. Так он как-то ухитрялся вытолкнуть из локальных минимумов.

Возвращаемся к сетям. Очевидно, что простое решение в лоб: нейрон - это хромосома, веса - это гены. Есть такой вариант, легко догадаться по названию. И понятно, что после обучения слой прекратит пропускать ошибку. Следовательно только слева-направо вести обучение, никак иначе.

И для генетического обучения, и для вычисления по нейрону, нужно решить какого уровня установить ошибку. Думаю так:
порядка 50% от обычных весов на первом слое
ошибка пропорциональна суммарной ошибке на нейроне. то есть, чем хуже работает нейрон, тем сильнее устанавливать разность потенциалов вход-выход-ошибка. Дураков бьём сильнее, а учить умного - только портить.
Аватара пользователя
Fouras
Старожил
Старожил
 
Сообщения: 7249
Зарегистрирован: Пн июн 12, 2017 1:23 am
Медали: 11
Пол: Мужской

БК-0010 старца

Сообщение Fouras » Ср май 22, 2019 4:10 am

Я не представляю когда мне спать.
Сейчас 3 часа делал forward_propagandion с линейной регрессией по каждому нейрону. Суть абсолютно элементарная, но количество индексов и всевозможных массивов просто добивает. Надо переходить на статическую типизацию, на typescript. Но нет времени вникать в него, идеи жгут и не дают покоя.

К back_propagation я добавлю классику:
  • импульс
  • снижение веса к нулю для выхода из больших весов
  • долбить плохие уроки по несколько раз

Помимо классики надо предварительное обучение. И вот для этого:
  • кластеризация уроков чтобы предварительное обучение делать на малой выборке
  • постепенное расширение слоев и нейронов на ходу в процессе обучения
  • ожидаемая бомба: forward_propogandion

И только после всего этого переходить к модели внимания. По-моему, нет смысла начинать с нее.
В какой-то момент думаю запустить генетический алгоритм, он должен заменить Монте-Карло, как более эффективная его реализация. Но надо посмотреть чем закончится forward_propogandion.
Аватара пользователя
Fouras
Старожил
Старожил
 
Сообщения: 7249
Зарегистрирован: Пн июн 12, 2017 1:23 am
Медали: 11
Пол: Мужской

БК-0010 старца

Сообщение Fouras » Ср май 22, 2019 2:33 pm

Посмотрел капсюльные нейросети, это просто фэйспалм.

Чтобы избавиться от макспулинга, а избавляться от него нужно не менее чем с третьего слоя сверточной сети, данные надо хранить в каком-то вероятностном графе, который я вижу так:

Изображение

Красным признаки. Зеленым - связи характерные для данного изображения. Необходима процедура сравнения таких графов с оценкой похожести: могут быть искажены углы, какие-то узлы отсутствовать, какие-то добавлены. И должна быть численная оценка сходства куска графа
Аватара пользователя
Fouras
Старожил
Старожил
 
Сообщения: 7249
Зарегистрирован: Пн июн 12, 2017 1:23 am
Медали: 11
Пол: Мужской

БК-0010 старца

Сообщение Fouras » Сб май 25, 2019 5:17 am

Реализовал в каком-то варианте обучение через расчет минимума нейронов, а для этого гоню ошибку с хвоста в начало и оптимизирую справа-налево. Почему-то в моем тесте он всегда дает почти точно 14% ошибку при стартовой случайной 30%. Наверное, все-таки где-то ошибка. Повторное применение не улучшает а просто колбасит вокруг тех же 14% в обе стороны
Аватара пользователя
Fouras
Старожил
Старожил
 
Сообщения: 7249
Зарегистрирован: Пн июн 12, 2017 1:23 am
Медали: 11
Пол: Мужской

БК-0010 старца

Сообщение Fouras » Пн май 27, 2019 12:46 am

На моём тесте регрессии добавление импульса к распространению ошибки не дало ничего в пределах погрешности.
Ничего не дало усиленное повторение больших ошибок.
Выгон ошибки справа-налево и аналитическое решение регрессии для каждого нейрона дает тем меньше результат, чем сложнее сеть. Причем бесконечно повторять не получается, сходится к какому-то значению и осциллирует вокруг него. Время схождения всего около 8 эпох, выигрыш от 25% до 10% от первоначальной ошибки. Ошибку я не усредняю по урокам, а суммирую, то есть, реальная ошибка от 4 до 2%.

Осталось генетический алгоритм и постепенное расширение пока идет обучение.
Аватара пользователя
Fouras
Старожил
Старожил
 
Сообщения: 7249
Зарегистрирован: Пн июн 12, 2017 1:23 am
Медали: 11
Пол: Мужской

БК-0010 старца

Сообщение Fouras » Пн май 27, 2019 1:52 am

Прежде чем писать генетический алгоритм, решил переписать Монте-Карло.

Сделал так: оптимизирую слои от начального к конечному, чтобы ошибка на выходе не стопорила.
Никуда не распространяю ошибку. Просто случайно меняю четверть весов и смотрю улучшилось ли. Если да, то повторяю это улучшение пока помогает. В противном случае откатываю.

Если долго не было улучшений, процесс прерываю.

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

Из минусов: иногда вообще ничего не находит и сеть висит с плохими результатами. Вероятно, для таких случаев надо увеличивать радиус поиска. Или уменьшать, надо проверять. А ведь ради этого я все это и затеял. Буду надеяться, что тупик градентного спуска не совпадает с тупиком Монту-Карло, все-таки они слишком разные.

Фактически, этот алгоритм точно совпадает с моим самым первым алгоритмом обучения сети 20 лет назад. Разница лишь в том, что комп стал в 10 раз быстрее и экспериментами могут улучшить сходимость.

Теперь смотрю имеет ли смысл строго решать от начала к концу: просто 1 проход с бесконечной долбёжкой Монте-Карло одного слоя. Все верно, результат как при аналитическом решении. Чуть лучше, поскольку там я не откатываю, а просто решаю. А насколько именно возвращать ошибку вверх по слоям - вопрос спорный. Зато теперь убедился, что дело не в алгоритме, а в принципе.
... Хотя нет, там где-то есть ошибка. С этим алгоритмами обучения постоянная мистика: что-то улучшается, но не до конца и кое-как пока есть ошибки. И только с последним исправлением наступает сказка.
Аватара пользователя
Fouras
Старожил
Старожил
 
Сообщения: 7249
Зарегистрирован: Пн июн 12, 2017 1:23 am
Медали: 11
Пол: Мужской

БК-0010 старца

Сообщение Fouras » Вт май 28, 2019 12:36 am

Хороший пример сегментации изображения и дополнения.

Изображение
Аватара пользователя
Fouras
Старожил
Старожил
 
Сообщения: 7249
Зарегистрирован: Пн июн 12, 2017 1:23 am
Медали: 11
Пол: Мужской

БК-0010 старца

Сообщение Fouras » Вт май 28, 2019 4:33 am

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

Рерол дал улучшение и среднего значения, 15% по старту, порядка 1% в заключении после градиентого спуска и добивки шэйком. Зато срезал худшие варианты с 45% до 25%. Достаточно было сделать 8 рандомных генераций и выбрать лучшую. Затем лучшую чуть улучшил рандомными улучшениями в те же случайных 8 шагов. Доводил до 100 рандомных вариантов, выигрыш был пшиковый. Уменьшение начинало увеличивать худшую ошибку из 1000 попыток оптимизировать (по 500 эпох).

Распределение на этот раз сделал нормальное, для аддидивных членов (bias или как он там называется) домножил на 0.2.
Аватара пользователя
Fouras
Старожил
Старожил
 
Сообщения: 7249
Зарегистрирован: Пн июн 12, 2017 1:23 am
Медали: 11
Пол: Мужской

БК-0010 старца

Сообщение Fouras » Ср май 29, 2019 3:14 am

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

Функции для оптимизации очень тяжелые - один вызов от минут до десятков минут. И ищется оптимум для параметра. Один вызов - это сбор статистики по сходимости сети и подбирает глобальный параметр, типа лёрнинг рэйта. Чтобы не руками эксперименты ставить и подбирать.

Чтобы подбирать целочисленные параметры, функция ищет аналоговый, к нему добавляется случайное число от 0 до 1 и округляется. При сборе статистики целочисленные параметры побираются аналогово.

Пожалуй, пора переходить на готовые программные пакеты (Керас, например), и свои изобретения уже вкорячивать туда. Хотелось бы на JS (brain.js), но там с документацией туго, она в виде видео. Что бред. Питон что-то мне не понравился, значит на плюсах. Ну посмотрим, может и питон посмотрю. JS чем хорош - под Хромом он компилятор, доступен везде, под него дифига чего есть и очень просто делать любой сложности интерфейсы. И все удобства интерпретатора сохранены.
Аватара пользователя
Fouras
Старожил
Старожил
 
Сообщения: 7249
Зарегистрирован: Пн июн 12, 2017 1:23 am
Медали: 11
Пол: Мужской

Пред.След.

  • { SIMILAR_TOPICS }
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в Башня старца Фура

Кто сейчас на конференции

Зарегистрированные пользователи: GoGo [Bot], Google [Bot], vadimr, Yandex 3.0 [Bot], Yandex [Bot]