Krutoy
-
Публикации
482 -
Зарегистрирован
-
Посещение
-
Победитель дней
72
Сообщения, опубликованные пользователем Krutoy
-
-
@ECS Огонь, большое спасибо!
Мне самому не хватало мозгов что бы это написать.
Сейчас имплементирую в код и скоро опубликую прогу для робота. Функция правда выглядит громоздко для EEPROM и робота с одной Т1 платой, но ченить придумаю.
-
2
-
-
1 час назад, ECS сказал:В общем, не уверен, что я правильно понял задачу, но ТЗ из второго примера результат соответствует
Спасибо, это ближе к решению.
Но эта функция неправильно работает, если дефолтные значения 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"
-
1
-
-
Я пишу свой интерпретатор на 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"
-
1
-
-
4 часа назад, Bs0Dd сказал:Они кстати, уже успели перейти в разряд готового браузера, но заниматься его улучшением мне совершенно некогда по причине учебы, а потом наверняка что-то другое навалится...
Кстати, если уж хочется крутить реальные веб-страницы, это вам в OpenComputers II (который еще не готов, но что-то делать уже можно). Там RISC-V, Линукс, помимо Луа можно много на чем писать, но атмосфера уже немного не та...
Линукс, чего? В майнкрафте? Процессоры?
Где об этом почитать? Звучит совсем не понятно.
-
Эх, ностальгия.
Почитав тред и посмотрев наработки @Bs0Dd так и хочется натереть ему нос и показать тру-HTML с первоначальной идеей отображать реальные веб-страницы.
Но правда, уже полтора года программирую свой 1.12.2 "Эксперт" модпак на ZenScript, и поэтому LUA пока ждет на полке.
Еще, изучив VueJS, хочется сразу делать реактивный браузер. Это будет сразу возможностью использовать браузер как GUI.
Но, думаю, не скоро.
Если кто то всё еще сильно хочет исходников - пишите. Попытаюсь нарыть и залить.
-
-
1 час назад, Doob сказал:По одному LSTM на каждом слое, выдает почти идеальный результат. Заметил, что повороты оцениваются строже, чем это реализовано в механике мода.
Странно, у меня 1-1 нейроны вообще забивают робота в угол и он крутится вокруг оси.
-
Веб-версия программы для обучения сети:
Будет тормозить, так как я еще не настроил рендер при экспорте на веб страницу.
Небольшое описание как пользоваться:
Вы можете:
- Наслаждаться анимационными понтами на 3 FPS
- Смотреть как связи между нейронами становятся толще. Например, связь между "копнул вверх" (swing up) и желанием двигаться вверх.
- Пробовать изменять скорость обучения (learning rate) и смотреть как сеть обучается слишком медленно или встает в тупик.
- Изменять количество нейронов (Hidden 1 and 2) сети и не понимать вместе со мной почему эффективность от этого почти не меняется.
В течении недели я добавлю возможность редактировать входные значения прямо на странице, и тогда вы сможете сами пробовать новые способы обучения.
-
2
-
1
-
23 часа назад, Doob сказал:Тут чувак интересно рассказывает, ч
Уффф, полтора часа видео в 2019 году... Я попробую посмотреть как нибудь.
23 часа назад, Doob сказал:статичную модель
Я не знаю что такое "статичная" или "динамическая" модель. Поясни.
-
В 16.06.2019 в 05:09, Doob сказал:Как ты его обучаешь?
Я покажу как устроена программа. Код будет на языке 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)
В 16.06.2019 в 05:09, Doob сказал:move() - 4 штуки
turn() - 2 шт.
swing() - 3 шт.
detect() - 3 шт.14 бит информации
Детекцию делать в самом простом случае не нужно. swing() уже сам по себе детекция, и говорит, что за блоки у нас вокруг.
Я вообще все действия сократил до 5ти - движение и поворот, кроме движения назад. swing() все равно надежнее всего делать каждое действие.
Вот мой список действий:
robotActions = { -> robot.tryMove(sides.forward) -> robot.tryMove(sides.down) -> robot.tryMove(sides.up) -> robot.turnRight() and false -> robot.turnLeft() and false }
В 16.06.2019 в 05:09, Doob сказал:Эффективность движения/поворотов [кол-во шагов] / [кол-во повторных шагов]
Эффективность обхода
Я не понял, зачем нам учитывать в расчетах эффективность движения и обхода? Разве нам не плевать как он двигается, если эффективность добычи нулевая? Или если она 100%? Я к тому, что эффективность добычи - единственный решающий параметр для робота.
-
В 03.06.2019 в 17:20, Doob сказал:Точно так. Самый простой способ обучения.
В общем я много думал, и это не вариант.
Если превратить выходные нейроны во внутренний слои и с них снимать значения, то последний один нейрон а.к.а "полезность" просто настроится всегда показывать 0. Для нейросети это беспроигрышный вариант - робот забился в угол, нейросеть определяет что польза будет 0, и ты ей обратным распространением ошибки подкрепляешь и передаешь 0.
В общем, не выйдет так делать.
Последние 3 дня работаю над экспортом эмулирующей программы в браузер, но и развлекаюсь добавляя анимации
-
7
-
-
Целую неделю вожусь с графикой. Это поможет сделать нейросеть более нагляднее.
А еще, я собираюсь за эту неделю перевести программу тестирования на HTML5, в браузер, так что каждый сможет попробовать свои собственные формулы для обучения. В интерфейсе можно будет брать любые параметры на входе, рассчитывать их как угодно и выдавать результат нейросети. Посмотрим, вдруг кто то из вас найдет метод лучше чем я.
P.S. Зачем удалили сообщения? Норм же общались...
-
4
-
-
Итак, первый кусочек исходного кода.
Это код обычного персептрона, который я использовал в самом начале. Сейчас я юзаю более сложную нейросеть LSTM, но начинал с этой.
https://gist.github.com/Krutoy242/e7b6618e8bc180acbe65b515a9ad1755
Это форк с другого кода, но я улучшил скорость работы сети, исправил ошибки и добавил удобства в работе с сетью.
В комментах есть описание и пример работы, пользуйтесь на здоровье.
В 04.06.2019 в 12:35, Doob сказал:Все легко настраивается, не вижу никаких проблем с получением нужных результатов.
Ладно, реализовать такое не сложно, так что попробую.
Ну и кто то сказал что на предыдущей гифке ничего не понятно и я добавил больше описаний
-
2
-
-
17 часов назад, Doob сказал:Точно так. Самый простой способ обучения.
Неее, это не сработает. Обучаются то веса связей между нейронами. То есть, будет изменяться не сила выходного значения у скрытого слоя нейронов, а связь с тем самым одним на выходе.
По сути, я получу сеть, которая будет обучаться предсказывать максимальную успешность в текущих условиях
-
Последние три для я переписывал нейросеть synaptic.js на ЛУА. И это получилось великолепно. Теперь я могу моделировать любые связи между нейронами а так же смотреть на работу LSTM сетей "изнутри".
А вот и наша LSTM сеть.
@Seryoga ты в роде шаришь в сетях, какие параметры в нейронах самые важные что бы их выводить на экран? Я вывожу пока вес связей и активацию.
- Яркость кружочков отражает из значение активации
- Белые и голубые линии показывают как сильно значение влияет на связанный нейрон
- Зеленые и синие сегменты на нейронах указывают на state и bias соответственно
Скрытый текст
Я пока под новую сеть не настроил обучение, так что она еще тупее чем раньше =))
20 часов назад, Seryoga сказал:Не, это не входные данные для FFNN, это входные параметры для семейства алгоритмов RL.
Видимо, мне нужно еще много про RL прочитать. Пока я не понимаю.
20 часов назад, Doob сказал:Выходной нейрон - корректирующий, перерасчет весов будет происходить в зависимости от свойств данных.
При ошибке, обратное распространение начнется не с нейронов, отвечающих за действие, а с корректирующего. Это значит, что веса на последнем слое будут адаптироваться к режиму обучения и корректировать выходы именно с теми коэффициентами, которые больше всего подходят.
Я ниче не понял. Поясни пожалуйста, или еще лучше, зарисуй.
Ты хочешь создать типа еще один выходной слой с 1 нейроном, сделать предыдущие 5 нейронов выходных - скрытым слоем?
-
1
-
2 минуты назад, Doob сказал:Ничего не писать, если надо упростить - объединяем все выходы в один нейрон. При ошибке, веса будут корректироваться на всех действиях. Тут даже можно на выходной нейрон давать не 0/1, а число в диапазоне, характеризующие "удачность" или "правильность" действия с точки зрения учителя.
Что то я не понял. Если у меня будет 1 нейрон на выходе, как я буду выбирать какое действие из 5 мне делать?
-
В 31.05.2019 в 16:29, Doob сказал:Робот был на этом блоке - пинаем его. Не смог сломать блок или переместиться, пинаем сильнее. Сделал много шагов от точки старта - пинаем пропорционально расстоянию, с учетом первого условия
Я так и делаю. Только, мне не достаточно просто "пинать". У меня есть 5 выходных значений. И если робот ничего не сделал полезного, я в выбранное значение пишу 0. А в остальные 4 чего писать?
Я пробовал в остальные и рандом значения, и 1. Но это все не то.
В 31.05.2019 в 16:29, Doob сказал:Обученную сеть расширять это довольно странно и больно,
Поэтому сначала определяют функционал
Не в моем случае. Здесь, я не буду заниматься обучением сети - она должна стартовать с 0 и сама себя обучать.
23 часа назад, Seryoga сказал:Можешь почитать про Reinforcement Learning.
Спасибо, прочитаю!
23 часа назад, Seryoga сказал:Скор --- количество блоков выкопанное за время N
Действия --- действия робота.
Состояние --- блоки от робота в радиусе RКак определять время N?
Действия? То есть мне на вход подавать выходные значения нормализованные до 0..1 ?
23 часа назад, Seryoga сказал:pss. Для lua есть библиотека Torch
Торч работает на .dll и скомпилированных файлах, а значит из майнкрафта его не запустить.
-
9 часов назад, Doob сказал:количества заходов робота на этот блок
Количество заходов почти ни на что не влияет, так как обычно равно 1 или 0. Например, робот где то на 100 высоте в небе летает - и все блоки первый раз посещает
Да и в будущем, будет условие, когда нужно отдавать ресурсы, и тогда он тоже будет посещать блоки не в первый раз.
1 час назад, AtomicScience сказал:через интернет-карту к реальному компьютеру
Я думал так сделать, но принципиально хочу остановиться только на возможностях самого майна. Думаю, даже на 4мб можно развиться, главное поднапрячься.
Но идея роботов разного уровня конечно нужна. Что бы разные сети занимались разными задачами. Например, что бы просто ходить по направляющим много ума не надо.
-
Сегодня изменил функцию полезности. Теперь обратное действие (например, поворот направо после поворота налево) имеет в два раза меньше полезности.
Робот отреагировал и через 10 поколений по 2000 действий научился срезать по спирали. Правда, он пока не догадался сверху опуститься на 1 блок ниже. Но, я получил рекордный результат - в одно из поколений он вскопал 1500 блоков за 2000 действий.
Скрытый текст
Но это всё равно всё не то. Я не понимаю, почему он, наример, выезжает за ресурсы и продолжает капать вперед.
Кстати, вот так выглядит консоль в Sublime Text.
- kpd - количество действий на количество копаных блоков.
- Затем идут показатели на входе. Позиция (3), удаленность от последней копки (1), степень разведки (1), удачные копки со сторон (3)
- 5 значений выходов соответственно, выделенно самое большое, которое и выполняется
- Позиция по x y z
- Количество вскопаных блоков
- Длинная полоска - коэффициент полезности
- Вконце те значения, которые я отдаю на "обратное распространение ошибки" (а.к.а обучение)
Скрытый текст
-
1 час назад, Doob сказал:Программа должна решать какую-то задачу, для этого надо ее составить.
Если у задачи нет цели, то невозможно получить результата на нейронке - кнуты и пряники никуда не ведут, обратное распространение ошибки рассчитывать не из чего.
Ок, сейчас задача - срубить как можно больше блоков за как можно меньшее количество действий. Что дальше?
-
52 минуты назад, Doob сказал:но не подходит для текущей задачи
Объясни, почему не подходит?
54 минуты назад, Doob сказал:надо точно знать, где есть нужный блок.
Так я не могу точно знать. Тир0 робот не может пользоваться геоаналайзером. Для него "точно" лишь блоки под, над и перед ним. Этого слишком мало для потенциальных полей.
56 минут назад, Doob сказал:придется весь алгоритм захардкодить.
- Выбираем, что надо получить от робота.
- Составляем задачу.
- Разрабатываем решение.
- Профит.
Я не против "захардкодить" простые комбинации. Например, я захардкодил ламать блоки со всех сторон после каждого действия.
Но вот дальше я не понял.
Допустим, я хочу получить максимум срубленных блоков (забавно, ведь без инвентаря робот даже не лутает).
Что за "задача"? Что значит "проработать решение"? PROFIT??
-
1 час назад, Alex сказал:Чему она должна обучиться? Что в конечном итоге должен делать "обученный" робот?
Пока я обучаю себя больше чем нейросеть
Сеть должна научиться "быть максимально полезной". Что есть польза - задает программист. В будущем, можно будет задать любое действие как "полезное", и робот сам научится. Это может быть копка ресурсов, выращивание пшеницы, строительство улья.
Например, робот-королева поставит рабочего, даст ему в руки 64 кактуса, по "феромонам" - меткам оставленными другими роботами - он поймет что "полезно", это когда блок куда то ставится, и робот пойдет исследовать мир в поисках куда поставить кактус.
2 часа назад, Alex сказал:когда не будет никакого "единственно правильного" или наиболее правильного решения
Оно всегда есть, даже когда ничего не ясно.
Например, если он копал прямо по 3 блока подряд за действие, а потом бац, и сразу 0 блоков, значит самым эффективным будет сделать
- Направо
- Вперед
- Направо
И тогда с большей вероятностью робот вернется к срезанию слоя.
НО! Если прошлый раз до длительного движения прямо он делал то же самое, повороты должны быть в лево (а-ка зигзаг). По спирали тоже можно копать, но зигзагом эффективнее.Весь сахар в том, что программисту не нужно больше хардкорно кодить как двигаться - нейросеть сама это поймет.
2 часа назад, Alex сказал:больше данных для обучения сети
Я весь во внимании! Предлагай, что можно "кормить" нейросети на вход, из того что может "голый" робот, без компонентов.
-
2 минуты назад, Alex сказал:неужели ты к нам вернулся?!
п.с. не важно, что подавать на вход... Главное - не пропадай и радуй нас своими программками:)
Спасибо за радушный прием!
Просто, у меня в жизни наконец белая полоса началась и можно заняться любимыми делами.-
3
-
-
(проект в разработке)
Цель данного проекта - создание нейросети и условий для ее самообучения. В идеале, это будет бомжовый робот минимальной комплектации (возможно даже без жесткого диска), который в зависимости от окружающих условий будет определять свою полезность. Также, он будет "программироваться" снаружи с помощью окружения оставленного другими роботами, формирующими "улей". Апогеем будет саморепликация.
Кроме достижения цели, важен и процесс. Наблюдать за самообучением и выбором действий у нейросети очень интересно.
Нейросеть изнутри:
Мигающие точки - нейроны, линии - синапсы (связи), справа эмулятор мира майнкрафт на движке 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, веб-версия эмулятора
Скрытый текстВеб-версия программы для обучения сети:
Будет тормозить, так как я еще не настроил рендер при экспорте на веб страницу.
Небольшое описание как пользоваться:
Вы можете:
- Наслаждаться анимационными понтами на 3 FPS
- Смотреть как связи между нейронами становятся толще. Например, связь между "копнул вверх" (swing up) и желанием двигаться вверх.
- Пробовать изменять скорость обучения (learning rate) и смотреть как сеть обучается слишком медленно или встает в тупик.
- Изменять количество нейронов (Hidden 1 and 2) сети и не понимать вместе со мной почему эффективность от этого почти не меняется.
-
9
-
7

LUA Лямбда-исчисление
в Lua
Опубликовано:
Тогда получается количество аргументов в виде параметра не нужно 😮