Перейти к содержимому

Krutoy

Гуру
  • Публикации

    482
  • Зарегистрирован

  • Посещение

  • Победитель дней

    72

Все публикации пользователя Krutoy

  1. Krutoy

    LUA Лямбда-исчисление

    Тогда получается количество аргументов в виде параметра не нужно 😮
  2. Krutoy

    LUA Лямбда-исчисление

    @ECS Огонь, большое спасибо! Мне самому не хватало мозгов что бы это написать. Сейчас имплементирую в код и скоро опубликую прогу для робота. Функция правда выглядит громоздко для EEPROM и робота с одной Т1 платой, но ченить придумаю.
  3. Krutoy

    LUA Лямбда-исчисление

    Спасибо, это ближе к решению. Но эта функция неправильно работает, если дефолтные значения nil f = L(function(a, b, c) return 'a:'..tostring(a)..' b:'..tostring(b)..' c:'..tostring(c) end, 'a', nil, 'c') print(f()()()) -- Выводит "a:a b:c c:nil", хотя должно "a:a b:nil c:c" Если же список дефолтных значений кончается на nil, то вообще ошибка: f = L(print, 'a', nil, nil) print(f()()()) -- attempt to call a nil value Хотя возможно, в Lua вообще нельзя посчитать количество значений из ..., если они кончаются на nil. Еще, я расширю задачу в первом посте. Так как Lua умеет работать с множественным возвращением значений из функции, лямбда должна обрабатывать и это. local function L(f, ...) -- ??? end -- Функция для примера - просто выводит три своих параметра local function abc(a, b, c) return '"a:'..tostring(a).. ' b:'..tostring(b).. ' c:'..tostring(c)..'"' end local f = L(abc, 'a', 'b', nil) -- Создаем λ-функцию с тремя значениями по умолчанию -- Должно выводить: print( f(1)(2)(3) ) -- "a:1 b:2 c:3" print( f()()() ) -- "a:a b:b c:nil" print( f(nil, 2)() ) -- "a:a b:2 c:nil"
  4. Krutoy

    LUA Лямбда-исчисление

    Я пишу свой интерпретатор на Lua для роботов. Мне потребовалось использовать лямбда-вычисления. Задача - написать функцию L, где L(f, n) выдавало бы функцию Ln(a1)(a2)(...)(an) которая при выполнении выдает f(a1, a2, ..., an). @ProgramCrafter подсказал написать так: local function L(f,n) if n<=1 then return f else return function(a) return L(function(...) return f(a,...) end, n-1) end end end Такая функция работает при значениях n>=1, но не работает с n=0 f = L(print, 2) f(1)(2) -- печатает: 1 2 f = L(print, 0) f() -- выдает функцию print Вопрос: Нужна функция L, которая принимает в параметр функцию f и дополнительно n аргументов - стандартных значений, которые так же будут показывать количество аргументов. local function L(f, ...) -- ??? end -- Функция для примера - просто выводит три своих параметра local function abc(a, b, c) return '"a:'..tostring(a).. ' b:'..tostring(b).. ' c:'..tostring(c)..'"' end local f = L(abc, 'a', 'b', nil) -- Создаем λ-функцию с тремя значениями по умолчанию -- Должно выводить: print( f(1)(2)(3) ) -- "a:1 b:2 c:3" print( f()()() ) -- "a:a b:b c:nil" print( f(nil, 2)() ) -- "a:a b:2 c:nil"
  5. Линукс, чего? В майнкрафте? Процессоры? Где об этом почитать? Звучит совсем не понятно.
  6. Эх, ностальгия. Почитав тред и посмотрев наработки @Bs0Dd так и хочется натереть ему нос и показать тру-HTML с первоначальной идеей отображать реальные веб-страницы. Но правда, уже полтора года программирую свой 1.12.2 "Эксперт" модпак на ZenScript, и поэтому LUA пока ждет на полке. Еще, изучив VueJS, хочется сразу делать реактивный браузер. Это будет сразу возможностью использовать браузер как GUI. Но, думаю, не скоро. Если кто то всё еще сильно хочет исходников - пишите. Попытаюсь нарыть и залить.
  7. @TaxisT@TaxisTда уже по сути забросил. Так и не смог решить проблему как обучать сеть и пока не появится идея что делать оно не работает нормально
  8. Странно, у меня 1-1 нейроны вообще забивают робота в угол и он крутится вокруг оси.
  9. Веб-версия программы для обучения сети: https://krutoy242.github.io/ Будет тормозить, так как я еще не настроил рендер при экспорте на веб страницу. Небольшое описание как пользоваться: Вы можете: Наслаждаться анимационными понтами на 3 FPS Смотреть как связи между нейронами становятся толще. Например, связь между "копнул вверх" (swing up) и желанием двигаться вверх. Пробовать изменять скорость обучения (learning rate) и смотреть как сеть обучается слишком медленно или встает в тупик. Изменять количество нейронов (Hidden 1 and 2) сети и не понимать вместе со мной почему эффективность от этого почти не меняется. В течении недели я добавлю возможность редактировать входные значения прямо на странице, и тогда вы сможете сами пробовать новые способы обучения.
  10. Уффф, полтора часа видео в 2019 году... Я попробую посмотреть как нибудь. Я не знаю что такое "статичная" или "динамическая" модель. Поясни.
  11. Я покажу как устроена программа. Код будет на языке Moonscript, но думаю будет понятно. При инициализации, я указываю какие параметры будут подаваться на вход. Вторым параметром я указываю зависимость значения на коэффициент полезности. При его подсчете я складываю все значения fn(n) и делю на их количество (в данном случае 8) addInput "tt_swingSuccesSide", "n" , {"swing forward", "swing down", "swing up"} addInput "tt_explored", "n/3", {"explored forward","explored down","explored up"} addInput "tt_closerToSweets", "n*3", {"closer to sweets"} addInput "wasThere", "1-n", {"was there",} В цикле действий, я подаю данные на входе для принятия решения, и выбираю самое большое значение - именно оно и будет выполнено роботом output = nn_activate(input) actKey, actVal = getHigherkv(output) -- actKey индекс с самым большим значением на выходе Затем делаются все действия и собирается новая информация, которая в следующей итерации подается на вход input В конце рассчитывается полезность действия о которой я говорил в самом верху. Именно это значение устанавливается как целевое для обратного распространения ошибки в выбранное действие. А вот с остальными действиями все сложнее. ("конфеткой" я называю блок, в котором (мы не были) and (что то копнули) and (хотя бы один из соседних блоков не разведан) ) Q = input\getQuality() Qi = 1-Q for i=#output, 1, -1 do output[i] = switch i when actKey -- Совершенное действие Q when optimalSide -- Действие, при котором расстояние до последней "конфетки" было бы меньше Qi when oppositeKey -- Обратное действие (вниз-вверх, влево-вправ) output[i]/2 else 0 nn_propagate(output) Детекцию делать в самом простом случае не нужно. swing() уже сам по себе детекция, и говорит, что за блоки у нас вокруг. Я вообще все действия сократил до 5ти - движение и поворот, кроме движения назад. swing() все равно надежнее всего делать каждое действие. Вот мой список действий: robotActions = { -> robot.tryMove(sides.forward) -> robot.tryMove(sides.down) -> robot.tryMove(sides.up) -> robot.turnRight() and false -> robot.turnLeft() and false } Я не понял, зачем нам учитывать в расчетах эффективность движения и обхода? Разве нам не плевать как он двигается, если эффективность добычи нулевая? Или если она 100%? Я к тому, что эффективность добычи - единственный решающий параметр для робота.
  12. В общем я много думал, и это не вариант. Если превратить выходные нейроны во внутренний слои и с них снимать значения, то последний один нейрон а.к.а "полезность" просто настроится всегда показывать 0. Для нейросети это беспроигрышный вариант - робот забился в угол, нейросеть определяет что польза будет 0, и ты ей обратным распространением ошибки подкрепляешь и передаешь 0. В общем, не выйдет так делать. Последние 3 дня работаю над экспортом эмулирующей программы в браузер, но и развлекаюсь добавляя анимации
  13. Целую неделю вожусь с графикой. Это поможет сделать нейросеть более нагляднее. А еще, я собираюсь за эту неделю перевести программу тестирования на HTML5, в браузер, так что каждый сможет попробовать свои собственные формулы для обучения. В интерфейсе можно будет брать любые параметры на входе, рассчитывать их как угодно и выдавать результат нейросети. Посмотрим, вдруг кто то из вас найдет метод лучше чем я. P.S. Зачем удалили сообщения? Норм же общались...
  14. Итак, первый кусочек исходного кода. Это код обычного персептрона, который я использовал в самом начале. Сейчас я юзаю более сложную нейросеть LSTM, но начинал с этой. https://gist.github.com/Krutoy242/e7b6618e8bc180acbe65b515a9ad1755 Это форк с другого кода, но я улучшил скорость работы сети, исправил ошибки и добавил удобства в работе с сетью. В комментах есть описание и пример работы, пользуйтесь на здоровье. Ладно, реализовать такое не сложно, так что попробую. Ну и кто то сказал что на предыдущей гифке ничего не понятно и я добавил больше описаний
  15. Неее, это не сработает. Обучаются то веса связей между нейронами. То есть, будет изменяться не сила выходного значения у скрытого слоя нейронов, а связь с тем самым одним на выходе. По сути, я получу сеть, которая будет обучаться предсказывать максимальную успешность в текущих условиях
  16. Последние три для я переписывал нейросеть synaptic.js на ЛУА. И это получилось великолепно. Теперь я могу моделировать любые связи между нейронами а так же смотреть на работу LSTM сетей "изнутри". А вот и наша LSTM сеть. @Seryoga ты в роде шаришь в сетях, какие параметры в нейронах самые важные что бы их выводить на экран? Я вывожу пока вес связей и активацию. Яркость кружочков отражает из значение активации Белые и голубые линии показывают как сильно значение влияет на связанный нейрон Зеленые и синие сегменты на нейронах указывают на state и bias соответственно Я пока под новую сеть не настроил обучение, так что она еще тупее чем раньше =)) Видимо, мне нужно еще много про RL прочитать. Пока я не понимаю. Я ниче не понял. Поясни пожалуйста, или еще лучше, зарисуй. Ты хочешь создать типа еще один выходной слой с 1 нейроном, сделать предыдущие 5 нейронов выходных - скрытым слоем?
  17. Что то я не понял. Если у меня будет 1 нейрон на выходе, как я буду выбирать какое действие из 5 мне делать?
  18. Я так и делаю. Только, мне не достаточно просто "пинать". У меня есть 5 выходных значений. И если робот ничего не сделал полезного, я в выбранное значение пишу 0. А в остальные 4 чего писать? Я пробовал в остальные и рандом значения, и 1. Но это все не то. Не в моем случае. Здесь, я не буду заниматься обучением сети - она должна стартовать с 0 и сама себя обучать. Спасибо, прочитаю! Как определять время N? Действия? То есть мне на вход подавать выходные значения нормализованные до 0..1 ? Торч работает на .dll и скомпилированных файлах, а значит из майнкрафта его не запустить.
  19. Количество заходов почти ни на что не влияет, так как обычно равно 1 или 0. Например, робот где то на 100 высоте в небе летает - и все блоки первый раз посещает Да и в будущем, будет условие, когда нужно отдавать ресурсы, и тогда он тоже будет посещать блоки не в первый раз. Я думал так сделать, но принципиально хочу остановиться только на возможностях самого майна. Думаю, даже на 4мб можно развиться, главное поднапрячься. Но идея роботов разного уровня конечно нужна. Что бы разные сети занимались разными задачами. Например, что бы просто ходить по направляющим много ума не надо.
  20. Сегодня изменил функцию полезности. Теперь обратное действие (например, поворот направо после поворота налево) имеет в два раза меньше полезности. Робот отреагировал и через 10 поколений по 2000 действий научился срезать по спирали. Правда, он пока не догадался сверху опуститься на 1 блок ниже. Но, я получил рекордный результат - в одно из поколений он вскопал 1500 блоков за 2000 действий. Но это всё равно всё не то. Я не понимаю, почему он, наример, выезжает за ресурсы и продолжает капать вперед. Кстати, вот так выглядит консоль в Sublime Text. kpd - количество действий на количество копаных блоков. Затем идут показатели на входе. Позиция (3), удаленность от последней копки (1), степень разведки (1), удачные копки со сторон (3) 5 значений выходов соответственно, выделенно самое большое, которое и выполняется Позиция по x y z Количество вскопаных блоков Длинная полоска - коэффициент полезности Вконце те значения, которые я отдаю на "обратное распространение ошибки" (а.к.а обучение)
  21. Ок, сейчас задача - срубить как можно больше блоков за как можно меньшее количество действий. Что дальше?
  22. Объясни, почему не подходит? Так я не могу точно знать. Тир0 робот не может пользоваться геоаналайзером. Для него "точно" лишь блоки под, над и перед ним. Этого слишком мало для потенциальных полей. Я не против "захардкодить" простые комбинации. Например, я захардкодил ламать блоки со всех сторон после каждого действия. Но вот дальше я не понял. Допустим, я хочу получить максимум срубленных блоков (забавно, ведь без инвентаря робот даже не лутает). Что за "задача"? Что значит "проработать решение"? PROFIT??
  23. Пока я обучаю себя больше чем нейросеть Сеть должна научиться "быть максимально полезной". Что есть польза - задает программист. В будущем, можно будет задать любое действие как "полезное", и робот сам научится. Это может быть копка ресурсов, выращивание пшеницы, строительство улья. Например, робот-королева поставит рабочего, даст ему в руки 64 кактуса, по "феромонам" - меткам оставленными другими роботами - он поймет что "полезно", это когда блок куда то ставится, и робот пойдет исследовать мир в поисках куда поставить кактус. Оно всегда есть, даже когда ничего не ясно. Например, если он копал прямо по 3 блока подряд за действие, а потом бац, и сразу 0 блоков, значит самым эффективным будет сделать Направо Вперед Направо И тогда с большей вероятностью робот вернется к срезанию слоя. НО! Если прошлый раз до длительного движения прямо он делал то же самое, повороты должны быть в лево (а-ка зигзаг). По спирали тоже можно копать, но зигзагом эффективнее. Весь сахар в том, что программисту не нужно больше хардкорно кодить как двигаться - нейросеть сама это поймет. Я весь во внимании! Предлагай, что можно "кормить" нейросети на вход, из того что может "голый" робот, без компонентов.
  24. Спасибо за радушный прием! Просто, у меня в жизни наконец белая полоса началась и можно заняться любимыми делами.
  25. (проект в разработке) Цель данного проекта - создание нейросети и условий для ее самообучения. В идеале, это будет бомжовый робот минимальной комплектации (возможно даже без жесткого диска), который в зависимости от окружающих условий будет определять свою полезность. Также, он будет "программироваться" снаружи с помощью окружения оставленного другими роботами, формирующими "улей". Апогеем будет саморепликация. Кроме достижения цели, важен и процесс. Наблюдать за самообучением и выбором действий у нейросети очень интересно. Нейросеть изнутри: Мигающие точки - нейроны, линии - синапсы (связи), справа эмулятор мира майнкрафт на движке Love 2d. Нейросети устроены похожим образом. Есть входные значения, скрытые слои и выходные значения. В моей программе робот собирает информацию вокруг себя. На вход подается: Есть ли блоки над, под и перед ним Насколько много клеток он "разведовал" за последнее действие Его позиция в виде значений x,y,z от 0 до 1 Иногда я тестирую со значениями стороны куда он смотрит, возможностью двигаться, расстоянию до последней удачной копки Нейросеть "думает" и выдает 5 значений, которые соответствуют действиям движения 1) вперед, 2) вниз, 3) вверх, 4) вправо, 5) влево. Робот выполняет большее из этих значений. Далее, после действия, я вычисляю коэффициент полезности r [0..1] для этого действия. -- swingSucces: количество вскопанных блоков за действие [0..3] -- input.exploreSucces: коэффициент разведки [0..1], где 0 - уже разводовал все 3 блока, 1 - впервые проверил эти 3 блока -- logic(input.sweetsD < input.old.sweetsD): расстояние до последней удачной копки увеличилось 0, или уменьшилось 1 r = (swingSucces + input.exploreSucces + logic(input.sweetsD < input.old.sweetsD)) / 5 Нейросеь обучается, и в выбранное выходное значение приписывается r a остальные уменьшаются\увеличиваются на 1-r for i=1, #output do output[i] = switch i when actKey (output[i]+val^2)/2 when rndKey (output[i]+(1-val))/2 when oppositeKey (output[i]+(1-val))/4 else output[i] nn:propagate(output) Теперь матан. В начале я использовал обычный Персептрон, найденный готовый на ЛУА, но который мне пришлось править. Проблема в том, что он не может учитывать последние состояния. Нейросети с памятью называются "Long short-term memory" или LSTM, где каждый нейрон выглядит вот так: Найдя библиотеку synaptic.js, хитрыми путями я извлек из нее готовую LSTM сеть, которая получилась на 53 000 строк. Но это не проблема, если зайдет, я перепрограммирую ее на LUA. Текущее состояние сети - отстой. Я неправильно ее обучаю, так как не знаю какие значения выдавать для "обратного распространения ошибки". Круча разные коэффициенты, у меня получилось научить ее двигаться по спирали, как карьерный робот. Сейчас, когда я добавил во входные значения расстояние до последней удачной копки, он научился "кушать" как яблоко, но с огромный количеством лишних действий. В самом майне блоков намного больше и это выглядит вот так. На первом скрине работал 1 робот, на втором штук 6. Сейчас в их действиях слишком много шума. Я специально не даю им кирки, что бы они не унеслись в бесконечность. Фидбек Мне нужно помощь. Подскажите, что лучше подавать на вход, и как обучать сеть. Главная проблема, что для обучения я должен указать какие значения должны быть на выходах при текущих условиях, а я и сам не знаю. Обычно, робот теряется в пустом пространстве и я не знаю какое действие ему казать как "единственно правильное". А так, буду сюда отписываться и отчитываться о процессе разработки. Update 20.06.19, веб-версия эмулятора
×
×
  • Создать...