zondag 24 mei 2020

Leren met letters 13 - Nieuwe insteek

Met een eigen getraind chars2vec model kom ik niet niet veel verder dan (ruim) 80% validation accuracy. Ik test eens wat het effect van mijn training is. Een setje woorden moet meer inzicht geven. Ik kies, in lijn met de meest voorkomende AI tests, voor o.a. katten en honden:

words = ['cat', 'catfish', 'catering','catt', 'kat','dog', 'dogfood',
        'hounddog','computer', 'computation', 'compiling',
        'mouse','mousetrap', 'mousewire','random']

Met het standaard model 50 doet hij dit:

 Standaard 100 vectoren:

Ik zie niet veel verschil. Maar nu mijn eigen getrainde model:

Hmmm. Dat ziet er zo op het eerste gezicht niet zo best uit.  Als we inzoomen is er gelukkig wel verschil:
Bijzonder dat ik uiteindelijk toch die 80% valacc haal hiermee. Ik test of het aan mijn hoofdletter toevoeging ligt met alternatieve charset of wellicht aan de gebruikte dataselectie.
Hmmm. Beide zo te zien. Weliswaar liggen de woorden nu iets beter uit elkaar maar de schaal is nog steeds klein vergeleken met de originele modellen. 

Een ander probleem blijft de de grote datasets en meerdere tussenstappen die ik moet maken om tot het gewenste resultaat te komen. 
Even ter herinnnering: Ik wil karakter input laten meespelen om woorden met een vergelijkbare stam een vergelijkbare betekenis mee te geven. Daarnaast moet ook de betekenis van woorden uit hun omgeving mee gaan tellen (word2vec). 

Wellicht is de training te combineren. Door een karakter woord als input te geven en de omliggende woorden als te voorspellen krijg ik wellicht gecombineerde woordvectoren. Zeker als ik ook mutaties op de woorden mee ga trainen. Ik maak dus voor de input een onehot op basis van de karakters en voor de output een onehot op basis van de (omliggende) woorden.

Uitdaging!!!



  


   

zondag 17 mei 2020

Leren met letters 12 - Op herhaling

Ja, dat is alweer even geleden dat ik mij met deze matererie heb bezig gehouden. (Zo te zien iets meer dan een maand). Tussendoor wat bezig geweest met een opleiding voor AI in healthcare.  Wel wat van opgestoken (sensitivity / specificity / true - false - positives - negatives / ROC / F1  etc) maar geen nieuwe experimenten mee gedaan. (en alweer een beetje vergeten :-( )



Na het laatste succes in het char2word2vec model wil ik dit toch ook eens proberen met hoofdletter gevoelige zinnen. 
Daarvoor moet ik de volgende stappen doen:
  1. De karakterset in het chars2vec model aanvullen met hoofdletters.
  2. Het chars2vec model aanpassen zodat woorden niet naar lowercase worden omgezet.
  3. Het chars2vec model trainen met een eigen woorden corpus dat ook de begin-hoofdletter mee traint.
  4. Op basis van het nieuwe chars2vec model een dataset genereren voor het trainen van 'word - embeddings'.
  5. Het movie-sentiment model trainen op basis van het eigen word2vec model en het neiuwe embeddings model.
Deel 1 en 2 lijken weinig problemen te geven. 

Bij deel 3 (train_chars2vec_eng_caps.py) loop ik tegen memory errors aan. Ik selecteer 70.000 van de aangemaakte woordparen om in 6 epochs het model te trainen. Ik vergeet de vectorgrootte in te stellen dus hij pakt de default van 50 per woord. Misschien wel voor nu even groot genoeg.

In deel 4  (new_model_for_text_evaluation_chars2vec_train_embeddings.py) maak ik bij elk woord uit de movie review corpus, de 4 omliggende woordvectoren aan. Dit om een wordembedding-model te trainen op basis van de 50 vectoren per woord. Dit geeft ook al snel memory errors. De grootte van de input (train_x) is 40.000 x 300 x 50 (zinnen x woorden x vector). Het formaat van de output (train_y) is nog eens 4 x zo groot. Voor deze training neem ik een (willekeurige) selectie van 20.000. Dit blijkt voldoende om de memory errors te ontlopen. Ik bewaar het nieuwe embedding model in 'model-best-c2w2v_v100.h5' waarbij de v100 dus feitelijk niet correct is maar goed, whats in a name?.

Deel 5 (new_model_for_text_evaluation_chars2word2vec2.py) is de 'proof of the pudding'. Ik heb daar een maand geleden met de model vormgeving zitten experimenteren en ik merk dat het begrip over de gebruikte methodiek behoorlijk is weggezakt. Ik loop dan ook al snel tegen meerdere nu onbegrijpelijke fouten aan. Maar eens kijken wat het oorspronkelijke idee is.

  1. Eerst worden de reviews weer omgezet naar v50 vectoren per woord met de functie "conv_text_ch2v". Deze verwijdert de 'tags', splitst de woorden op in zinnen, bewerkt de bijzondere tekens en vertaald vervolgens woorden naar v50 vectoren met de functie "c2v_model.vectorize_words(list of words)". Uiteraard is eerst hiervoor mijn eigen, op hoofdletters getrainde c2v model geladen.  
  2. Deze data wordt opgesplitst in een train en test deel en opgeslagen voor verder gebruik.
  3. De v50 zinnen worden als input in het te trainen eindmodel meegegeven. Daarvoor moet eerst een layer aan het model worden toegevoegd met de getrainde wordembeddings. We maken hiervoor gebruik van een 'hulpmodel':
    • c2w2v_model = load_model(path + 'model-best-c2w2v_v100.h5')
    • get_1st_layer_output = K.function([c2w2v_model.layers[0].input],
    •                                   [c2w2v_model.layers[0].output])
    • hmodel = Model(c2w2v_model.inputs, c2w2v_model.layers[0].output)
  4. Dit 'hmodel' wordt als eerste laag in het te trainen model gebruikt:
    • def Model_attention_conv_api():
    •     input_shape = Input(shape = (max_sent * max_words, max_vec))
    •     x = hmodel (input_shape)
    •     x = Dense(512) (x)
    •     x = Conv1D(512, 2, activation='relu') (x)
    •     x = AveragePooling1D() (x)
    •     x = SeqSelfAttention(attention_activation='relu') (x)
    •     x = Flatten() (x)
    •     x = Dense(128) (x)
    •     x = Dense(label_size-1, activation='sigmoid') (x)
    •     model = Model(inputs = input_shape,outputs=x)
    •     return model
Ik zie nu waarom ik een aantal fouten krijg die ik niet snap. Ik heb blijkbaar nog een poging gedaan om ook de v50 vertaling direkt in het model op te nemen. (Ben dus uitgegaan van de verkeerde code :-( ) 
Dat heb je als je er teveel tijd tussen laat zitten.  

Maar nu doet hij het:

Training met hoofdletters (F1 =  0.80)

Ok, nog geen topprestatie maar wel een aanwijzing dat de methodiek werkt.