Connect with us

Статьи

Почему авторы Trello не смогли создать бизнес на 1 миллиард долларов

Почему инновационный и популярный продукт не принес своим создателям максимально возможную прибыль? Создатель нескольких SaaS-компаний Хитен Шах разобрал ошибки, которые допустили создатели Trello.

Анна Гуляева

Опубликовано

/

     
     

Почему инновационный и популярный продукт не принес своим создателям максимально возможную прибыль? Создатель нескольких SaaS-компаний Хитен Шах разобрал ошибки, которые допустили создатели Trello.

В 2011 Джоэл Спольски на TechCrunch Disrupt запустил новый продукт компании Fog Creek под названием Trello. Он был похож на белую доску со стикерами, перенесенную в веб-браузер и в приложение для iPhone. Вместо того, чтобы перемещать физические заметки на доске, вы могли перетаскивать карточки на доске в браузере.

За считанные дни Trello удалось привлечь внимание 131 тысячи человек. 22% из этих людей зарегистрировались. Trello хотели создать простой и полезный продукт, который сможет использовать кто угодно. Он распространялся, как лесной пожар.

Поэтому Trello в итоге пришлось продать Atlassian за $425 миллионов, хотя он и мог стать следующим SaaS-приложением на миллиард долларов.

Спустя пару месяцев после запуска Спольски написал пост, в котором предвидел самую большую сложность:

Создать большой горизонтальный продукт, полезный в любой сфере жизни, почти невозможно. Вы не можете заработать очень много, потому что соревнуетесь с другими горизонтальными продуктами, которые могут покрыть расходы на разработку при помощи огромного числа пользователей. Это высокий риск, но и высокая награда.

В точности следуя этому, в Trello успешно создали горизонтальный продукт, быстро набравший миллионы пользователей и инвестиции в сотни миллионов долларов. Однако в Trello так и не справились с привлечением платящих клиентов.

Они были сфокусированы на первоначальном создании пользовательской базы и лишь последующей монетизации, но когда взглянули на своих подписчиков, было уже поздно – момент был упущен. Хотя Trello является идеальным дополнением к набору инструментов для повышения производительности от Atlassian, это затрудняет дальнейшее развитие продукта.

Давайте поговорим о возможности, которую упустил Trello, и что следовало сделать вместо этого.

Почему Trello нужно было заниматься продажами

Trello был создан вокруг концепции канбан-доски. Канбан – это система для гибкого производства, которую Toyota сделали популярной в 1940-х. Идея заключалась в том, что каждая карточка представляла собой продукт, его часть или инвентарь. Когда карточку перемещали на доске, это означало, что что-то физически переместили от поставщика на фабрику.

На практике это выглядело так:

Когда Trello только появился, технически было действительно сложно создать браузерную доску, в которой вы сможете совместно перемещать карточки в разные списки. Многие SaaS-инструменты того времени были большими базами данных с визуальным интерфейсом, натянутым поверх (например, Salesforce). Создавалсь архитектура, в которой вы структурируете данные по лидам, клиентам или задачам.

В Trello подошли к этому с противоположного направления. Видение продукта заключалось в том, чтобы все сломать и опираться на визуальную идею карточек на досках. Чтобы это сделать, Trello внедрили инновационный стек. Одностраничное веб-приложение в основном работало как оболочка, которая вытаскивала все данные с серверов менее чем за полсекунды и менее чем за 250 килобайт. После первого посещения они кэшировали страницу, чтобы Trello загружалась еще быстрее.

Они построили свои сервера на Node и использовали MongoDB для хранения данных, поэтому веб-приложение загружалось очень быстро. Каждый раз, когда пользователь перемещал карточку в новый список или менял запись на доске, Trello отправлял эти данные в другие браузеры, чтобы доска открывалась почти мгновенно.

Архитектура Trello

Результат был удивительно простым. Вы делали изменение на доске, и оно отображалось во всех других местах.

Все это было новым в то время и привлекло к Trello много внимания. Но в 2016 подобное красивое и отзывчивое  приложение стало не так сложно создать, и канбан-доски начали появляться везде:

GitHub представили канбан-доски в сентябре 2016:

Asana анонсировали канбан-доски в ноябре 2016:

Airtable запустили канбан-доски в ноябре 2016:

Джастин Розенштейн, сооснователь одного из крупнейших конкурентов Trello, Asana, сказал: “Мы определенно отдаем должное Trello. Этот продукт первым создал подобное видение”. Но Джастин непреклонен в вопросе копирования функции досок Trello: “Мы рассматриваем Trello как функцию, а не как продукт”.

Trello мог стать миллиардным бизнесом, если бы он был ”системой записи”, то есть, единственным надежным источником информации для компаний. Представьте, что вы можете использовать Trello не только чтобы отслеживать вашу маркетинговую воронку, но и чтобы перемещать информацию с маркетинговой доски в пайплайн продаж и план развития продукта. Вместо отдельной доски для каждой команды у вас могла бы быть большая доска для всей компании.

Trello не стал такой системой записей. Он стал сильной визуальной метафорой, которую скопировали его конкуренты. Канбан-доска оказалась отличной UX-функцией, но не защищенной от копирования.

В SaaS побеждает не первая компания и не компания с лучшей идеей. Побеждают те, кто постепенно лучше решают проблему. Когда вы создаете популярную или успешную функцию, конкуренты её крадут.

В Trello могли бы удвоить свою прибыль, переведя индивидуальных клиентов на платную подписку. Они могли сосредоточиться на создании функций для малого и среднего бизнеса. Или они могли расшириться на предприятия. Всё это привело бы к повышению оценочной стоимости компании до более чем миллиарда долларов. Давайте обсудим, что Trello могли бы сделать на каждом шаге, начиная с индивидуальных пользователей.

1. Trello недостаточно быстро монетизировался

При помощи freemium модели возможно построить нацеленную на пользователей миллиардную компанию. В 2013, спустя шесть лет после запуска, Dropbox был оценен в 8 миллиардов долларов, их доход – 200 миллионов долларов, а количество пользователей – 200 миллионов человек. Это было даже до того, как Dropbox запустил тариф для бизнеса – доход компания преимущественно получала от продажи пользователям месячной подписки за 10 долларов.

Спустя три года после запуска рост количества пользователей Trello обещал превысить уровень Dropbox: в 2015 году у Trello было 10 миллионов пользователей (через три года после запуска у Dropbox было четыре миллиона клиентов). Но Trello было гораздо сложнее переводить неплатящих пользователей на свой план “Trello Gold”.

Запуск Trello Gold в 2013 был освещен этим постом в блоге, которые выделил три причины, по которые пользователю следует платить 5 долларов в месяц за Trello:

  • Настраиваемый фон доски
  • Ограничение в 250 МБ для файлов, прикрепленных к карточке (против 10 МБ в бесплатном плане)
  • Стикеры и кастомные эмодзи

Хотя все любят эмодзи, это не очень хорошая причина тратить деньги на приложение. Бесплатный тариф Dropbox предоставляет 2 ГБ пространства. Платный тариф предоставляет 1 ТБ, что в 50 раз больше бесплатной версии.

Определить ценностное предложение Trello было сложно, потому что они должны были ещё в начале понять, за какие функции захотят платить индивидуальные пользователи.

Решение: Изучить кейсы freemium-модели

В самом начале в Trello решили создавать горизонтальный freemium-продукт, который будет использовать каждый, а о монетизации подумать попозже. Вместо этого им следовало погрузиться в кейсы с самого начала, чтобы понять, почему люди регистрируются, для чего им нужен продукт и за что они будут готовы платить.

Если у вас есть продукт с множеством возможных применений, посмотрите сначала все кейсы его использования:

  • Существует ли у вас конкурент, который может делать то же самое или уже делает это сейчас?
  • Каков потенциальный доход этого варианта?

Исследуя свою клиентскую базу и пользователей вашего конкурента, вы можете выделить кейсы с наибольшей прибылью за время жизни пользователя.

Предположим, что Trello обнаружил, что в его пользовательской базе юристы, риэлторы и дизайнеры принесут потенциально самую большую прибыль. Они могли бы узнать, что дизайнеры хотят доступ к календарю с доски, а юристы хотят доски с режимом только для чтения, которыми они смогут поделиться с клиентами.

Эти функции Trello включили в свой план для бизнеса, но не подчеркнули их в маркетинге, потому что хотели охватить более глобальные вещи. Вместо этого Trello могли бы создать отдельные лендинги для того, чтобы перенаправлять пользователей без подписки на специфические кейсы.

Когда у вас есть обширный продукт, особенно важно рассмотреть индивидуальные варианты его применения, потому что это позволит вам создавать особые функции для этих вертикалей Если вы не хотите строить свой бизнес на freemium-модели, вы можете подняться выше и нацелиться на малый и средний бизнес (SMB).

2. Trello не стал незаменимым для SMB

Даже без доходного B2C-бизнеса Trello могли стать SaaS-инструментом для работы компаний, закрепившись на SMB-рынке. Проблема заключалась в том, что Trello не доказал свою незаменимость в качестве инструмента для управления рабочими процессами, чтобы оправдать свою стоимость перед компаниями.

В 2013 Trello запустил первый план Business Class для малого и среднего бизнеса. Сначала они установили цену в 200 долларов в год для организации, прежде чем перейти к более традиционной модели ценообразования SaaS за рабочее место.

Trello Business Class стоил 10 долларов за пользователя (плата взималась раз в год), и за эти деньги вы получали:

  • Безграничную интеграцию досок
  • Дополнительные функции совместной работы
  • Режим “только для чтения” и настройки приватности

Когда Дэвид Кэнсел, со-основатель Drift, упомянул годовую стоимость Trello в своей презентации, вся команда была шокирована – цена составила 1700 долларов. Как говорит Дэвид: “Только несколько людей используют Trello ежедневно. Однако мы платим за количество подключенных людей. Очевидно, существует разрыв между ценой, которую мы платим, и пользой, которую мы получаем”. Дэвид затем перевел свою команду обратно на бесплатный план.

В статье на Forbes CEO Trello Майкл Прайор сказал: “Я не хочу, чтобы люди проводили по десять часов в Trello ежедневно, мы не продаем рекламу и не хотим получать больше вашего времени, как это делают социальные платформы”.

Это нормально. Когда вы берете плату по количеству пользователей, вам не нужно оптимизировать свой продукт, чтобы эти пользователи заходили в приложение чаще. Но вам нужно найти способ продемонстрировать свою ценность компании.

Что следовало сделать Trello?

Решение: Создать лучшую интеграцию для SMB

Trello могли бы создать более нужный продукт, сильнее интегрировав его с другими инструментами, чтобы команды просто не могли его заменить.

Представьте возможность открывать и закрывать GitHub Issues прямо внутри Trello. Представьте, что все ваши лиды из Salesforce автоматически открываются или закрываются в Trello. Trello мог бы стать доской управления всеми остальными инструментами компании, что было бы очень ценно.

Вместо этого главные функции Trello были скопированы. Представителю GitHub задали вопрос о создании досок для визуального управления вопросами, на что он сказал: “Все ожидали этой функции и спрашивали, почему у нас её не было”. Поэтому GitHub создали доски.

Если вы создаете подобное горизонтальное SaaS-приложение, разделите своих пользователей по интеграциям:

  • Какие API используют люди?
  • Сколько данных входит в продукт и выходит из него?

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

На рынке SaaS-приложений для малого и среднего бизнеса очень большая конкуренция, и компаниям все проще перейти с одного решения на другое. Вы можете либо перехитрить конкурентов, либо расширить свой продукт для больших корпораций.

3. Trello не подходил для предприятий

Смена фокуса на рынок предприятий – доказанная модель для SaaS. Slack сделал это, запустив Enterprise Grid. Trello могли бы построить прибыльный бизнес таким же образом, быстро переключившись на рынок предприятий.

Менее чем через год после запуска стратегии корпоративных продаж, ежегодные платежи (ARR) достигли отметки в 10 миллионов долларов. В своем интервью вице-президент Trello по продажам Кристен Хабахт сказала, что Trello следует достаточно простой стратегии корпоративных продаж:

«Наша команда по работе с предприятиями рассматривает [клиентов], у которых действительно много пользователей Trello. Большая часть нашей стратегии исходящих продаж – это просто связаться с этими компаниями и сказать: У вас более 2 000 человек пользуются Trello, с кем мы можем поговорить об этом?»

10 миллионов повторяемых платежей – это не мало. Проблема со стратегией Trello заключалась в том, что она опиралась только на то, что люди в компании уже использовали Trello. Команды продаж, маркетинга и развития продукта могли использовать массу разных досок. Но сложнее было бы организовать всю компанию вокруг Trello.

Решение: Стать системой хранения данных для предприятия

Trello должны были задать такой вопрос: “Как нам интегрироваться с системами, которые используют большие компании, и стать незаменимой частью рабочего процесса?”.

Один из способов – стратегия Slack. С ростом компании они пытались распространиться от индивидуальных разработчиков к командам, а от команд к компаниям. Slack обнаружил здесь проблему, потому что, в отличие от инструмента продаж или маркетинговой аналитики, почти каждый человек в команде мог наложить вето на инструмент повышения продуктивности. Поэтому Slack провел шесть месяцев в приватном бета-тестировании, изучая свою клиентскую базу и рассказывая им о необходимости в инструменте внутренней коммуникации. Они оптимизировали процесс онбординга вокруг метрики в 2000 отправленных внутри организации сообщений. Сегодня 93% этих компаний продолжают использовать Slack.

Видение, стоящее за корпоративным продуктом Slack, позволяет организациям создавать “структуры” при помощи Slack. Функциональность приложения для предприятия отличается пользовательского. Команды в компании могут организовываться в “рабочие пространства” и формировать подразделения в соответствии со структурой организации. В Slack пытались понять, как и почему продукт распространяется от маленьких команд к отделам и целым организациям, и поэтому они смогли выделить ключевые проблемы предприятий и решить их в Enterprise Grid.

Большие компании любят гибкость и конфигурируемость. Как и Slack, Trello мог занять нишу в предприятии, позволяя ему настраивать Trello согласно структуре организации. Преимущество Trello заключается в том, что это действительно многосторонний и простой в использовании продукт. Предоставив компании возможность создавать структуру подразделений, Trello мог бы выступить соединительной тканью между частями организации.

Поздравляю, Trello

Смотреть в прошлое, конечно, проще. Хотя большая часть статьи посвящена упущенной возможности Trello, мы не должны забывать, что создание SaaS-бизнеса, оцененного в 425 миллионов долларов, это большое достижение.

Команда Fog Creek заплатила за создание Trello из своего кармана. Приложение стало успешным с момента запуска на TechCrunch Disrupt. За два года Trello приобрел 500 тысяч пользователей, а за четыре года – 4,75 миллиона, и это до привлечения средств инвесторов. Команда создала удивительный продукт, который опередил свое время. Он был простым, изящным и легким в использовании.

В прошлом году я написал такой твит:

Вот такое влияние Trello оказал на SaaS, и вы видите его следы везде: от GitHub до Jira.

Но если вы хотите создать следующее SaaS-приложение на миллиард долларов, вы должны помнить о постоянном развитии своего продукта. Не фокусируйтесь на одной функции, которую могут украсть конкуренты. Вместо этого интегрируйте эту функцию во все другие продукты, чтобы копировать её стало бессмысленно.

Помимо прочего, вы должны понимать своих клиентов с самого начала, потому что так вы будете знать, что внедрить в свой продукт и в каком направлении его развивать. Исследования и усердная работа – это единственный способ сохранять ваш продукт востребованным на рынке.

 

Комментарии
Если вы нашли опечатку - выделите ее и нажмите Ctrl + Enter! Для связи с нами вы можете использовать info@apptractor.ru.
Advertisement
Click to comment

You must be logged in to post a comment Login

Leave a Reply

Программирование

Все инженеры умеют программировать, но не все программисты могут быть инженерами: в чем отличие?

Никто не может стать инженером за два месяца, за шесть месяцев или за год. Почему не все программисты могут называться инженерами и какими навыками обладают настоящие инженеры-разработчики?

Анна Гуляева

Опубликовано

/

Многим людям не нравится термин “инженер по разработке программного обеспечения” из-за относительного сравнения с инженерным делом. Но эта статья посвящена не термину. Если вам не нравится название, вы можете заменить его на “автор ПО”, “мастер ПО” или даже “художник по ПО”.

Под инженером по разработке я подразумеваю человека, который считает создание качественных программ своей профессией. Человек, который применяет науку и статистику в своей профессии и не смотрит на это как на работу, которая просто приносит деньги.

Знание программирования не делает вас инженером. Любой может научиться программировать. Любой может создать простые программы, которые будут работать для него на собственном компьютере, но это не гарантирует, что те же программы будут работать для остальных.

Моя любимая аналогия — любой человек может петь для себя в душе, но на вечеринке вы не будете ставить свои записи. Вы полагаетесь на профессионалов.

Хотите еще бльше аналогий? Конечно:

  • Мы изучаем математику и правописание в школе, но это не делает нас математиками и авторами.
  • Многие могут научиться готовить, но, чтобы накормить много людей, мы зовем повара.
  • Вы не будете звать соседа с инструментами, чтобы построить дом с нуля.

Я хочу донести мысль о том, что простые программы отличаются от тех, что создали инженеры. Программирование — это создание инструкций для компьютеров, чтобы они приняли входные данные и превратили их в определенный результат.

Процесс проектирования программ — это планирование, написание, тестирование и поддержка компьютерных программ с целью решения проблемы для многих пользователей. Это создание надежных решений, которые выдержат проверку временем и будут работать не только с очевидными проблемами, но и с неизвестными.

Инженеры понимают все о проблемах, которые они решают, о своих решениях, об ограничениях этих решений, последствиях этих решений для приватности и безопасности.

Если человек не понимает проблему, он или она не может создать решение для нее.

Склонность к поиску решений

Инженеры не считают свою деятельность просто написанием программ. Они думают о потребностях и решениях проблем. Это важно, потому что не каждая проблем нуждается в новой программе. Некоторые проблемы можно решить уже существующими программами. Некоторые проблемы можно вообще предотвратить, если действовать заранее. Создание хороших программ часто включает предотвращение будущих проблем.

Сложные проблемы требуют создания нескольких программ. Некоторые проблемы требуют параллельной работы программ, а другие — последовательной. Некоторые проблемы можно решить обучением пользователей.

Перед созданием программы инженер задает вопросы:

  • Какие проблемы я пытаюсь решить?
  • Можно ли сделать для их решения что-то, кроме написания кода?
  • Что я могу сделать, чтобы эти проблемы было проще решить при помощи кода?

Качество кода

Отличные программы понятны, и их можно легко расширить, они отлично работают с другими программами, а поддерживать их не так сложно. Качеством кода нельзя жертвовать, а использовать временные решения из-за дедлайна или эмоций — неприемлемо.

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

Каждый программист (не)счастлив по своему

Сама по себе программа не так полезна. Ценность их функций проявляется, когда разные программы коммуницируют друг с другом, обмениваются данными и совместно работают над представлением данных и интерфейсов пользователям. Об этом нужно помнить при создании программ. Какие сообщения они будут принимать? Какие события будут отслеживаться? Какие сообщения они будут отправлять? Как мы будем проводить аутентификацию и авторизацию коммуникаций?

Другой важный аспект отличных программ — это ясность кода, а не количество тестов или число в отчете по тестовому покрытию. Этот код может прочитать кто-то ещё? Смогу ли я понять этот код через несколько недель?

В программировании существует только две по-настоящему сложных вещи: инвалидация кэша и наименование вещей, — Фил Карлтон

Удобство чтения кода важнее, чем вы думаете. К сожалению, для ясности кода нет хороших метрик. Знание хороших методов может помочь, но часто этого недостаточно. Хорошие инженеры просто учатся этому с опытом. Здесь подходит метафора с писательством: знание большого количества слов не поможет вам писать понятные тексты.

“У меня не было времени на короткое письмо, поэтому я написал длинное”, — Марк Твен

В программах случаются ошибки. Возможность без проблем исправить их — это ключевой атрибут хорошей программы. Ошибки должны сопровождаться понятными сообщениями и храниться в одном месте. Когда появляется отчет о новой ошибке, ответственный за исправление человек должен иметь возможность устранить в ней баги. Он или она должны иметь возможность зайти в систему и прочитать информацию об ошибке в любое время. У них должна быть возможность подтвердить ожидания о любой части системы.

Правильный разработчик

Среда и тестирование

Когда инженеры пишут программы, они должны убедиться, что эти программы будут работать в разных средах, на разных устройствах, в разных часовых поясах. Программы должны работать на экранах разного размера и ориентации. Они должны справляться с ограниченностью памяти или вычислительной мощности.

Программное обеспечение для браузера должно работать во всех популярных браузерах. Программы для компьютеров должны работать для пользователей Mac и Windows. Приложения для работы с данными должны работать, когда подключение слишком медленное или его совсем нет.

Чтобы написать программу, инженеры должны продумать любой возможный сценарий и спланировать тестирование всех этих сценариев. Это начинается со “счастливого пути”, когда ничего неожиданного не происходит, но затем инженеры должны прописать каждую проблему, которая может случиться, и написать для них тесты. Некоторые инженеры начинают с написания тест-кейсов, которые симулируют эти сценарии. Затем они пишут код, который проходит все эти тесты.

Инженеры понимают расплывчатые требования программ. Уникальный навык инженера — это не просто знать, как написать решение, но понять, что должно быть в этом решении.

Стоимость и эффективность

Во многих случаях инженеры могут решить проблемы быстро. Если вы думаете, что найм опытных программистов повысит расходы, подумайте еще раз. Чем больше у программиста опыта, тем быстрее он или она сможет создать надежное решение, которое можно будет поддерживать без особых трудностей. Это означает сокращение расходов в долгосрочной перспективе.

Как найти лучших разработчиков для работы над проектом

Вам также нужно принять во внимание стоимость запуска программы. Каждая программа будет использовать компьютерные ресурсы, которые не бесплатны. Инженеры будут писать эффективные программы, которые не будут тратить компьютерные ресурсы впустую. Например, это кэширование часто используемых данных, но это только одно из тысяч решений, которые могут сделать программу быстрее и эффективнее.

Начинающий программист может сделать для вас дешевое решение, но оно в итоге потребует у вас и у вашего клиента больших затрат, чем изначально эффективное решение.

Удобство использования

Хорошие программы создаются с учетом пользовательского опыта. Взаимодействие человека и компьютера — это большая тема с многочисленными исследованиями и выводами. Чем чаще будут учитываться эти выводы, тем лучше будут программы.

Вот несколько примеров:

  • При создании форм для ввода данных хорошая программа будет игнорировать прописные или строчные буквы? которые используются для ввода email-адреса. Она также уберет ненужные пробелы. Не нужно мучать пользователя из-за включенного Caps Lock, адрес почты уникален. Если программа принимает новые адреса, она должна сообщать пользователю о проблемах с вводом, например, об отсутствии знака @ или опечатке в gmail.ocm.
  • При перенаправлении пользователя хорошая программа запомнит первоначальное местоположение и перенаправит пользователя туда после завершения задачи. Хорошая программа также запомнит уже введенные данные и взаимодействия, которые нужны будут в следующих шагах. Например, вы ищете авиабилеты на Expedia в качестве гостя. Затем вы решили создать аккаунт. Вся ваша история поиска будет сохранена в новый аккаунт, и вы сможете получить к ней доступ с разных устройств.
  • Хорошая программа создается с учетом пользовательских сценариев. Поставьте себя на место пользователя. Однажды я забронировал билет United и забыл ввести свой номер постоянного пассажира. После получения подтверждения я отправился на сайт United, чтобы добавить номер, и эта задача заняла у меня десять минут. К этой функции не было очевидных путей, поэтому мне пришлось проверить все ссылки, которые могли бы вести к ней. Я уже был на странице с этой функцией, но я не увидел её в первый раз, потому что она была спрятана в большой форме. Мне пришлось найти информацию о пассажире, пролистать около 20 строк в этой форме, ввести номер пассажира и номер телефона, чтобы отправить эту форму. Это пример программы, которая создавалась без учета точки зрения пользователя.

Читабельность и безопасность

Это наиболее важные моменты, которые отличают профессионалов от любителей. Они знают, что ответственны за создание надежных и безопасных решений.

Программа должна быть устойчивой к плохим входным данным, состояниям и взаимодействиям. Этого очень сложно достичь, и поэтому мы слышим о том, что люди погибают из-за ошибок в ПО.

Пользователи будут вводить неверные данные в программу. Некоторые будут делать это специально, чтобы взломать её. Ответственного за недавний скандал с Equifax обвинили в том, что этот человек не сделал свою работу, то есть не создал устойчивую к зловредным входным данным программу.

Безопасность касается не только зловредных данных, но и обычных. Если пользователь забывает пароль, то сколько раз он или она сможет его ввести? Заблокируете ли вы после этого аккаунт? Что если кто-то этого и добивается? Позволите ли вы вводить пароль через незащищенное соединение? Что если попытка логина состоялась из необычного места? Что если логин кажется сгенерированным автоматически?

Что вы сделаете, чтобы защитить пользователей от межсайтового скриптинга и подделки запросов, атаки посредника и простого социального фишинга? Есть ли у вас стратегия на случай DDoS-атаки? Эти вопросы — это только несколько из проблем, к которым вы должны готовиться.

Безопасные программы не хранят чувствительную информацию в форме простого текста, а в виде зашифрованных данных, которые сложно взломать. Это запасная стратегия на случай взлома. В программах будут случаться ошибки, и если вы об этом не знаете или вы не подготовлены, то вас нельзя считать профессионалом.

Дефекты программ невидимы. Наша способность предсказывать и предотвращать известные дефекты ограничена. Поэтому инженеры понимать ценность хороших инструментов, которые могут помочь им писать корректные и безопасные программы.

Инструменты

Несомненно, нам нужны хорошие инструменты. Они многое меняют и часто недооцениваются. Представьте, если бы нам все ещё нужны были FTP для ффайлов! Представьте проблемы с производительностью и устранением багов без Chrome DevTools! Представьте, как неэффективно бы было писать на JavaScript без ESLint и Prettier!

Любой инструмент, который сокращает цикл обратной связи, должен быть ценным дополнением. Аргумент Брета Виктора об изобретении мгновенной визуальной репрезентации того, что мы создаем, открыл мне глаза. Принятие и улучшение инструментов — это единственный способ попасть в это светлое будущее.

Когда я нахожу отличный инструмент, я жалею лишь о том, что не нашел его раньше. Хорошие инструменты помогут вам стать хорошим программистом. Ищите их, используйте их, цените их и улучшайте их.

Выбор языка имеет значение. Типобезопасность имеет значение. Лучшее, что случилось с JavaScript — это TypeScript и Flow. Статический анализ кода важнее, чем вы думаете. Если вы этого не делаете, то ставите себя под удар неизвестных будущих проблем. Не программируйте без системы статической проверки типов. Если в вашем языке этого нет, поменяйте язык или используйте компилятор. Сегодняшние компиляторы могут работать, просто читая комментарии в коде, и это будущее проверки типов для языков, которые не поддерживают её.

Эволюция разработки

Никто не может стать инженером за два месяца, за шесть месяцев или за год. Вы не научитесь этому в буткемпе. Я учусь на протяжении последних двадцати лет. Я стал достаточно уверенным, чтобы назвать себя опытным программистом только после десяти лет обучения и создания и поддержки приложений, которые используют тысячи пользователей.

Разработка не для каждого, но все должны учиться решать свои проблемы с компьютерами. Если вы можете научиться писать простые программы, то стоит это сделать. Если вы можете научиться использовать сервисы, то стоит это сделать. Знание программ с открытым исходным кодом даст вам много возможностей.

Проблемы эволюционируют, и разработка должна развиваться аналогично. Будущее этой профессии — позволить обычным пользователям использовать свои компьютеры без необходимости учиться пять лет. Дайте пользователям возможность решать простые проблемы простыми инструментами. Инженеры должны создавать хорошие инструменты, решать большие проблемы и пытаться предотвращать неизвестные.

 

Комментарии
Продолжить чтение

Разработка

Что нужно и чего не нужно делать во время Code Review

Сандия Санкаррам из компании SurveyMonkey рассказала о том , как распознать токсичную коммуникацию среди программистов и как с ней бороться.

Анна Гуляева

Опубликовано

/

Code Review могут быть спорными. Недавно я впервые выступала на конференции с темой токсичного поведения в культуре просмотра кода. Я готовилась получить большое количество критики, но в итоге тему приняли добротой и поддержкой.

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

Я перечислила несколько распространенных шаблонов поведения, которые случаются во время Code Review, а также несколько рекомендаций о том, как команды разработчиков могут создать более благоприятную атмосферу, если не будут делать токсичность нормой. Все описанное происходило со мной или я была этому свидетельницей. Я и сама вела так себя в прошлом.

1. Представление мнения в качестве факта

Не делайте заявлений, пока не сможете процитировать документацию, формальные требования или примеры кода, чтобы подтвердить их. Людям нужно знать, почему их просят внести изменение, и личные предпочтения — это недостаточно хороший аргумент.

Вместо того, чтобы говорить “В этом компоненте не должно быть состояний” предоставьте контекст этих рекомендаций:

“Так как в этом компоненте нет методов или состояний жизненного цикла, его можно сделать функциональным компонентом без состояний. Это улучшит производительность и читабельность. *Вот* документация.”

Это поведение распространено, когда разработчики обсуждают предпочтения в стиле и синтаксисе. Это важные обсуждения, но они не должны происходить во время просмотра кода, так как стиль и синтаксис не относятся к проблеме, которую разработчик изначально планировал решить.

Выделите эти дискуссии и решите, каких правил и стиля будет придерживаться группа. Используйте линтеры и автоматические фиксеры. Так вы сможете придерживаться правил по стилю, а не своих персональных предпочтений, во время обзора кода.

Это особенно важно, когда у вас более высокая должность или авторитет в команде. Если вы будете так себя вести, у разработчиков не останется другого выбора, и им придется подстраиваться под ваши требования.

2. Лавина комментариев

Когда человек совершает ошибку, вероятно, он или она сделали ту же ошибку в других местах. Я заметила, что часто те, кто просматривает код, указывают на каждый случай ошибки вместо того, чтобы оставить один детальный комментарий со ссылками на полезные ресурсы.

Объединение комментариев позволит вам донести свое сообщение и не ошеломить человека. Бесполезно и угнетает:

Более полезно:

Я могу понять, что это может быть полезно, так как комментарий исчезает, когда разработчик исправляет ошибку. Но если эта ошибка повторяется, значит, разработчик не знает об определенном правиле, и ему или ей нужно указать на корректные ресурсы.

3. Просить инженеров решить проблемы, которые возникли не из-за них

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

Я не говорю, что разработчики не должны чувствовать ответственность за код, который начали писать не они. Я говорю, что более правильным решением будет создать отдельный тикет и решение для беспорядочного кода. Так вы не добавите кому-то работы, и плохой код будет исправлен.

Правила, которые я выработал по результатам тысяч code review

4. Задавать осуждающие вопросы

Не задавайте вопросов вроде: “Почему ты просто не сделаешь это здесь?”. Такие вопросы предполагают, что это очевидное решение. Это также заставляет разработчиков оправдываться.

Эти осуждающие вопросы часто являются замаскированными просьбами. Вместо этого напишите рекомендацию (с цитированием документации) и не используйте грубые слова.

“Ты можешь сделать это, и это будет полезно поэтому.”

5. Сарказм

Сарказм — это неправильное поведение, когда вы даете обратную связь. Саркастические комментарии ничего не объясняют. Вместо этого детально опишите проблему и напишите рекомендации, но оставьте шутки в стороне.

Бесполезно: “Ты вообще тестировал(а) этот код?”

Полезно: “Происходит сбой при вводе отрицательного числа. Можешь, пожалуйста, разобраться с проблемой?”

Вот ещё один пример комментария, который несмешной и бесполезный:

Я не говорю, что мы подлые. Мы просто беспощадные. Ты заметишь, что я оставил комментарий “Бип!” на импорте каждого файла, к которому ты притронулся. Я имел в виду, что твои импорты нарушают нашу стандартную процедуру, но это было слишком долго писать в каждом файле.

Комментарий “Бип!” бесполезен. Это просто педантичный юмор, который не помогает человеку, который писал код.

6. Использование эмодзи, чтобы указать на проблемы

Не нужно использовать эмодзи с пальцами вниз или человеком, которого тошнит. Это так же бесполезно, как и сарказм. Эмодзи можно понять неправильно. Эмодзи тратят время людей, которые пытаются понять, что вы имели в виду.

Вряд ли вас действительно будет тошнить от ошибок в коде. Вы можете использовать радостные эмодзи, чтобы показать, что код выглядит хорошо, но не используйте их, чтобы указать на проблему.

7. Ответ не на все комментарии

Люди, которые писали код, могут тоже вести себя некорректно. Если вы отправляете код без ответа на все комментарии, люди могут задуматься, зачем они вообще тратили время на помощь вам, а вы покажете, что некоторые мнения важнее других.

Если комментарий относится не к вашей работе или вы не будете действовать в соответствии с обратной связью, просто кратко объясните причины. Не занимайтесь гостингом.

8. Игнорирование токсичного поведения производительных людей

Токсичное поведение не нужно игнорировать только потому, что разработчик отлично работает. Хотя он или она может делать фантастическую работу, важно помнить, что их поведение делает работу других людей сложнее.

О работе с людьми, ведущими себя токсично:

Всем остальным работать с этим человеком будет сложно и неинтересно. Они будут избегать взаимодействия с ними, даже если это негативно повлияет на их способность выполнять задания. Коммуникация в вашей организации нарушится. Если все станет плохо, ваша команда начнет искать возможности в другом месте. Пока вы будете сталкиваться с утечкой людей и неудачными проектами, эти разработчики продолжат работать так, как будто все в порядке. — Джозеф Гефрох.

Бездействие может оказать серьезное влияние на команду, так как разработчики будут чувствовать себя демотивированными. Они начнут бояться процессов фидбэка, которые должны были помогать им расти. Лично я нервничаю каждый раз, когда получаю письмо о том, что бывший коллега (который оставлял токсичную и бесполезную обратную связь), прокомментировал мой запрос. Хотя такое поведение влияет на всех по-разному, мы все можем согласиться, что никто не получает от этого пользы.

Примечание: хочу отметить, что случайное проявление одной из описанных вещей не делает человека токсичным. А вот повторяющиеся оскорбления и язвительная обратная связь говорят о многом.

Как писать чистый и красивый код

Полезные вещи в обзоре кода

Это рекомендации, которые можно применить к любому человеку в дружелюбной среде, даже если здесь они даны в контексте просмотра кода.

1. Используйте вопросы или рекомендации, чтобы вести диалог

Никогда не требуйте от людей внести изменения и не задавайте осуждающих вопросов, потому что это не открывает диалог между вами. Резкие вопросы заставляют их оправдываться. Вместо этого спросите, что человек думает о предложенном решении:

“Можно поместить эти трансляции в файл констант, как думаешь? Их слишком много, имеет смысл создать для них отдельный файл.”

или предоставьте рекомендацию:

“У тебя в этом файле много запросов на трансляцию функции X. Имеет смысл создать отдельный файл под константы функции X.”

2. Не указывайте, а работайте вместе

Когда вы занимаетесь парным программированием, вы должны задавать вопросы, обсуждать и давать ссылки на ресурсы.

“Когда вы хотите работать с другим человеком, вы должны быть полностью вовлечены, а не просто появляться периодически”, — указания для пользователей Recurse Center.

3. Отвечайте на каждый комментарий

Если вы не планируете применять советы человека, оставьте заметку об этом. Не игнорируйте тех, кто уделил время на помощь вам.

Например:

“ — Что ты думаешь о создании хелпера для этого вызова API?

— Эта строка не входит в мой набор изменений. Я пока отправлю этот код, но я создам отдельную issue на GitHub для вызова API и отправлю это в бэклог группы.”

4. Иногда обсуждение нужно перенести в оффлайн

После десятков противоречивых комментариев и предложенных решений должно быть понятно, что онлайн-коммуникация стала непродуктивной для решения проблемы. Устройте встречу, чтобы обсудить вопрос вживую, так вы сможете прийти к решению быстрее.

5. Используйте возможности, чтобы научить чему-то, и не хвастайтесь

Перед тем, как участвовать в просмотре кода, спросите себя — ваш комментарий помогает другому разработчику учиться или вы просто любите придираться?

Подумайте, почему вы принимаете в этом участие. Помните, что цель просмотров кода — помочь другим разработчикам расти.

6. Не выказывайте удивление

Не нужно удивляться, если у кого-то нет тех же знаний, что есть у вас. Если люди могут понять нехватку опыта в какой-то теме и попросить о помощи —  это отлично. Не заставляйте их переживать из-за того, что они “уже должны были знать” эту информацию.

Григорий Петров: Код проекта: что хотел сказать разработчик

7. Автоматизируйте все возможное

Просмотр проблем, которые могут уловить линтеры, перехватчики в git или автоматизированные тесты, бесполезен. Люди не всегда видят эти проблемы, и поэтому существуют эти инструменты автоматизации.

Существуют инструменты, которые запускают тесты после проверки кода, и они показывают предупреждения, когда набор изменений нарушает какие-либо тесты. Эти функции есть у TeamCity и Jenkins CI. Используйте перехватчики в git. Они запускают тесты и линтеры, когда кто-то пытается отправить код, и перехватывают этот запрос, если в нем содержится код с ошибками.

8. Отказывайтесь от нормализации токсичного поведения

Не нужно поддерживать токсичные комментарии из-за их статуса кво. Ищите коллег, которые вас поддержат в этом. Если вы заметите, что кто-то оставляет бесполезные комментарии, дайте им знать об этом (если вы можете сделать это на вашей должности и в вашей компании) и будьте прямолинейны.

Григорий Петров: Как и зачем читать чужой код

9. Менеджеры, нанимайте внимательно, слушайте свою команду и применяйте меры

Менеджеры могут создать позитивную и дружелюбную культуру в своей команде.

  • Не нанимайте в команду токсичных разработчиков. Смотрите не только на технические навыки, оценивайте способности кандидатов к коллаборации и коммуникации. Критически анализируйте их работу и смотрите на их реакцию. Убедитесь, что каждый человек привносит что-то положительное в культуру компании.
  • Если у вас в команде есть токсичные разработчики, спросите у всех в отчетах о том, как им работается наедине с другими сотрудниками. Отчеты покажут, если у вас действительно есть токсичный разработчик.
  • Поговорите с этим человеком. Покажите ему примеры и правильную обратную связь.
  • Не изолируйте токсичного разработчика. Нужно побудить этого человека на здоровую коммуникацию с командой. Изоляция не поможет человеку исправиться.
  • Повторяйте, что ожидаете от команды коллаборации в дружелюбной обстановке.

10. Установите стандарт с самого начала существования команды

Если ваша команда небольшая, она может принять идеи и начать воплощать их сразу. Даже если вам это пока не нужно, помните, что вы хотите, чтобы ваша команда оставалась отличной с появлением новых сотрудников.

11. Поймите, что вы можете быть частью проблемы

Чтобы сделать обстановку лучше, важно быть честными с собой и подумать о том, не вели ли вы себя таким образом. Когда я была джуниор-разработчиком, у меня было несколько случаев, когда я видела баг в чьем-то коде и радовалась, потому что так я могла стать частью просмотра. Я теперь понимаю, что использовала эту возможность, чтобы похвастаться, а не помочь. Я пытаюсь помнить об этом и я думаю, что у каждого должен быть такой момент саморефлексии.

Одна последняя вещь…

Я не хочу регулировать содержимое фидбэка, я просто прошу людей следить за своим тоном.

Я знаю, что обратная связь важна, и я не объявляю ей войну. Я не прошу команды жертвовать качеством своего кода. Здоровая культура Code Review и высокое качество кода не исключают друг друга. Я надеюсь, что люди предпримут шаги, чтобы предоставлять конструктивную обратную связь и создать более благоприятную среду, где разработчики смогут учиться, расти и совершать ошибки.

Краткое содержание:

Комментарии
Продолжить чтение

Разработка

Обнаружение объектов с помощью Глубокого Обучения на Raspberry Pi

CEO проекта NanoNets рассказал об использовании нейронных сетей на небольших устройствах вроде Raspberry Pi.

Анна Гуляева

Опубликовано

/

В мире существует множество устройств с ограниченной памятью и небыстрыми процессорами, такие как, например, мобильные телефоны и Raspberry Pi, которые не могут запускать сложные модели глубокого обучения. Эта статья показывает, как вы тем не менее можете распознавать объекты при помощи Raspberry Pi.

Если вам не терпится, вы можете пролистать пост до ссылок на GitHub.

Почему Raspberry Pi?

Raspberry Pi покорил сердца людей: в мире продано около 15 миллионов устройств, на которых создаются отличные проекты. Учитывая популярность Raspberry Pi и глубокого обучения, мы решили создать систему распознавания любого объекта при помощи Pi.

Что такое обнаружение объектов?

За 20 миллионов лет эволюции человеческое зрение сильно развилось. 30% нейронов мозга человека работают над обработкой визуальной информации, для осязания этот показатель составляет 8%, а для слуха — 3%.

По сравнению с машинами, у людей есть два больших преимущества: стереоскопическое зрение и бесконечное количество данных для обучения (за пять лет жизни ребенок обрабатывает примерно 2,7 миллиарда изображений со скоростью 30fps).

Чтобы имитировать производительность людей, учёные разбили задачу визуального восприятия на четыре категории:

  1. Классификация — присваивание ярлыка целому изображению.
  2. Локализация — определение рамки вокруг объекта и его описание.
  3. Обнаружение объектов — создание нескольких рамок на изображении.
  4. Сегментация изображения — создание точных сегментов, содержащих объекты, на изображении.

Обнаружение объектов применяется в нескольких случаях. Хотя сегментация изображения дает более точный результат, её проблемой является сложность создания данных для обучения. Человек в 12 раз дольше сегментирует изображение по сравнению с созданием рамок. Более того, после обнаружения объекта есть возможность сегментировать его из рамки.

Использование обнаружения объектов

Обнаружение объектов — это важная функция, которая используется во многих индустриях. Несколько примеров показаны ниже:

Как использовать обнаружение объектов для решения моих проблем?

Обнаружение объектов можно использовать для ответа на многие вопросы. Вот несколько категорий:

  1. Присутствует ли объект на моем изображении? Пример: нет ли в моем доме грабителя?
  2. Где находится объект на изображении? Пример: когда автомобиль перемещается, важно знать, где находятся разные объекты.
  3. Сколько объектов на изображении? Пример: сколько коробок стоит на полке в складе?
  4. Какие типы объектов есть на изображении? Пример: какое животное находится в конкретной части зоопарка?
  5. Каков размер объекта? При помощи статичной камеры просто определить размер объекта. Пример: какого размера манго?
  6. Как разные объекты взаимодействуют друг с другом? Как группировка на футбольном поле влияет на результат?
  7. Где находится объект во времени? Пример: отслеживание движущегося объекта вроде поезда и вычисление скорости.

Обнаружение объектов менее чем за 20 строк кода

Существуют разные модели и архитектуры для обнаружения объектов. Каждая отличается по скорости, размеру и точности. Мы выбрали один из самых популярных алгоритмов — YOLO, и показали, как он работает в 20 строк кода (если игнорировать комментарии).

Примечание: это псевдокод. который не должен быть рабочим примером. В нем есть черный ящик, часть со сверточной нейронной сетью, которая довольно стандартна и показана на изображении ниже. Вы можете прочитать полную статью здесь: https://pjreddie.com/media/files/papers/yolo_1.pdf.

Архитектура сверточной нейронной сети, которая используется в YOLO

Как создать модель глубокого обучения для обнаружения объектов?

Процесс глубокого обучения состоит из шести шагов, которые разбиты на три части:

  1. Сбор данных для обучения
  2. Обучение модели
  3. Прогнозы на новых изображениях

Фаза 1 — сбор данных для обучения

Шаг 1. Соберите изображения (минимум 100 на один объект)

Для этой задачи вам нужно будет сто изображений для одного объекта. Попытайтесь собрать данные, максимально близкие к тем, для которых вы потом будете делать прогнозы.

Шаг 2. Аннотации (нарисуйте рамки на изображениях вручную)

Нарисуйте рамки на изображениях. Вы можете использовать инструмент вроде labelImg. Вам понадобятся люди, которые будут работать над аннотациями. Это занятие может занять много времени.

Фаза 2 — обучение модели на графическом процессоре

Шаг 3 — поиск уже обученной модели для обучения на основе переноса

Вы можете прочитать об этом больше здесь. Вам нужна будет обученная модель, чтобы сократить необходимое для обучения количество данных. Без этого шага вам понадобится минимум 100 тысяч изображений для обучения модели. Вы можете найти обученные модели в этом репозитории.

Шаг 4 — обучение на графическом процессоре (облачные сервисы вроде AWS/GCP или вашем собственном процессоре)

Для упрощения процесса обучения мы создали docker image, которое сделает обучение проще.

Чтобы начать обучение модели, вы можете запустить:

sudo nvidia-docker run -p 8000:8000 -v `pwd`:data docker.nanonets.com/pi_training -m train -a ssd_mobilenet_v1_coco -e ssd_mobilenet_v1_coco_0 -p '{"batch_size":8,"learning_rate":0.003}'

По этой ссылке вы можете узнать больше о деталях процесса.

В docker image содержится скрипт run.sh, который можно вызвать при помощи следующих параметров.

run.sh [-m mode] [-a architecture] [-h help] [-e experiment_id] [-c checkpoint] [-p hyperparameters]
-h          display this help and exit
-m          mode: should be either `train` or `export`
-p          key value pairs of hyperparameters as json string
-e          experiment id. Used as path inside data folder to run current experiment
-c          applicable when mode is export, used to specify checkpoint to use for export

Больше деталей можно найти здесь.

Чтобы обучить модель, вам нужно подобрать правильные гиперпараметры.

Подбор гиперпараметров

Искусство глубокого обучения требует поиска лучших параметров для повышения точности модели. Этот процесс — это немного магии и немного теории. Вот отличный ресурс, который поможет вам найти правильные параметры.

Квантование модели (чтобы она умещалась на маленьких устройствах)

На маленьких устройствах вроде телефонов или Raspberry Pi очень мало памяти и вычислительной мощности.

Обучение нейронной сети происходит при помощи внесения крохотных изменений в веса, и этим изменениям для работы нужна точность плавающей запятой (хотя в некоторых исследованиях здесь пытаются применить и квантованные репрезентации).

Использование обученной модели и получение вывода очень отличаются. Одно из магических свойств сетей глубокого обучения — они хорошо справляются с высоким уровнем шума в данных.

Зачем производить квантование?

Модели на основе нейронных сетей могут занимать много места на диске. Почти все пространство занимают веса нейронных связей, так как в одной модели много миллионов таких весов.

Узлы и веса нейронной сети обычно хранятся как 32-битные числа с плавающей запятой. Цель квантования — сжать размер файлов при помощи хранения минимума и максимум каждого слоя, а затем привести каждое плавающее значение к восьмибитному целому числу. Размер файлов сокращается на 75%.

Код для квантования:

curl -L "https://storage.googleapis.com/download.tensorflow.org/models/inception_v3_2016_08_28_frozen.pb.tar.gz" |
  tar -C tensorflow/examples/label_image/data -xz
bazel build tensorflow/tools/graph_transforms:transform_graph
bazel-bin/tensorflow/tools/graph_transforms/transform_graph \
--in_graph=tensorflow/examples/label_image/data/inception_v3_2016_08_28_frozen.pb \
  --out_graph=/tmp/quantized_graph.pb \
  --inputs=input \
  --outputs=InceptionV3/Predictions/Reshape_1 \
  --transforms='add_default_attributes strip_unused_nodes(type=float, shape="1,299,299,3")
    remove_nodes(op=Identity, op=CheckNumerics) fold_constants(ignore_errors=true)
    fold_batch_norms fold_old_batch_norms quantize_weights quantize_nodes
    strip_unused_nodes sort_by_execution_order

Примечание: в наш docker image уже встроено квантование.

Фаза 3 — предсказание на новых изображениях

Шаг 5 — захват нового изображения посредством камеры

Вам нужна будет работающая камера Raspberry Pi. Затем захватите новое изображение.

Для инструкции по установке посмотрите эту ссылку.

Шаг  6 — прогноз на основе нового изображения

Скачайте модель

Как только вы закончите обучать модель, вы можете скачать её на Pi. Чтобы экспортировать модель, запустите:

sudo nvidia-docker run -v `pwd`:data docker.nanonets.com/pi_training -m export -a ssd_mobilenet_v1_coco -e ssd_mobilenet_v1_coco_0 -c /data/0/model.ckpt-8998

Затем загрузите модель на Raspberry Pi.

Установка TensorFlow на Raspberry Pi

В зависимости от устройства вам, возможно, нужно будет изменить установку.

sudo apt-get install libblas-dev liblapack-dev python-dev libatlas-base-dev gfortran python-setuptools libjpeg-dev
sudo pip install Pillow
sudo pip install http://ci.tensorflow.org/view/Nightly/job/nightly-pi-zero/lastSuccessfulBuild/artifact/output-artifacts/tensorflow-1.4.0-cp27-none-any.whl
git clone https://github.com/tensorflow/models.git
sudo apt-get install -y protobuf-compiler
cd models/research/
protoc object_detection/protos/*.proto --python_out=.
export PYTHONPATH=$PYTHONPATH:/home/pi/models/research:/home/pi/models/research/slim

Запустите модель для прогноза

python ObjectDetectionPredict.py --model data/0/quantized_graph.pb --labels data/label_map.pbtxt --images /data/image1.jpg /data/image2.jpg

Измерение производительности Raspberry Pi

У Raspberry Pi есть ограничения по памяти и вычислительной мощности (совместимая с GPU Raspberry Pi версия TensorFlow пока недоступна). Таким образом, важно измерить, сколько времени у модели займет создание прогноза на новом изображении.

Рабочий процесс с NanoNets

Наша цель в NanoNets — сделать работу с глубоким обучением очень простой. Обнаружение объектов — это важная область для нас, и мы создали процесс, который решает много проблем с внедрением моделей глубокого обучения.

Как NanoNets делает процесс проще:

  1. Не требуется аннотация

Мы убрали потребность в аннотации изображений, у нас есть аннотаторы, которые сделают это за вас.

  1. Автоматизация лучшей модели и выбор гиперпараметров

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

  1. Отсутствие необходимости в дорогом оборудовании

NanoNets находится в облаке и работает. не используя ваше оборудование.

  1. Совместимость с мобильными устройствами вроде Raspberry Pi

Так как устройства вроде Raspberry Pi и смартфоны не созданы для сложных вычислительных задач, вы можете передать рабочий процесс в облако, которое делает все вычисления за вас.

Вот небольшой отрывок для создания прогноза на основе изображения при помощи NanoNets API

Создание своей NanoNet


Вы можете создать свою модель при помощи:

  1. Используя GUI и автоаннотацию модели
  2. Используя наш API

Шаг 1: клонируйте репозиторий

git clone https://github.com/NanoNets/object-detection-sample-python.git
cd object-detection-sample-python
sudo pip install requests

Шаг 2: получите бесплатный ключ API

Получите бесплатный ключ API здесь.

Шаг 3: установите ключ API как Environment Variable

export NANONETS_API_KEY=YOUR_API_KEY_GOES_HERE

Шаг 4: создайте новую модель

python ./code/create-model.py

Примечание: здесь генерируется MODEL_ID, который вам нужен будет для следующего шага.

Шаг 5: установите Model ID как Environment Variable

export NANONETS_MODEL_ID=YOUR_MODEL_ID

Шаг 6: загрузите данные для обучения

Соберите изображения объекта, который вы хотите обнаруживать. Вы можете оставлять аннотации при помощи нашего веб-UI (https://app.nanonets.com/ObjectAnnotation/?appId=YOUR_MODEL_ID) или использовать инструменты с открытым исходным кодом вроде labelImg. Как только в вашем наборе данных будет готовы папки, аннотации и изображения, начните загружать набор данных.

python ./code/upload-training.py

Шаг 7 — обучение модели

Как только изображения загружены, начните обучать модель.

python ./code/train-model.py

Шаг 8 — получите состояние модели

Обучение модели занимает два часа. Вы получите письмо, как только обучение закончится. В процессе вы можете проверять состояние модели.

watch -n 100 python ./code/model-state.py

Шаг 9 — сделайте прогноз

Как только модель будет обучена, вы сможете делать прогнозы.

python ./code/prediction.py PATH_TO_YOUR_IMAGE.jpg

Код на GitHub

Обучение модели

Код TensorFlow для обучения и квантования модели

Код NanoNets для обучения модели

Прогнозы на Raspberry Pi

Код TensorFlow для прогнозов на Raspberry Pi

Код NanoNets для прогнозов на Raspberry Pi

Наборы данных с аннотациями

Автомобили на индийских дорогах

Набор данных Coco

Комментарии
Продолжить чтение

A/B тестирование

A/B-тестирование в Firebase: часть 2

Продолжаем изучать Remote Config и A/B-тестирование в Firebase и учимся делать ваших пользователей самыми счастливыми!

AppTractor

Опубликовано

/

Автор:

Расширенный пользовательский таргетинг

Давайте изменим механизмы, чтобы понять, что еще мы можем сделать с Firebase Remote Config вне A/B-теста.

В предыдущем уроке вы избежали международного кризиса, установив shouldWeIncludePluto в true для ваших пользователей в Скандинавии. Оказывается, однако, что такой настройки на основе страны недостаточны. Выбор того, планета ли Плутон, является глубоко личным, и многие люди со всего мира хорошо относятся к планетному статусу Плутона. Как мы можем настроить Planet Tour для всех?

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

Свойства пользователя в Google Analytics

Свойство пользователя в Google Analytics для Firebase – это просто свойство, связанное с конкретным пользователем.

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

В вашем случае вы будете использовать свойство likeSmallRocks, чтобы понять то, как пользователь относится к небольшим, холодным скалам на окраинах нашей солнечной системы. Затем вы будете использовать это свойство в сочетании с Remote Config, чтобы предоставить пользователям новый опыт на основе этого значения.

Хотя существуют разные способы определить, является ли пользователь поклонником маленьких отдаленных скальных пород, проще всего просто спросить их.

В верхней части PlanetsCollectionViewController.swift добавьте эту строку:

import Firebase

Затем добавьте следующее определение reuseIdentifier:

private let takenSurveyKey = "takenSurvey"

Наконец, добавьте следующее внутри расширения с помощью MARK: – Internal, прямо над функцией addFancyBackground ().

@objc func runUserSurvey() {
  let alertController = UIAlertController(title: "User survey",
    message: "How do you feel about small, remote, cold rocks in space?",
    preferredStyle: .actionSheet)

  let fanOfPluto = UIAlertAction(title: "They're planets, too!", style: .default) { _ in
      Analytics.setUserProperty("true", forName: "likesSmallRocks")
  }

  let notAFan = UIAlertAction(title: "Not worth my time", style: .default) { _ in
      Analytics.setUserProperty("false", forName: "likesSmallRocks")
  }

  alertController.addAction(fanOfPluto)
  alertController.addAction(notAFan)
  navigationController?.present(alertController, animated: true)

  UserDefaults.standard.set(true, forKey: takenSurveyKey)
}

Нужно отметить две вещи в опросе, который вы добавили – во-первых, после того, как вы получите ответ от пользователя, вы записываете его в новое свойство пользователя likesSmallRocks. Во-вторых, вы делаете заметку в UserDefaults этого пользователя, который уже принял участие в опросе, чтобы его не спрашивать каждый раз при посещении приложения.

Теперь, когда вы определили свое свойство пользователя в коде, вам необходимо выполнить второй шаг, который позволяет консоли Firebase знать, что это свойство существует, чтобы оно могло начать создавать отчеты на его основе. Лучше всего добавлять user property в консоль Firebase одновременно с добавлением ее в код. Откройте консоль Firebase и выберите «Google Analytics», затем «User Properties» .

Теперь будьте осторожны в следующем шаге – консоль Firebase не позволяет редактировать или удалять свойства пользователя после их создания! Выберите NEW USER PROPERTY и создайте новую запись, которая называется likeSmallRocks. Я рекомендую копировать и вставлять имя, чтобы убедиться, что оно точно соответствует. Дайте ему любое описание, которое вы хотели бы. Затем нажмите CREATE.

Вернитесь в PlanetsCollectionViewController.swift и в конце viewDidAppear(_:) и добавьте эти строки, чтобы убедиться, что вы запрашиваете это только один раз при установке приложения:

if !UserDefaults.standard.bool(forKey: takenSurveyKey) {
  runUserSurvey()
}

Если вы хотите немного упростить тестирование, добавьте этот код viewWillAppear(_:) выше customizeNavigationBar(), который добавит кнопку на панель навигации, чтобы запустить опрос в любое время, минуя проверку того, что вы уже видели это:

let retakeSurveyButton = UIBarButtonItem(barButtonSystemItem: .compose,
                                         target: self,
                                         action: #selector(runUserSurvey))
parent?.navigationItem.rightBarButtonItem = retakeSurveyButton

Создайте и запустите приложение. Теперь вас спросят, как вы относитесь к маленьким скалам в космосе. Не стесняйтесь и честно ответьте.

Настройка вашего приложения

Теперь вы можете начать настройку Remote Config на основе этого значения. Откройте консоль Firebase и выберите Remote Config. Если вы закончили предыдущий туториал, вы увидите свою запись для shouldWeIncludePluto. И если вы этого не сделали, создайте ее заново.

Если вам нужно создать, сначала нажмите «ADD YOUR FIRST PARAMETER». Затем введите значение параметра shouldWeIncludePluto для Parameter key и сохраните значение по умолчанию пустым (Default value). Затем нажмите ADD PARAMETER.

Нажмите значок карандаша рядом с надписью shouldWeIncludePluto, чтобы изменить его, затем выберите Add value for condition > Define new condition. Назовите новое условие «Small rock fans» и укажите это условие, если User property > likesSmallRocks | exactly matches | true.

Примечание. Не выбирайте оператор сравнения == в этом диалоговом окне – это используется только для чисел.

Нажмите CREATE CONDITION, затем установите для этого значения значение true и значение по умолчанию – false .

Примечание. Если вы не выполнили предыдущий туториал, то здесь не будет состояния «Pluto fans». Ничего страшного!

Нажмите UPDATE, затем PUBLISH CHANGES.

Теперь создайте и запустите приложение снова.

Если вы указали, что являетесь фанатом маленьких отдаленных планет, то теперь вы должны увидеть Плутон среди списка планет. Если вы этого не сделали, вы не увидите Плутон… если ваше устройство не думает, что оно находится в скандинавской стране, и в этом случае Плутон все еще там (при условии, что вы прошли предыдущий туториал и установили это условие).

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

Как насчет внесения некоторых более тонких изменений в призыв к действию для ваших поклонников Плутона? В вашем приложении есть переменная planetImageScaleFactor,  которая определяет, насколько близко размер изображений планеты соответствует фактическому размеру соответствующей планеты.

При значении 1.0 они соответствуют масштабу, поэтому планеты, подобные Плутону, едва ли с пиксель велиичной. При значении 0.0, все планеты имеют одинаковый размер. Прямо сейчас эта переменная имеет значение по умолчанию 0.33, которое дает вам представление об относительных размерах планет, в то же время делая их легкими для обнаружения.

Нужно немного уменьшить это значение для поклонников небольших планет, чтобы более мелкие планеты, такие как Плутон и Меркурий, стали больше.

Вернитесь в Remote Config в консоли Firebase и создайте новую запись для planetImageScaleFactor. Дайте ему значение 0,2 для пользователей в состоянии «Small rock fans» и значение по умолчанию 0,45. Нажмите UPDATE, затем PUBLISH CHANGES.

Снова запустите Planet Tour. В зависимости от того, как вы относитесь к маленьким скалам, планеты, такие как Марс или Плутон, должны выглядеть пропорционально больше или меньше.

Хотя это может показаться забавным и несущественным изменением, такие типы настроек могут быть весьма полезными. Когда вы узнаете больше о своих пользователях и разных частях своего приложения, которые они предпочитают, вы можете начать предоставлять пользователям по-настоящему индивидуальный опыт, сделав так, чтобы элементы, которые им нравятся, были всегда впереди и в центре.

И вы можете выполнить некоторые A/B-тесты с этими параметрами, чтобы узнать, что делает пользователей вашего приложения самыми счастливыми!

Комментарии
Продолжить чтение

Реклама

Наша рассылка

Каждому подписавшемуся - "1 час на UI аудит": бесплатный ускоренный курс для разработчиков!

Нажимая на кнопку "Подписаться" вы даете согласие на обработку персональных данных.

Вакансии

Популярное

X
X

Спасибо!

Теперь редакторы в курсе.