Pull to refresh
60
0
Алексей @trehleb

Программист

Send message

Все просто :) В репозитории я создаю эксперименты по мере изучения новых топиков (CNN, RNN, GAN и так далее). До Трансформеров еще не дошел. Но спасибо за подсказку, посмотрю в сторону Трансформеров также.

Данные должны обновляться раз в сутки. Но я сегодня увидел "DEPRICATED WARNING" уведомление. Планирую переключиться на использование новых файлов из того-же репозитория.

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


Модель первого нейрона: y1 = w1 x1 + b1
Модель второго нейрона: y2 = w2
x2 + b2


Если нейроны без функции активации, то можем считать, что выход первого нейрона подаётся на вход второго: x2 = y1.


В итоге два нейрона суммарно на выходе дадут:


y2 = w2 (w1 x1 + b1) + b2
y2 = w1 w2 x1 + w2 * b1 + b2


y2 — предсказываемое значение модели,
x1 — входное значение модели.


Для большей прозрачности можем переименовать переменные:


yPredicted = w1 w2 x + w2 * b1 + b2


Ошибку одного предсказания будем считать как и раньше:


predictionCost = (yCorrect — yPredicted)^2 / 2


predictionCost = (yCorrect — w1 w2 x — w2 * b1 — b2)^2 / 2


Далее находим среднюю ошибку для всего набора тренировочных данных:


averageCost = 1/m * SUM[predictionCost]


И теперь, чтобы оптимизировать параметр каждого нейрона в отдельности, нужно взять 4 частных производных от averageCost (назовём эту функцию, как C, для простоты дальнейшей записи:


dC/dw1
dC/db1
dC/dw2
dC/dn2


Найдя эти четыре производные можем делать градиентный спуск (корректировку параметров):


w1 := w1 — dC/dw1


и так далее...

Если не ошибаюсь, то после введения функции активации (например Сигмойда) итоговая зада, которую будет решать сеть и каждый нейрон в частности будет скорее задачей классификации (true/false), чем задачей регрессии (предсказания конкретного значения).

Каждый нейрон на выходе будет иметь число от 0 до 1, которое будет «говорить» о его «уверенности» в чем-то.

Если на выходе всей сети будет всего один нейрон, то вся сеть в итоге может служить классификатором true/false. Например, имеем на входе 400 пикселей картинки на которой изображена собака и сеть нам «говорит», что, пускай, с вероятностью в 0.89 на входе была собака. Значение выходного нейрона в 0.34 будет говорить, что скорее всего на входе была не собака.

Если на выходе сети два нейрона, то каждый из них может отвечать за свой класс, например первый нейрон будет говорить об «уверенности» сети, что на входе сети изображена «Собака», второй нейрон определяет, что изображен «Кот». В итоге мы на вход сети мы будем давать фото (пиксели), на выходе иметь две вероятности (пускай 0.3 для собаки и 0.9 для кота), можем выбрать большее значение и сказать, что «сеть думает, что на картинке изображен кот».

Если же нужно все-таки «предсказывать» конкретную не дискретную цифру (например стоимость аренды квартиры через месяц на основании данных о квартире, районе, динамике рынка и пр.) то можно использовать методы регрессии. Кстати очень хорошая обзорная статья — Машинное обучение для людей.
  1. По поводу подбора скорости обучения альфа я, к сожалению, на данный момент не знаю лучших практик. Сейчас делаю это простым подбором, эмпирически. Помогает построение графика зависимости погрешности от эпох. Если график растёт или убывает с последующим возрастанием — это может быть признаком того, что, возможно, нужно уменьшить скорость обучения. Хаотичность графика так-же может говорить об этом (признак пропущенного минимума, возращение назад, пропуская минимум снова, опять вперёд, пропуская минимум и так далее). Уменьшать можно шагами нелинейно, чтобы быстрее найти подходящий размер шага (0.05, 0.005, 0.0005, назад 0.0008, 0.0001 — снова таки, это не правило, а скорее эмпирический опыт). Рост погрешности с каждой последующей итерацией так же может быть признаком того, что входные данные надо нормализировать (усреднить и сдвинуть к нулю). Если нейронов несколько (по глубине), возможно введение функции активации поможет избежать «взрыва» (резкого увеличения) параметров нейронов и в итоге погрешности.


  2. По поводу набора тренировочных данных и их количества. В случае с нано-нейроном мы пытались имитировать очень простую и, что наиболее важно, линейную зависимость. Мы это знали заранее. И, действительно, для того, чтобы провести линию правильно может хватить всего двух точек (двух экземпляров тренировочных данных). Но нано-нейрон — упрощенный пример. В реальной жизни мы бы не знали линейная эта зависимость или гораздо более сложная (полиномиальная? синусоидальная? логарифмическая? комбинация всех вместе взятых? ещё более сложная?). В этом случае, чем больше данных для обучения нам удастся раздобыть, тем лучше. Большее количество данных никогда не помешает точности нашего алгоритма (может правда замедлить скорость обучения). Так же, кроме тренировочных данных, важно иметь набор тестовых данных, по которому мы сможем судить, что наш алгоритм не «переучился» или не «недоучился» (bias vs variance issue) и правильно имитирует закономерности в тренировочных данных. По поводу диапазона данных. Если мы собираемся использовать наш нано-нейрон для конвертирования температуры в диапазоне [-40, +60], то соответсвенно и данные для тренировки и для тестирования должны быть тоже из этого диапазона. В случае с нано-нейроном это был диапазон [0, 100] снова таки для простоты. Нужно понимать, что если мы натренировали нано-нейрон на диапазоне [0, 100], то теоретически, использовать его для предсказания (конвертирования) температуры вне этого диапазона — нежелательно (может быть непредсказуемый результат в случае с нелинейными зависимостями


Да, все верно, функция нейрона (модель) может быть любой. Насколько я знаю, наиболее распространенный вариант для модели нейрона — линейная функция. В нашем случае нано-нейрон имеет всего один вход, поэтому функция выглядит как y = w * x + b (всего один вход х). В случае нейронной сети, каждый нейрон будет иметь не один, а несколько входов (количество входов m равно количеству нейронов в предыдущем слое) и тогда модель нейрона немного усложнится, но все-равно останется линейной:

Y = W1 * X1 + W2 * X2 + ... + Wm *Xm + b

где, Xn — это n-й вход нейрона, а Wn — это n-й параметр нейрона (отвечает за восприимчивость нейрона к числу на входе Xn).

Далее, модель нейрона имеет непосредственное влияние на функцию ошибки (погрешности). То есть нельзя изменить модель нейрона не изменив итоговую формулу расчета функции погрешности.

Минимизируем мы именно функцию ошибки, поскольку она отвечает за то, насколько наш нейрон прав или неправ и мы хотим, чтобы его ошибка свелась к минимуму.

В нейронной сети выходной сигнал нейрона пропускается еще через дополнительную функцию активации (тот же Sigmoid или ReLu). То есть если бы мы использовали функцию активации (назовем ее Z) для нано-нейрона, то его выход/активация вычислялась бы по формуле a = Z(y), где y = w * x + b, а z = 1 / (1 + e^(-x)). В этом случае, использование функции активации повлияло бы на функцию оценки и повлияло бы в итоге на ее производную.

Я опустил эти детали в статье (много входов у нейрона и его последующая активация) для того, чтобы формулы были как-можно проще, для простоты изложения.
Производная берется не от модели, а от «функции ошибки (погрешности)». В тексте выше это формула avarageCost (производная от: 1/m * SUM[(y — prediction) ^ 2 / 2]). Ведь мы хотим найти минимум не для формулы предсказания модели, а для функции, которая описывает насколько прав/неправ наш нейрон.
Andronas, да я Вас понимаю, было бы здорово иметь много хорошего материала (статей, лекций, приложений) на более понятном языке. Мне кажется причина уклона в английский язык заключается во влиянии… Влияние, которое оказывают англоязычные программисты в той же сфере машинного обучения, по моему субъективному мнению, на порядок выше. Чтобы далеко не ходить можно взять, например, TensorFlow или NumPy библиотеки, упомянутые в статье, или курс по машинному обучению от Andrew Ng — это все создано или описано именно англоязычным сообществом. В итоге и возникает то самое влияние, которое определяет «моду» в сфере программирования и машинного обучения в частности.
Да, Вы правы, опечатка. Поправил.
PyCharm — отличный и действительно помогает правильно писать.

Я интегрировал консольный Pylint c целью:
— сделать процесс проверки кода IDE-независимым
— сделать процесс проверки готовым к Continuous Integration.

В итоге репозиторий может быть использован одинаково как программистами пишущими в PyCharm, так и пишущими в VSCode, в Vim, в Sublime и в <Вставьте свое название редактора>. Причем результат «линтирования» будет одинаковым для всех случаев и независимым от реализации каждого конкретного IDE-плагина.

Более того, тот же самый процесс «линтирования» с теми же самыми правилами (файл pylintrc в корне проекта) может быть запущен на сервере (в данном случае Travis-CI) для проверки каждого нового pull-request-а на соответствие общим правилам написания кода.
Да, все верно, O(log(n)) для сбалансированного дерева и O(n) в худшем несбалансированном случае. Я обновил табличку в репозитории и добавил комментарий к BST.
Указанный вариант сложности предполагает как-раз «плохую» хеш-функцию, так, что все данные будут попадать в одну ячейку. Я обновил табличку в репозитории и указал, что в случае с идеальной хеш функцией сложность будет действительно O(1).
Да, Вы правы, что поиск/вставка/удаление будут линейными в hash table, но это при условии хорошо подобранной хеш-функции.

В табличке я указал O(n) для самого худшего случая, когда все данные попадают в одну «ячейку». Далее уже сложность зависит от реализации этой самой «ячейки» (массив это или linked list или что-то еще).

Я обновил табличку в репозитории и в комментариях указал этот нюанс.
Да, делал для себя, хотелось в одном месте собрать полезную информацию по алгоритмам и попрактиковаться заодно.
Ещё возможно было бы интересно увидеть статью с псевдо «иностранными» фразами, но на русском или украинском языках. Типа «Кум теля пасе, кума лён тре» :) Вроде бы говоришь на своём, а звучит по «забугорному» :)
Хотите научить англичанина говорить по-русски «Я люблю Вас» — попросите его быстро признести «Yellow-blue bus» и дело сделано, хех :)
image
Такими перегородками наверное можно смекалку развивать:
Смекалистые перегородки
Покупатель и продавец-консультант в кулинарии AppleStore:
— Ух-ты, торт «iPhone»? А расскажите про начинку, что в нём?
— Ну это имиджевый торт, весит 135 гр., начинка обычно яблочная. Были правда на Украине и в Белоруссии некоторые проблемы с «санстанцией», этот торт запрещали продавать, но сейчас не об этом… В общем — это торт, с которым не стыдно ходить по улице :)
Я конечно за то, чтобы навсегда забыть про IE6 :) Но при разработке сайта всё-таки стоит учитывать на какую целевую аудиторию он рассчитан.

Например статистика от Liveinternet для русскоязычного интернета
на 4 августа 2009 года «говорит» (или «говорила», если вы будете смотреть позже 4-го
числа :)), что в среднем за последние три месяца доля пользователей IE6 составила 16,1%.

Конечно этот процент будет падать, но ИМХО на сегодняшний день думаю не многие заказчики захотят терять 16% потенциальных клиентов.
У нас в блоге есть что-то похожее, правда криптографией там и не пахнет, просто анимация из преобразованных в текст картинок :)

Преобразование делалось на PHP, потом полученные картинки вставлялись во Флеш. Ооочень не оптимальная схема, но… получилось то, что получилось :)
1

Information

Rating
Does not participate
Location
Киев, Киевская обл., Украина
Date of birth
Registered
Activity