После многолетнего перерыва я наконец решился взять ещё один отпуск, который провёл за программированием. Целую неделю я смог спокойно работать в режиме отшельника вдали от привычного давления работы. Моя жена великодушно предлагала мне взять такой отпуск вот уже несколько лет, но отпуск и я — это в принципе слабо совместимые вещи.
В качестве смены обстановки после моей текущей работы на Oculus, я хотел написать с нуля на C++ несколько реализаций нейронных сетей, и планировал сделать это, используя строго систему OpenBSD. Кто-то из моих знакомых заметил, что это достаточно случайный набор технологий, но в итоге всё сработало хорошо.
Несмотря на то, что мне не приходилось использовать OpenBSD в своей работе, мне всегда нравилась её идея – это относительно минималистичная и самостоятельная система с целостными видением, а также акцентом на качество и мастерство. Linux способен на многое, но целостность – это не про Linux.
Я не являюсь ярым фанатом Unix. Я неплохо справляюсь с этой операционной системой, но комфортнее всего мне работается в Visual Studio под Windows. Я подумал, что неделя погружения в работу в стиле старой школы Unix по полной будет мне интересна — пусть даже если это и будет означать, что я буду работать медленнее. Это было своего рода приключение в духе ретрокомпьютинга — моими лучшими друзьями на время стали fvwm и vi. Заметьте — не vim, а самый настоящий настоящий vi из BSD.
В конце концов, мне не удалось исследовать систему настолько глубоко, насколько мне хотелось — 95% времени я провёл, занимаясь лишь простыми действиями в vi / make / gdb. Я оценил высокое качество страниц man, поскольку я попробовал делать всё в самой системе, не прибегая к поиску в Интернете. Было забавно увидеть ссылки на вещи, отошедший в прошлое свыше 30 лет назад, вроде терминалов Tektronix.
Я был немного удивлен тем, что поддержка C++ оказалась не на высоте. G++ не поддерживал C++11, LLVM C++ плохо работал с gdb. Gdb неоднократно падал – как мне кажется, из-за проблем с C++. Я в курсе того, что можно через порты (ports) обновиться до свежих версий, но я решил использовать только базовую систему.
Оглядываясь назад, я считаю, что мне стоило просто пойти путём «полного ретро» и написать всё на ANSI C. В моей жизни часто бывают дни, когда я, как и многие программисты постарше, размышляю в следующем духе: «Возможно, в конечном итоге C++ не настолько хорош, как это принято думать...». Мне многое в нём нравится, но мне не в тягость писать небольшие проекты на чистом C.
Возможно, в свой следующий отпуск я попытаюсь пользоваться только одним emacs — это ещё один важный пласт программистской культуры, с котором я так и не успел как следует познакомиться.
У меня есть отличное общее понимание того, как работает большинство алгоритмов машинного обучения, мне приходилось писать линейный классификатор и дерево принятия решений, но по какой-то причине я всегда избегал нейронные сети. В глубине души, я подозреваю что модный «хайп» вокруг машинного обучения пробудил во мне осторожность скептика, и у меня по-прежнему сохраняется некоторая рефлексивная предвзятость насчёт подхода «давайте закинем всё в нейронную сеть, а она пусть там разбирается».
Продолжая придерживаться ретро-тематики, я распечатал несколько старых публикаций Яна Лекуна и собирался производить всю свою работу в оффлайне, словно я действительно нахожусь в горной хижине — но кончилось всё тем, что я пересмотрел многие лекции курса Stanford CS231N на YouTube, и они реально оказались полезными. Я крайне редко смотрю видео лекции в силу того, что обычно мне трудно оправдать для себя столько серьезную трату времени — но в отпуске-то можно себе это позволить.
Не думаю, что у меня есть какие-либо стоящие мысли насчёт нейросетей, которыми стоило бы поделиться — но это была крайне продуктивная для меня неделя, которая помогла превратить теоретически «книжные» знания в реальный опыт.
В работе я воспользовался своим традиционным подходом: сначала быстро получить результат написав наспех грубоватый «хакнутый» код, после чего написать с нуля новую реализацию, основываясь на извлечённых уроках — таким образом, обе реализации будут рабочими, и при необходимости я смогу сравнить их между собой (cross check).
Вначале я пару раз неправильно понял метод обратного распространения ошибки (backprop) — переломным моментом стало сравнение с численным дифференцированием! Мне показалось интересным, что тренировка нейросети идёт даже тогда, когда различные её части могут быть не совсем правильными — пока полученный знак остается правильным большую часть времени, дело зачастую продвигается дальше.
Я остался доволен получившимся кодом моей многослойной нейронной сети; он в той форме, которую я могу просто использовать в своих дальнейших экспериментах. Да, для чего-нибудь серьезного я должен буду использовать существующую библиотеку, но в жизни бывает много случаев, когда удобно, что у вас под рукой есть всего пара .cpp и .h файлов, в которых вы самолично написали каждую строку кода. Мой код для свёрточной нейронной сети (conv net) получился успел дойти лишь до фазы «работает, но с кучей хаков» — я мог бы потратить на него еще день или два для того, чтобы написать ясную и гибкую реализацию.
Мне показалось интересным, что когда я тестировал свою первоначальную нейронную сеть на MNIST (базе данных образцов рукописного написания цифр) прежде, чем добавлять любые свертки, я получил гораздо лучшие результаты, чем указанные значения для не-свёрточных нейросетей (non-convolutional NN), указанных в сравнении ЛеКуна 1998 года — примерно 2% ошибок на тестовом множестве с одним слоем из 100 узлов, против 3% для более широких и глубоких сетей того времени. Думаю, здесь дело в современных лучших практиках — ReLU, Softmax и улучшенной инициализации.
Это и есть одно из самых впечатляющих свойств работы нейронных сетей — все они настолько просты, что прорывные достижения зачастую могут быть выражены всего несколькими строчками кода. Судя по всему, здесь есть некоторое сходство с трассировкой лучей из мира компьютерной графики, где вы можете достаточно быстро реализовать физически корректный трассировщик лучей (physically based light transport ray tracer) и создавать современные изображения, если у вас есть необходимые данные и достаточно терпения, чтобы дождаться результатов выполнения.
Я гораздо лучше разобрался с пониманием принципов перетренировки / генерелизации / регуляризации при помощи изучения нескольких параметров тренировки. В последнюю ночь своего отпуска, я уже не трогал архитектуру и просто игрался с гиперпараметрами. Как оказалось, сохранять концентрацию в то время, пока "она тренируется" оказалось значительно тяжелее, чем в классическом случае, когда "оно компилируется".
Теперь я буду смотреть в оба, чтобы найти подходящую возможность применить новые навыки в в своей работе в Oculus!
Мне страшно даже подумать о том, во что успели превратиться мой почтовый ящик и рабочее место за время моего отсутствия — завтра увидим.
Комментарии (34)
Valsha
16.03.2018 13:50Ну почему это маразм? Человек же отдыхает. Все по разному отдыхают. Вот он пишет на С++ и хотел бы на ANSI C. То что это «старые, не модные смузи технологии», то это его дело. Кто то вон играет на ретро приставках NES и тп девайсах. Это же отдых!!!
nizkopal
16.03.2018 14:18+2Я ожидал от статьи чуть больше интересных подробностей. :)
В целом пост о том, «как я провел лето». Конечно, интересно иногда почитать статьи крутых дядек, даже если они ни о чем. Просто чтобы насладиться их чаще всего нестандартным образом мышления, или замотивированностью их целеустремленностью. Но это, похоже, не тот случай.
В любом случай спасибо переводчику за работу.
Gorthauer87
16.03.2018 18:33+2Интересно, а не думал ли он на пару недель вообще от программирования отключиться? И вообще желательно от всех цифровых девайсов.
Глядишь может быть придумал бы что-нибудь фантастическое.j_wayne
16.03.2018 19:24Это был бы не Джон Кармак. Он программировал Q3 Arena даже в свадебном путешествии на Гавайях.
0xd34df00d
16.03.2018 20:18+1У него хотя бы было свадебное путешествие.
nizkopal
17.03.2018 02:03на Гавайях…
VulvarisMagistralis
17.03.2018 10:57+1на Гавайях…
Это не так уж и дорого, даже если бы он не был миллиардером.
Marui
16.03.2018 21:15-1Недельный отпуск после многолетнего перерыва??? Ничего против Кармака не имею, но это немного странно. Работать после ~30 лет успешного бизнеса. Ему уже 50. Вы скажете, что «ему нравки, отвали». Окей, окей. Его менеджеру, который младше его в 2 раза, это тоже нравки. Никакого абьюза. Скажете, что он сам? Есть мысли, что его просто заваливают работой с заголовком «ты нам нужен, без тебя никак! Отпуск нидадим! Ты должен!». Как абьюзят ботаников в школах. Или Возняка.
aml
16.03.2018 21:57+2Вы не допускали, что для него работа — это не ожидание выходных, а наборот — это и есть самый кайф и отдых?
encyclopedist
16.03.2018 23:29На всякий случай: Кармак — CTO о Окулус. Он сейчас менеджер. Он по работе сам другим указывает что им делать. И судя по всему немного скучает по программистской работе.
JC_IIB
17.03.2018 00:05Ничего против Кармака не имею, но это немного странно. Работать после ~30 лет успешного бизнеса. Ему уже 50. Вы скажете, что «ему нравки, отвали».
Я скажу так — отвали от Кармака.
ankh1989
17.03.2018 05:14+2Он не работает в том смысле в котором мы это понимаем. Даже мелкие менеджеры с 30-40 человеками говорят, что забывают как писать код и потому занимаются этим в отпуске. Кармак же птица намного более высокого полёта и вся его работа это посещать митинги и говорить другим что делать. Теперь почему он вообще этим занимается. Раньше он был сам себе начальник, а теперь вдруг кому то подчиняется. Всё дело в том, что это сильно выгоднее по деньгам и совсем не добавляет обязательств. Есть примеры когда основатели компании делали миллиарды, а потом становились менеджерами с 3-4к человек в большой корпорации — даже для миллиардера это серьёзный оффер. А зачем вообще ему ещё больше денег? Ну хороший самолёт стоит немало. Яхты там всякие, обслуживание всего этого добра.
ATwn
16.03.2018 22:50Жена Кармака — золотой человек, не отвлекает от работы даже во время отпуска :)
Вот повезло в жизни мужику!
asmrnv777
17.03.2018 07:45-3Кодить в отпуске… Странно это.
sanrega
17.03.2018 13:11+2по крайней мере, он кодит, в отличие он инфантильных веб-макак, которые грызут себя (и сообщество) душераздирающими вопросами «Нужно ли программисту знать математику?», «Как заставить себя работать так чтобы не перетрудиться?», и «Как выучить английский с нуля, чтобы не учить, но выучить?»
slonm
17.03.2018 11:33Странно что многие комментирующие воспринимают слово отпуск как синоним отдыха. Отпуск != отдых. Отпуск это просто временный отход от долговременных дел. Существует даже понятие творческий отпуск для таких случаев, как в статье
novikovag
Кармак впал в маразм, теребя мертвые кресты и тупиковые нейронные сети.
JC_IIB
Видимо, кто-то задался получить ачивку «Тролль», усердно оставляя провокационные комментарии.
Jamdaze
Начинать новый проект на с++ до 11-ой версии это и правда маразм. Как можно испытывать настальгию к старым версиям с++, это же такое убожество.
Kobalt_x
Очень легко, если ваши таргеты это мейнфреймы которые уже вендор не поддерживает, а поддержка процессора в GCC можно сказать отсутствует
mwizard
Тоньше нужно.
fukkit
Имеет право.
0xd34df00d
Тут как раз C++ WG meeting проходит, и плюсы живее всех живых.