[Из песочницы] Разработка аналога FindFace одним школьником
История от первого лица
Как сделать аналог FindFace в одиночку и не сойти с ума
И почему так делать не надо
Как все начиналось
Шел 2015 год. Я учился в средней школе, очень сильно увлекался программированием. На чем только не программировал. Участвовал в разных технических конкурсах. После одного из них у меня появилась идея сделать штуку, которая сможет распознавать лица и находить человека в вк. Ну, как всегда, все великое из-за девушек. Ну, вы поняли.
Потом в 2016 вышел FindFace. Но я все-таки делал разные наработки, алгоритмы, просто для себя, мне было интересно.
Потом я занимался разными другими проектами по программированию, и отложил на будущее.
В марте 2017 года я решил объединить свои наработки, написать много чего еще и сделать его аналог.
Приступая к разработке. Техническая часть
В разработке используется нейронная сеть, которая разбивает лицо на части и ищет точки — дескрипторы. Если посчитать евклидово расстояние между ними, мы сможем определить близость-удаленность между двумя лицами на разных фотографиях.
Сейчас существует много алгоритмов компьютерного зрения, например, OpenCV. Но для моего проекта они не насколько точны и быстры, поэтому пришлось придумать разные способы оптимизации, переписать некоторые части, а также написать многое с нуля. Если честно, это был ад. Если бы я знал, что там будет, я бы никогда не начал.
Сам поиск по базе выполняется по тому же принципу, только с разными разработанными мною оптимизациям.
Когда я запускал поиск по всей базе в первые разы, он шел очень долго — несколько минут для одной фотографии.
Я думал, это конец. И придется закончить проект. Я не спал несколько дней, но все-таки придумал, как оптимизировать. И наконец-то выпустил бету. Сейчас поиск идет в среднем 0.25 секунды по всей базе на одно фото. Сервер может сделать 15000–25000 поисков в час.
К релизной версии, я думаю ускорить поиск, как минимум в 2 раза, за счет некоторых идей в моей голове. Почему я не написал это сейчас? Потому что, банально, устал.
Также можно легко ускорить скорость за счет улучшения серверов и их количества.
Еще иногда падает сервер. Я пока не знаю, почему так происходит. Но догадываюсь. Но это не точно.
Серверная часть
В серверной части используется PHP. Да, банально. Не, Node.JS. Пока без memcached, redis и др. Но как нагрузки значительно вырастят, оптимизирую этот момент.
В начале я думал просто написать php-скрипт к каждому методу. Но хорошо, что быстро понял, что это плохая идея. И решил сразу делать нормальный api, который уже вырос в несколько тысяч строк кода.
Насчет скорости дисков. Я не измерял, но по моим ощущениям, SDD-диски на серверах работают со скоростью HDD на домашнем компьютере. Нет, конечно, немного быстрее, но все же не так быстро как хотелось бы. А про HDD лучше вообще не говорить, тормозят ужасно.
Также сначала я использовал виртуальные сервера VDS из-за более дешевой стоимости, чем выделенные сервера. Но понял, что если надо делать много вычислений, как в моем проекте, которые хранятся в ОЗУ и кэше процессора, использовать VDS очень плохая идея. Я думаю, так происходит из-за того что на VDS запускается несколько виртуальных машин, и кэш процессора делится на все виртуальные машины. Из-за этого скорость вычислений может очень сильно прыгать. Поэтому используйте выделенные сервера, у них практически всегда постоянная скорость вычислений.
Android
Что рассказать про Android? Обычный клиент, который сейчас поддерживает версию Android SDK 15+. Благодаря этому можно отказаться от Android Support Library. Я вообще не понимаю, почему до сих пор многие ее используют. Хотя Google уже несколько лет назад рекомендовал поддерживать Android, начиная с версии 4.0.3 (SDK 15). И также сейчас мало кого можно найти с версией устройства ниже 4.0.3.
Также я не стал бы рекомендовать использовать стандартный ActionBar и ActionBarMenu, если вам надо хотя бы что-то немного кастомизировать. Да, это возможно, но вы столкнетесь с кучей проблем. Лучше напишите свой ActionBar.
Могу еще сказать про стандартные Fragment и FragmentManager. Когда-то в других проектах мне надо было добавить нестандартные анимации между экранами. И что вы думаете Fragment их поддерживал? Конечно, нет.
Я смотрел их исходный код, я не понимаю зачем так сильно было усложнять такие простые вещи. В итоге написал свои Fragment и FragmentManager. Думал сделать их Open Source, но надо их более стандартизировать, пока до этого руки не дошли.
Возможно, вы скажите, что стандартные решения более эффективны по памяти и быстрее работают. Но это не так.
Kotlin или Java? Я использую Java, потому что так мне привычнее и в данном случае использовать Koltin в этом проекте не даст преимуществ.
Также хочу заметить для тех у кого приложение должно отображать много разнообразной графики, картинок, используйте разные библиотеки с кэшированием картинок для этого или напишите свою. Их много, например, Picasso, Glide, Fresco и т.д. Мне больше нравится Picasso, поэтому ее и использую. В предыдущих проектах я тестировал разные библиотеки, но лучше всех показал Picasso. Я если честно, уже не помню в чем были недостатки других конкурентов. Также Picasso поддерживает изменение размера картинок, загрузку по url, разные выравнивания и много чего еще.
iOS
Версии пока под iOS нет. Но, конечно, будет использоваться Swift, а не Objective-C. Я вообще не понимаю, как такая компания как Apple с ее ресурсами, могла сделать такой неудобный язык программирования для современных устройств.
Да, когда разрабатывался этот язык, устройства имели проблемы с нехваткой памяти. Но в наше время (первый iPhone вышел в 2007 году) использовать Objective-C с его ручной настройкой памяти для разработки под iOS, я считаю очень плохим тоном.
Самое забавное в этой ситуации то, что Objective-C экономит память, а сами приложения под iOS весят больше, чем под Android и намного больше тормозят на старых iOS устройствах. Возможно это так, потому что Стив Джобс не был программистом и не знал, что лучше использовать для разработки.
Также я выскажу свое мнение про Swift. Оборачивание переменных сделано неудобно. По идее, это должно было облегчить код и убрать дополнительные проверки, но по итогу их стало еще больше. Поэтому если вы используете функции из других библиотек, вам придется использовать больше разных ненужных проверок, чем если бы вы писали на Java. Короче, Apple опять пошел не туда. Но уже лучше чем Objective-C. Даешь официальная версию Java от Apple под iOS!
Также я не говорю, что моя точка зрения абсолютно верна. Я не так много программировал на Swift. Но любому человеку Java будет проще чем Swift для начала изучения и разработки.
Про деньги и монетизацию
Вопрос — откуда у меня деньги на сервера? Поскольку все вышеописанные мною операции, требуют очень много вычислительных ресурсов, даже после колоссальных оптимизаций.
Я отвечу честно, я потратил на аренду серверов и консультации со специалистами по машинному обучению и нейронным сетям (только консультации, код писал я) больше 600 тысяч рублей. Встречный вопрос — откуда у подростка такие деньги? Сразу всем приходит на ум — дали родители. Но на самом деле я не взял у родителей и рубля. Просто, когда я учился в школе, я параллельно работал программистом и откладывал. Вот так вот, все очень печально.
Также если за все потраченное время и силы на проект я бы работал программистом, хотя бы в полсилы, я бы заработал больше 2 миллионов рублей.
Сейчас аренда серверов стоит тоже очень дорого для меня — поэтому я ввел платные поиски, чтобы окупать ее и зарабатывать на проекте.
Также планируется создание решений для бизнеса.
Лирическое отступление. Почему так делать не надо
Из-за создания этого проекта с моей личной жизнью в это время происходили «веселые» истории (и не только с личной жизнью), а последние несколько месяцев вообще не было личной жизни. Если интересно, читайте fails.
Договорились встретиться в день N.
В три часа ночи перед этим днем, мне в голову приходит гениальная идея. Но я все-таки гоню ее. Но понимаю, что это не получается. Встаю, работаю. Все ок. Все супер. Все работает. Но опять поспал 1–2 часа в эту ночь. Пытаюсь заснуть потом, но уже не могу.
Как я заметил, мир после очень большого умственного напряжения (несколько дней подряд) и недосыпа (тоже несколько дней подряд) воспринимается, вообще, совсем по-другому. Попробуйте. Это не описать словами.
Итак. Вернемся к истории. Наступает вечер, встречаемся, садимся в кафе, пьем кофе. Она много чего рассказывает. Я тоже говорю, вставляю в разговор разные истории. Понимаю, что что-то не то говорю. Она опять много чего говорит. И вдруг отключаюсь. Прямо засыпаю за столом, потом опять просыпаюсь, потом опять засыпаю. И так несколько раз. Потом как-то попадаю обратно домой.
Больше я ей не звонил. Мог, но что-то уже не хотел. А она, наверное, подумала, что мне с ней вообще не интересно.
Просыпаюсь я как-то утром. Понимаю, что достаточно сильно не выспался. Но начинаю работать, появляется прилив энергии. Ну, думаю хватит энергии на весь день, все будет ок.
Беру телефон, звоню девушке, с которой на днях познакомился (она умная и красивая, очень миленькая, такое редко вообще есть), говорю: Давай встретимся сегодня вечером. Она говорит: Давай.
К вечеру я понимаю, что с энергией внутри меня происходит веселая ситуация. Она проявляет себя крайне нестабильно, как первые версии любого софта в начале разработки. Ну, думаю, что-нибудь придумаю.
Когда я встречаю девушку, мы начинаем идти. Через минут 5–10, я понимаю, что я не могу вообще связывать слова. От слова вообще. (Когда такое со мной вообще было?) Получается — амм… амм…, а ты… а… и т.д. Понимаю, что будет вообще фэйл. Надо напрячься. Но энергия пропала вообще. Наверное, сказалось несколько дней не высыпания. Но я все-таки пытаюсь шутить, но мои шутки не заходят. (Шутки — это эмоциональная составляющая. Не важно что говорить, важно как.) Но в данном случае эмоции я вообще не могу проявлять, говорю какие-то глупости. Я понимаю, надо уходить. Но все же продолжаю идти с ней дальше.
Почему я продолжаю идти дальше? Просто у меня в этот момент очень сильно замедлилась реакция. Проходит минут 40–60. Я понимаю, что она скорее всего думает, что я вообще умственно отсталый. Но все-таки, наконец говорю, давай потом увидимся, а то я что-то не выспался. Ну, и ухожу.
Через несколько дней я ей позвонил. Но она сказала, что у нее все запланировано. Ну, вы поняли.
Гуляем, вижу, общение идет хорошо. Все ок. Но так как энергии опять не много, идет пока только общение. Беру у нее телефон. Прощаемся. Потом опять работаю некоторое время. От большого умственного напряжения чувствую себя плохо несколько дней. Вообще ничего не делаю. Потому что даже не могу смотреть фильмы, например. Как отхожу, у проекта начинаются разные финансово-технические проблемы. Так проходит месяц, другой. Я ей так и не позвонил. Сейчас уже вообще прошло больше полгода. Она, наверное, уже нашла себе кого-то.
Может позвонить, как думаете?
Таких типов историй еще было несколько. Потом понял, что пока разрабатываю основную часть проекта, вообще не получится с личной жизнью. Поэтому последние несколько месяцев (а может и больше года, смотря что считать) ее вообще не было.
Также я тестировал мое приложение на девушках из историй. Нашлись 3 из 6 тем алгоритмом, который используется в beta-версии. Улучшенной версией алгоритма нашлось 5 из 6.
Что в итоге получилось
Пока проект находится в бета-версии, используется менее точный алгоритм для поиска.
В данный момент работает Android-версия.
Также будут версии для web и iOS.
Версия для web уже есть в сыром варианте, но пока я ее не буду вам показывать.
Можете затестировать пока Android-версию.
Я буду честен и скажу, что мой поисковик в бета-версии пока уступает по качеству FindFace, находит примерно через раз-два, но уже ищет. Там пока не вся база (пока с 1 по 270 миллион), не поддерживаются повороты головы и фото с маленькими лицами среди этой базы. Но я знаю как сделать это технически, это уже работает и будет попозже. Просто пока нет денег на вычислительные ресурсы.
Также разработан другой алгоритм поиска, который не уступает по качеству FindFace, но пока он не используется из-за дороговизны серверов. Для того чтобы его запустить, нужны вычислительные ресурсы ценой в несколько миллионов рублей.
Размышления и будущее
Вообще, так как, у меня были наработки до этого, я думал, что я намного раньше справлюсь с проектом, а он затянулся почти на два года. Я не предвидел многие подводные камни, и в большинстве случаев пытался во всем разобраться досконально сам. Но зато теперь я хорошо разбираюсь в большом количестве разных аспектов программирования. И вообще, уже думаю, что смогу запустить ракету в одиночку.
Конечно, дальнейшее развитие проекта уже будет в команде. Я уже хорошо понимаю, как и что можно делегировать. Сейчас я планирую привлечь инвестиции, набрать команду и сделать много чего интересного. Также можно придумать разные решения для юр.лиц. Есть понимание, куда двигаться дальше.
Если у вас есть знакомые инвесторы, расскажите, пожалуйста, им об этом проекте. Если вы сами инвестор, пишите на почту из маркета.
Проект имеет очень большой потенциал для применения в разных сферах жизни.
Вопрос к вам. Что вы думаете по этому поводу?
Если эту статью читают люди, которые работают (работали) в таких крупных компаниях, как Apple, Facebook, Google и т.д. или аналогичных отечественных. У меня к вам вопрос — почему у вас так много программистов? Я понимаю, что в больших компаниях есть возможность делать лучше тестирование, создать более подробный расчет статистики, писать более быстрые, оптимизированные решения, разрабатывать компиляторы для своих нужд, и даже свои языки.
Но я все же не понимаю, почему, например, при Павле Дурове у ВКонтакте было 20 программистов, а у Facebook 20 000 программистов. Да, нагрузка у Facebook в среднем в 10 раз больше. Но нагрузка здесь не так важна. Она уменьшается с ростом серверов, а не с увеличением количества программистов.
Если сравнить решения от ВКонтакте, например, KPHP. Он быстрее чем Hip-Hop от Facebook и т.д. Что же тогда делают программисты в таких компаниях? Объясните, пожалуйста, в комментариях, если знаете.
Выводы
Чтобы сделать этот проект мне приходилось очень сильно умственно напрягаться, потратить много денег и забить на многие сферы в жизни. Мой совет вам и самому себе — никогда так не напрягайтесь, иначе вы не будете наслаждаться жизнью или хотя бы просто жить. Вы попадете в такой ад, который вам и не снился, хотя пока вы еще на земле, и имеете полное право пока не гореть в аду. Ну, это я немного отступил.
P.S. Иногда сервера падают и перегружаются (об этом написал выше). Прошу понять и не обижаться.