wafel93
wafel93
No elo swiry z #python #machinelearning #tensorflow
Mam takie zadanie do wykonania, jestem newbie i zastanawiam sie nad generalnym podejsciem/architektura:

Generowanie textu na podstawie podprzednio widzianych zdan oraz przekazanego kontekstu (slowa kluczowe).
W pierwszym przypadku jak rozumiem, moge zastosowac jakas rekurencyjna warstwe np LSTM, GRU, zmapowac zdania na chary i jako cel ustawic wybor kolejnej litery - zrobiem pare takich.
Ale w jaki sposob moge przekazac konktekst wypowiedzi? Np. uczenie generowania zdan ala Shakespear lub Nietzsche? Zalozmy ze dane wejsciowe bede mial dodatkowo otagowane taka statyczna flaga oznaczajaca autora.
  • Najlepsze
  • Wszystkie komentarze
matwiejblyat
Nie bardzo rozumiem. Dowiązujesz kontekst do autora gdzie to są odrębne rzeczy. Żeby sieć się nauczyła pisać/mówić/cokolwiek jak ktoś konkretny to musisz w nią pakować dane z tego kogoś konkretnego. Żeby coś takiego osiągnąć to ja bym przepuścił trenowanie raz na danych z Shakespeara, zapisał stan sieci, drugi raz na danych z nietzshego i zapisał do odrębnego pliku. Wczytanie stanu sieci to nie jest jakieś drogie zadanie. A flagowanie to właśnie do
mrocznapszczola
Generowanie tekstu to nie trywialny problem. Nie siedzę w tym temacie ale z tego co się orientuję będzie ciężko zrobić jeden model który generuje tekst wielu autorów opierając się na znaczniku, chyba że będzie to jakiś model łączony. Zobacz czy tutaj nie ma nic co może pomóc:
paperwithcode
OpenML
Github
skrzacik320
skrzacik320
@wafel93: Możesz sobie autorów zakodować w embeddings i potem używać ich jako h0 dla twoich rnn-ów.
wafel93
wafel93
wafel93 Autor
0
@matwiejblyat: to nie do końca jest tak, że mam 2 autorów - mam tagi do tekstu, słowa kluczowe - a więc średnio robić ręcznie osobną sieć na każdą możliwość. Dostałem radę, żeby zrobić to na zasadzie modelu seq2seq i to by nawet grało, tyle że pierwszy człon nie powinien być sekwencyjny ( w sensie, bez znaczenia w jakiej kolejności są tagi, liczy się ich obecność). Nie bardzo wiem jak z
wafel93
wafel93
wafel93 Autor
0
@mrocznapszczola: na tym githubie chyba faktycznie coś jest, table-to-text generation brzmi podobnie jak mój problem, zobaczymy - dzięki wielki :)
wafel93
wafel93
wafel93 Autor
0
@skrzacik320: jako h0, czyli? Ogólnie myślałem, żeby doklejać do litery wejściowej jakiś dodatkowy wektor określający autorów i jako dana wyjściowa patrzeć na rzeczywistą literę danego autora. Tylko nie wiem czy mi sieć nie zwariuje - czy tak się w ogóle da zrobić (╯︵╰,)
skrzacik320
skrzacik320
@wafel93: Przede wszystkim koduj całe wyrazy, a nie pojedyncze litery. W tym temacie poczytaj na temat BERT. Jak używasz Pytorch, to sprawdź sobie bibliotekę AllenNLP.

h0 to jest stan początkowy dla komórki rnn. Potem komórka wczytuje po kolei tokeny (czyli zakodowane znaki / wyrazy) i przy każdym zmienia ten stan na kolejny.

Najpierw skup się na tym jak działają LSTM, potem czym jest atencja (xD), a potem jak działa Transformer.
wafel93
wafel93
wafel93 Autor
0
@skrzacik320: przerobiłem prawie dwie książki z przykładami i nadal nie wiem jak dziala LSTM albo co to jest Transformer xDD
Mam do Ciebie dwa pytania, skoro tak:
1) Dlaczego lepiej jest kodować całe wyrazy niż litery? Generalnie nie mam zbyt dużo danych, ok 20k zdań z tagami opisującymi każde z nich - może powiem totalną głupotę - czy nie lepiej w takim wypadku stosować pojedyncze litery?
2) Dostałem początkowe info
skrzacik320
skrzacik320
@wafel93: https://colah.github.io/posts/2015-08-Understanding-LSTMs/ - bardzo dobrze wytłumaczone i zilustrowane jak działają RNN, LSTM i GRU.

Kodować całe wyrazy jest lepiej po prostu dlatego, że wtedy sekwencja jest o wiele krótsza. Jak napiszesz zdanie "Ala ma kota" to zakodowanie tego wyrazami da Ci sekwencję o długości 3, a znakami 11. I odwrotnie, stworzenie tego zdania przez model będzie wymagało wygenerowania 3 wartości zamiast 11.

Seq2seq to inaczej architektura encoder-decoder, może pod tym hasłem znajdziesz więcej
wafel93
wafel93
wafel93 Autor
0
@skrzacik320: jeśli nadal masz cierpliwość do jakiegoś randoma z neta (za co super dziękuję swoją drogą), to poczytałem dalej i mam następujące przemyślenia:

1) mój problem nie jest klasycznym Seq2Seq -> oglądałem jakiegoś mądrego azjatę na YT i przedstawiał tam różne struktury RNN. Wspomniany wyżej zakłada, że Input jest sekwencyjny, jak w przypadku np. tłumaczenia zdań z angielkiego na polski (w wielkim uproszczeniu jak rozumiem). Powiedział także o modelu One2Many, który
skrzacik320
skrzacik320
@wafel93: Ok, zacznijmy od Embeddings, a później przejdziemy do reszty. To, co wcześniej o krótszym kodowaniu nadal ma znaczenie, ale to było trochę nadmierne uproszczenie.

Embeddings to przypisanie każdemu elementowi (w tym wypadku literze albo słowu) wektora n liczb. Można na to patrzeć, jak na współrzędną tego elementu w n-wymiarowej przestrzeni. Na początku, gdy inicjujemy losowo, te elementy są porozrzucane w tej przestrzeni chaotycznie i bez sensu.

W trakcie treningu te współrzędne
skrzacik320
skrzacik320
@wafel93: Twój zestaw danych jak rozumiem wygląda tak:

(autor, zdanie) -> (następne zdanie)

Jeśli kodujesz całe słowa, to możesz po prostu scalić autora i zdanie w jeden string, tak że słowo reprezentujące autora będzie zawsze na pierwszym miejscu. Więc twój przykład będzie wyglądał
skrzacik320
skrzacik320
@wafel93: Czytam twoje posty i nie mogę zrozumieć jak właściwie wyglądają twoje dane wejściowe i wyjściowe. Możesz tutaj pokazać 5 przykładów ze zbioru, na którym chcesz trenować? :-P
wafel93
wafel93
wafel93 Autor
0
@skrzacik320: a więc może wyłożę karty na stół, bo to z autorami to było jedynie porównanie - na takich przykładach ogarniałem Seq2Seq.

Mój zbiór danych to komentarze do zdjęć - każde zdjęcie jest otagowane kilkoma słowami kluczowymi (np. animal, ecology). Same komentarze są raczej jednozdaniowe i mało skomplikowane (Instagram :P), aczkolwiek problematyczny moze być fakt, że jest w nich dużo emotek (które być może wyfiltruję, jeśli okaże się to zbyt złożony problem
skrzacik320
skrzacik320
@wafel93: Aaaa to rozumiem :-) Rzeczywiście to nie jest seq2seq. Na początku możesz spróbować najprościej jak się da, bez żadnych rnn. Po prostu robisz sieć, która koduje te tagi w multi-hot i wypluwa wektory ze zdaniami o stałej długości. Jak mówisz, zdania są krótkie, więc mogłoby to nawet zadziałać. Np. wyjściem twojej sieci byłby tensor o rozmiarze [batch, length, token] gdzie batch to liczba przykładów, length to maksymalna długość zdania,
wafel93
wafel93
wafel93 Autor
0
@skrzacik320: wlasnie przerabiam o co chodzi w embeddings i faktycznie, znalem jedynie wierzcholek gory lodowej xD

W zasugerowanym przykladzie bez RNN, jak rozumiem, zakladam kodowanie literowe.
Input = array[200], gdzie 1 sa tylko uzywane tagi, np. input[34] = 1, bo ecology tam zakodowalem.
Przepuszczam calosc przez warstw Dense