Здравейте хора, идвам към разработката, управлявана от тестове (TDD) от опит в машинното обучение (ML). Преди няколко седмици присъствах на лекция @swcraftmontreal на отличния @Khris_Fernandez — започнахме разговор.

В софтуера често нашите инструменти не са толкова добри, колкото тези, които създаваме за клиентите — използва се фразата „Децата на обущаря нямат обувки“. Толкова сме заети да създаваме инструменти за клиенти, че често не създаваме свои собствени.

Крис спомена вече вкоренения цитат Софтуерът изяжда света, но че дори сега повечето софтуери не са проверени — оттук и необходимостта от TDD. Това ме накара да се замисля за цитата AI Is Eating Software и какво означава това за TDD. (Почти всички AI са някакъв вид ML.) Усещам, че има приложение на ML към TDD практика, нещо като DeepTabNine (което прилага Deep Learning към AutoCompletion), но прилага ML към TDD.

TDD е отчаяно необходим в ML

Мисля, че TDD е страхотен, харесвам го.

Определено се използва за писане на стабилни абстрактни ML алгоритми — въпреки че използваме думата тест за различна концепция. Също така, продуктов мениджър (PM) може да определи теста за добро изпълнение на конкретно приложение с вероятностни мерки (искам програма, която работи с 98% точност, 90% запомняне, 95% точност, 80% f1-резултат за 0,4 секунди, и т.н. — за решение за класификатор — нещо подобно може да бъде указано за регресия или дори обучение с подсилване).

Това ме накара да се замисля за TDD и ML. Идеята тлее, така че пиша средна статия за нея.

Замяна на някои TDD с ML

TDD е по същество сбруя за насочване на (софтуерния инженер)SWE от изискванията за проза към последователност от 1 и 0 (програмата), която се държи в рамките на изискванията. Човек може да разглежда целия проблем като задача за контролирано обучение (ние искаме да намерим програма за решение, която преминава всички тестове — тези тестове са примери на езика на ML). Някои TDD могат/ще бъдат автоматизирани с помощта на ML. С други думи, един ML алгоритъм ще обработва тестове и след това ще генерира последователност - контролиран модел на последователност, ако искате.

Мисля, че голямата картина на това как да се заменят подзадачите на TDD е следната:

​0. примери за необработени данни (спецификации на естествения език - изискванията на PM).

1. примери за обработени данни (червени неуспешни тестове, засега все още трябва да се дефинира SWE от спецификациите).

2. алгоритъм за обучение (невронна мрежа на мозъка на програмиста).

3. стъпка на обучение/оптимизиране (писане на код за направяне на тестовете зелени).

4. регулиране (рефакторинг код).

Малко странно за настройката на ML (където груповото обучение от много примери е норма), но за всеки тестов пример, показан на системата, тя може да изпълни алгоритъма за обучение и да създаде нова последователност от 1 и 0. Тоест извършване на обучение за създаване на програма от всеки нов написан тест и за всички минали тестове, които са натрупани.

Тотализатор за количка за плодове

​По-специално с Крис направихме доджо по програмиране на количка за пазаруване на плодове с все по-сложни тестове, които тя трябваше да премине. Направихме тестове като проверка дали празна количка е 0; че един плод от списъка струва своята единична цена; че някои дадени комбинации са общи, както се очаква. Тогава станахме малко по-сложни с промоциите и отстъпките за членство.

Така че за този конкретен случай можем да съберем дъмп на базата данни с цени, суми и суми от разписки от голям търговец на дребно (да речем Walmart). След това алгоритъмът за обучение просто трябва да научи функцията, която преобразува от (цени, суми) към суми за всички примери (или тестове) в базата данни. Може да научи всички видове промоции, отстъпки за членство и условия само от примерите.

ML калкулатор

Друг пример е този отличен калкулатор. Това е калкулатор, обучен от примери. Този калкулатор е обучен от комбиниране на традиционни ML модели. Данните са примери, създадени от основни тестови шаблони за събиране, изваждане, деление и умножение. Крайната програма е модел с научени тегла и можем да видим, че работи. Може да се програмира и с помощта на традиционната TDD практика.

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

Критика: Регулирането всъщност не е рефакторинг

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

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

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

Мисленето не е толкова синьо небе

Разбира се, някой може да каже, какво да кажем, когато нямате база данни. Е, тогава това базирано на ML решение не се прилага веднага, ще трябва първо да напишем тестовете от прозата. След това алгоритъмът може да научи програма, която преминава всички определени от SWE тестове.

Човек обаче може да приеме тази идея след 3–10 години в бъдеще и да се надява на инструмент за НЛП да премине от подзадача 0 към подзадача 1. Това е усъвършенстван/специално обучен секвенсер, който може да анализира спецификациите на естествения език и изходните тестове.

В момента преводът от японски на испански в Google translate се поддържа от ML програма, GNMT. Въпреки че не е идеален, той се приближава. Не би трябвало да е толкова трудно да въвеждате проза от PM и да извеждате тестове на масов език за програмиране.

Един език, който идва на ум, еPython. Стандартният библиотечен модул doctestприложен към docstring тестове предоставя примерни тестове точно там, в изходния код — имаме нужда само от няколко милиона примера. След това преминаването от Python към всеки друг език може да стане чрез transpiler.

Всичко това може дори да е възможно сега.

Генериране на много тестове (примери)

За да могат алгоритмите за машинно обучение да работят добре върху бъдещи невиждани примери, те обикновено се нуждаят от обучение инастройка — което изисква примерите да бъдат разделени на поне два несвързани комплекта. За да коригираме това, подозирам, че ще имаме нужда от повече от един екземпляр на тест за конкретна функция (в ML функция означава нещо съвсем различно), поне един в теста за обучение и един в набора за настройка (обикновено наричан валидиране или dev set — но не искам да бъркам с гъвкавата терминология). В идеалния случай бихме искали много повече от 2 примера за тази функция (дори стотици или хиляди), но те трябва да са евтини за създаване.

Ако отидем по-дълбоко, тези тестове са примери за желана характеристика - това, което е посочено в прозата на PM. Възможно ли е да има тестов генератор, който преобразува аргументите на функцията в желаното поведение – функцията. Това би било картографиране от типове към типове - кара ме да мисля за категорична теория на типовете. Не съм сигурен как да продължа това...

Заключение

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

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

Друг момент е, че SWE е ограничен до броя тестове, които могат да бъдат обработени - тя може да премине през десетки, да кажем стотици тестове на ден. За сравнение, един ML алгоритъм би трябвало да може да обработва милиони тестове за миг на око. Добре, така че трябва да има много предупреждения и нотация с голямо О, за да се квалифицира това, но ще остане факт, че мащабът на времето, необходимо за преминаване на тестове с програма, е значително различен за Human SWE срещу Machine с интелигентен ML алгоритъм.

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

Това, което предлагам е, че ML може да пише програми, когато има набор от тестове, предоставени от PM/SWE, не само за проблеми с присъща несигурност.

​Такъв е и този самоуправляващ се назад велосипед :-)

Или казано по друг начин. The. Обущарски. деца. Ще. имам. Обувки.

Или от друга гледна точка. The. Децата на Cobbler нямат нужда да ходят. Те. Мога. Бягай. в. Кецове. „Осъществено от ML“разбира се.

Благодаря за коментарите.