Как решить проблемы с кодированием

Практические стратегии решения проблем для работающего специалиста по данным

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

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

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

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

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

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

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

Увеличение - это процесс создания новых данных из доступных изображений путем применения случайных преобразований, таких как обрезка, размытие, изменение яркости и т. Д. См. Изображение выше, которое взято из файла readme потрясающей библиотеки albumentations.

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

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

Шаг 0: понимание проблемы

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

  • Каков масштаб проблемы? В нашем примере увеличения изображения вам нужно будет обрабатывать тысячи изображений в секунду в процессе производства, или вам просто нужно поэкспериментировать с некоторыми методами? Если необходимо решение промышленного уровня, вы должны знать об этом заранее.
  • Будут ли другие люди использовать ваше решение? Если люди собираются активно работать с вашим кодом, необходимо приложить значительные усилия для обеспечения качества кода и документации. С другой стороны, если это только для вашего использования, нет необходимости так много над этим работать. (Я уже вижу людей, которые со мной не согласны :) Однако я твердо верю в минимизацию объема работы. Так что, если вам нужно только быстро опробовать идею и поэкспериментировать, не стесняйтесь не принимать во внимание качество кода.)
  • Вам нужно общее или специальное решение? Можно потратить много времени на реализацию функций, которые никто никогда не будет использовать, включая вас. В нашем примере вам нужен широкий спектр методов увеличения изображения или просто вертикальное и горизонтальное переворачивание? В последнем случае также может работать предварительное переворачивание изображений и добавление их в тренировочный набор, что требует минимальных усилий.

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

Когда вы понимаете свои ограничения и имеете несколько точную спецификацию проблемы, пора приступать к работе.

Шаг 1. Есть ли существующее решение?

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

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

  • Вы экономите огромное количество времени и работы. Это очень важно при работе в сжатые сроки. (Один из моих учителей с иронией говорил, что «вы можете сэкономить час поиска в Google с двумя месяцами работы». Примечательно.)
  • Установленные инструменты, скорее всего, будут правильными. Инструменты с открытым исходным кодом постоянно проверяются сообществом. Таким образом, они с меньшей вероятностью будут содержать ошибки. (Конечно, это не гарантия.)
  • Меньше кода для вас. Опять же, мы всегда должны стремиться к уменьшению сложности и, желательно, количества кода. Если вы используете внешний инструмент, вам не нужно беспокоиться о его обслуживании, а это очень важно. У каждой строчки кода есть скрытая стоимость обслуживания, которую нужно оплатить позже. (Часто, когда это наиболее неудобно.)

Младшие разработчики и специалисты по данным часто не обращают на них внимания и предпочитают всегда писать все с нуля. (Я, конечно, знал, но быстро научился лучше разбираться в этом.) Самый крайний случай, который я видел, - это разработчик, который написал свою собственную структуру глубокого обучения. Вам не следует никогда этого делать, если вы не являетесь исследователем глубокого обучения и не знаете, как добиться большего, чем существующие фреймворки.

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



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

Есть существующее решение. Что дальше?

Предположим, что на вашем пути к расширению изображений для конвейера предварительной обработки данных вы последовали моему совету, искали существующие решения и нашли замечательную библиотеку albumentations. Большой! Что дальше?

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

  • Хорошо ли он работает и правильно ли поддерживается? Есть одна вещь, которая хуже, чем использование внешнего кода: использование ошибочного и необслуживаемого внешнего кода. Если проект плохо документирован и не поддерживается, вам следует избегать этого.
    Для небольших проблем, ответы на которые обычно можно найти в Stack Overflow, важна часть хорошо работает. (См. Сообщение, которое я указал выше.)
  • Можно ли адаптировать напрямую? Например, если вы используете библиотеку обработки изображений, несовместимую с альбументациями, вам придется проделать дополнительную работу. Иногда этого может быть слишком много, и вам нужно искать другое решение.
  • Достаточно ли он работает? Если вам нужно обрабатывать тысячи изображений в секунду, производительность является важным фактором. Библиотека может быть очень удобной в использовании, но если она не работает, ее нужно уйти. Это может быть проблемой не для всех случаев (например, если вы просто ищете быстрое решение для проведения экспериментов), но если это так, то его следует обнаружить заранее, прежде чем прилагать к нему много усилий.
  • Понимаете ли вы, как это работает и каковы его основные предположения? Это особенно верно для использования фрагментов кода Stack Overflow по причинам, о которых я упоминал выше. Для более сложных проблем, таких как проблема увеличения изображения, вам не нужно понимать каждую часть внешнего кода построчно. Однако вам необходимо знать требования библиотеки, например, формат входных изображений.

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

Что делать, если нет существующих решений?

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

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

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

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

Шаг 2. Разбейте решение (необязательно)

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

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

Когда это будет сделано

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

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



То, что раньше было «просто» решением, превратилось в библиотеку с тысячами пользователей.

Заключение

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

Навыки решения проблем можно улучшить с помощью целенаправленной практики и осознания привычек мышления. Есть несколько платформ, на которых вы можете найти проблемы для работы, например, Project Euler или HackerRank. Однако даже если вы начнете применять эти методы к проблемам, с которыми вы сталкиваетесь во время работы, вы заметите, что ваши навыки быстро улучшатся.

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