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

Практически стратегии за решаване на проблеми за работещия учен по данни

Всеки един ред код, писан някога, в крайна сметка е направен с една цел: да решава проблеми. Без значение какво правите, вие решавате проблеми в няколко мащаба едновременно.

Малък едноредов ред решава проблем, който кара функцията да работи. Функцията е необходима за тръбопровод за обработка на данни. Тръбопроводът е интегриран в платформа, която позволява решение, управлявано от машинно обучение, за своите потребители.

Проблемите са навсякъде. Тяхната величина и въздействие може да са различни, но общите стратегии за решаване на проблеми са едни и същи.

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

Имайки опит в областта на математиката на изследователско ниво, имах възможността да практикувам решаване на проблеми и да наблюдавам процеса. Изненадващо, това не е нещо, което трябва да импровизирате всеки път. По-скоро,

успешният решаващ проблеми има няколко стандартни инструмента и общ план под колана си, като се адаптира, докато върви.

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

Увеличаването е процесът на генериране на нови данни от наличните изображения чрез прилагане на произволни трансформации като изрязване, замъгляване, промени на яркостта и т.н. Вижте изображението по-горе, което е от readme на страхотната библиотека albumentations.

Трябва да доставите функцията до следващата седмица, така че трябва да започнете работа по нея веднага. Как да подходим към проблема?

(Като самият аз съм математик, мисловният ми процес е силно повлиян от книгата „Как да го решим от Джордж Поля“. Въпреки че математическият проблем е различен от проблемите с кодиране в реалния живот, това е задължително четиво за всеки, който иска да се справи добре с разрешаване на проблем.)

Стъпка 0: Разбиране на проблема

Преди да се опитате да разрешите какъвто и да е проблем, който имате предвид, има някои въпроси, на които трябва да се отговори. Неразбирането на някои детайли правилно може да доведе до загуба на време. Определено не искате да правите това. Например, добре е да сте наясно със следното.

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

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

Когато разберете вашите ограничения и имате донякъде точна спецификация на проблема, е време да се захванете за работа.

Стъпка 1. Има ли съществуващо решение?

Първото нещо, което винаги трябва да правите, е да търсите съществуващи решения. Освен ако не прекрачвате самите граници на човешкото познание, някой друг вече се е сблъсквал с този проблем, създал е нишка в Stack Overflow и евентуално е написал библиотека с отворен код около нея.

Възползвайте се от това. Има няколко предимства от използването на добре установени инструменти, вместо да създавате свои собствени.

  • Спестявате огромно количество време и работа. Това е от съществено значение, когато работите в кратки срокове. (Един от моите учители казваше иронично, че „можете да спестите един час търсене в Google с два месеца работа“. На място.)
  • Установените инструменти е по-вероятно да бъдат правилни. Инструментите с отворен код се валидират и проверяват постоянно от общността. По този начин е по-малко вероятно да съдържат грешки. (Разбира се, това не е гаранция.)
  • По-малко код, който трябва да поддържате. Отново, винаги трябва да се стремим към намаляване на сложността и за предпочитане количеството код. Ако използвате външен инструмент, не е нужно да се притеснявате за поддръжката му, което е много. Всеки ред код има скрити разходи за поддръжка, които трябва да бъдат платени по-късно. (Често когато е най-неудобно.)

Младшите разработчици и специалистите по данни често ги пренебрегват и предпочитат винаги да пишат всичко от нулата. (Със сигурност го направих, но бързо се научих да знам по-добре.) Най-екстремният случай, който съм виждал, беше разработчик, който написа своя собствена рамка за дълбоко обучение. Не трябва никога да правите това, освен ако не сте изследовател в дълбокото обучение и имате идея как да се справите значително по-добре от съществуващите рамки.

Разбира се, не всички проблеми изискват цяла рамка, може би просто търсите едноредова. Търсенето на съществуващи решения със сигурност може да бъде от полза, въпреки че трябва да внимавате в този случай. Намирането и използването на кодови фрагменти от Stack Overflow е добре само ако отделите време, за да разберете как и защо работи. Ако не го направите, това може да доведе до неприятни сесии за отстраняване на грешки по-късно или дори до сериозни уязвимости в сигурността в най-лошия случай.



За тези по-малки проблеми търсенето на съществуващо решение се състои от разглеждане на уроци и най-добри практики. Като цяло има баланс между безмилостния прагматизъм и нестандартното мислене. Когато внедрите нещо по начин, който обикновено се прави, вие правите услуга на разработчиците, които ще използват и поддържат тази част от кода. (Често включително и вас.)

Има съществуващо решение. Какво следва?

Да предположим, че по пътя си към осигуряване на увеличаване на изображението за вашия тръбопровод за предварителна обработка на данни сте последвали моя съвет, потърсили сте съществуващи решения и сте открили страхотната библиотека „albumentations“. Страхотен! Какво следва?

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

  • Работи ли добре и дали се поддържа правилно? Има едно нещо, което е по-лошо от това да не използвате външен код: използването на външен код с грешки и неподдържан код. Ако даден проект не е добре документиран и не се поддържа, трябва да го избягвате.
    За по-малки проблеми, където отговорите обикновено могат да бъдат намерени в Stack Overflow, частта добре работи е от съществено значение. (Вижте публикацията, която съм свързал по-горе.)
  • Адаптира ли се директно? Например, ако използвате библиотека за обработка на изображения, която не е съвместима с albumentations, тогава трябва да свършите допълнителна работа. Понякога това може да е твърде много и трябва да потърсите друго решение.
  • Адекватно ли работи? Ако трябва да обработвате хиляди изображения в секунда, производителността е фактор. Една библиотека може да е напълно удобна за използване, но ако не успее да работи, трябва да си отиде. Това може да не е проблем за всички случаи (например, ако просто търсите бързо решение за провеждане на експерименти), но ако е, трябва да се открие рано, преди да се работи много по него.
  • Разбирате ли как работи и какви са основните предположения? Това е особено вярно за използването на кодови фрагменти за препълване на стека, поради причините, които споменах по-горе. За по-сложни проблеми, като проблема с увеличаването на изображението, не е необходимо да разбирате всяка част от външния код ред по ред. Трябва обаче да сте наясно с изискванията на библиотеката, например формата на входните изображения.

Това, разбира се, е приложимо само ако наистина можете да намерите външно решение. Прочетете, за да видите какво да правите, когато това не е така.

Ами ако няма съществуващи решения?

Понякога трябва да разработите решение сами. Колкото по-малък е проблемът, толкова по-често се случва. Това са чудесни възможности за учене и изграждане. Всъщност това е действителната част от разрешаването на проблеми, тази, която прави много от нас най-развълнувани.

Има няколко стратегии, които да използвате, всички те трябва да са във вашия инструментариум. Ако четете внимателно, ще забележите, че има общ модел.

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

По същество решаването на проблеми е итеративен процес, при който разделяте проблема стъпка по стъпка, като в крайна сметка го свеждате до лесно разрешими части.

Стъпка 2. Разбийте разтвора (по избор)

Има една обща черта, която забелязах в много отлични математици и разработчици: те се радват да избират решение, анализирайки какво ги кара да работят. Това е начинът, по който се учите и изграждате стабилен, но прост код.

Чупенето на неща може да бъде част от процеса на решаване на проблеми. Преминавайки от специален случай към общ, обикновено откривате решения, като счупите това, което имате.

Когато е направено

В зависимост от мащаба на самия проблем, трябва да обмислите използването му с отворен код, ако ви е позволено. Решаването на проблеми за други разработчици е чудесен начин да допринесете за общността.

Например, така създадох modAL, една от най-популярните библиотеки за активно обучение за Python. Започнах от много специфичен проблем: изграждане на тръбопроводи за активно обучение за биоинформатика. Тъй като изграждането на сложни методи винаги изисква експериментиране, имах нужда от инструмент, който позволява бързо експериментиране. Това беше трудно постижимо с наличните рамки по това време, така че бавно трансформирах кода си в инструмент, който лесно може да бъде възприет от други.



Това, което преди беше „само“ решение, се превърна в библиотека с хиляди потребители.

Заключение

Противно на общоприетото схващане, ефективното решаване на проблеми не е същото като постоянното представяне на гениални идеи. По-скоро това е мисловен процес с някои добре дефинирани и лесни за използване инструменти, които всеки може да научи. Умните разработчици ги използват инстинктивно, правейки ги да изглеждат като магия.

Уменията за решаване на проблеми могат да бъдат подобрени с целенасочена практика и осъзнаване на мисловните навици. Има няколко платформи, където можете да намерите проблеми, върху които да работите, като Project Euler или HackerRank. Въпреки това, дори ако започнете да прилагате тези методи към проблеми, които срещате по време на работата си, ще видите, че уменията ви се подобряват бързо.

Ако обичате да разделяте концепциите за машинно обучение и да разбирате какво ги кара да работят, имаме много общи неща. Вижте моя блог, където често публикувам технически публикации като тази!