-
Notifications
You must be signed in to change notification settings - Fork 0
yavka summary.md
Този път, за жалост, няма да мога да дам техническо описание на алгоритмите, които използваме за генериране на текст, защото просто използвам #нещо-готово.
Преди време бях чел малко за невронни мрежи, откъдето се сетих за следната статия. Няма да перифразирам цялата статия, но за тези, на които не им се чете, генерират неща като Шекспир, Съчинения на Пол Грейъм, Уикипедия страници, математически формули и даже source code на Линукс ядрото.
Ето пример с Шекспир:
PANDARUS: Alas, I think he shall be come approached and the day When little srain would be attain'd into being never fed, And who is but a chain and subjects of his death, I should not sleep.
Second Senator: They are away this miseries, produced upon my soul, Breaking and strongly should be buried, when I perish The earth and thoughts of many states.
DUKE VINCENTIO: Well, your wit is in the care of side and that.
Second Lord: They would be ruled after this chamber, and my fair nues begun out of the fact, to be conveyed, Whose noble souls I'll have the heart of the wars.
Clown: Come, sir, I will make did behold your worship.
VIOLA: I'll drink it.
Първоначалната ми идея бе да използвам алгоритъма от тази статия, но да обуча мрежата с текстове от ГП. Проблемите с това бяха три:
- Невронните мрежи се нуждаят от голямо количество информация, но не намерих много текстове на ГП.
- Обучаването на невронна мрежа отнема много време.
- Обучаването изисква мощен процесор.
Първия проблем можем да решим като не използваме само текстове на ГП, а включим и други певци. Резултатът няма да е съвсем в негов стил, така че това е само временно решение. Третият проблем можем да прескочим като обучим мрежата на някой мощен сървър.
За жалост, обаче, няма начин да скъсим времето за обучение значително. В повечето статии за невронни мрежи, хората обучават мрежата поне няколко часа, а понякога дори със седмици. Ние нямахме толкова време на разположение, а и няма как да бъдем сигурни, че това, което ще получим на изхода, ще бъде използваемо.
Започнах да търся алтернативи на невронни мрежи, с идеята все пак да пусна една мрежа, но да не разчитам само и единствено на нейния резултат. Така попаднах на следната статия за Markov chains. След малко четене в Wikipedia, се сетих, че UserSim бота на Reddit (от който взех идеята за Slack user simulator) също използва Markov chain.
От там попаднах на страницата на тази библиотека за Markov chain, която ползвам и в крайния продукт.
Първите няколко теста на библиотеката направих като копирах текстовете на песните на ГП, (които успях да намеря на този сайт)[textove.com] на ръка.
Бях си наумил няколко идеи, които исках да пробвам с генерирането. За целта ми трябва по-автоматизиран процес за теглене на текстове. След близо 1 час търсене на безплатно API за текстове с Мони, реших, че по-лесно мога да напиша scraper за textove.com.
В следващите няколко дни изпробвах идеи да подобря резултата от библиотеката:
Първо добавих памет към Markov chain-а, така че да помни последните N думи. Те се подават като вход за следващото изречение, и алгоритъма се опитва да генерира изречение, което включва колкото може повече думи. Идеята на този експеримент бе да се получат по-свързани изречения, но резултатът не бе толкова добър колкото очаквах. Изреченията наистина ми се струваха по-свързани, но генераторът често влизаше в цикъл когато попадне на дума, която се среща в много малко изречения, например “Нескафе” в текстовете на Ъпсурт.
Следващата ми промяна бе да използвам N случайни думи от последното изречение, за да създам новото. Очаквах циклите да се пораждат доста по-рядко, но на практика нямаше особена промяна. След малко debug logging, забелязaх, че в текстовете, които използвам, има доста повтарящи се думи и частици. Например, думата “да” се среща на 610 места в текстовете на Азис, и затова е много вероятно да бъде избрана. Резултатът е поредица от изречения, във всяко от което се съдържа думата “да”.
За да избегна това, въведох списък от забранени думи, в който пазя последните M използвани входни думи. Така единствените цикли, които могат да се получат са серия от няколко изречения, които се повтарят, но това е малко вероятно да се случи. По-вероятно е, обаче, да генерираме изречение, в което има само забранени думи, и да няма как да продължим. В този случай, алгоритъма прави няколко опита с различни комбинации от думи, и ако не успее да генерира подходящо изходно изречение, не подава входни думи на генератора.
Това драстично намали появата на цикли в изходните текстове, но резултатът отново не бе особено свързан. Част от причината за това е, че по-популярните думи влизат в списъка със забранени думи много бързо, след което алгоритъма има избор между средно използвани думи и много-рядко използвани думи. Това води до ситуации, в които ако алгоритъма използва дадена рядко срещана дума, следващите изречения винаги са едни и същи.
Реших проблема като промених алгоритъма винаги да подбира най-популярните думи от текущото изречение, които не са били използвани до момента. Така, алгоритъма винаги има възможно най-големия набор от потенциални изречения.
Единствено не ми хареса, че използвам някаква библиотека без да разбирам какво прави и как работи.