zaterdag 20 april 2019

4 - More NLP

Inmiddels een grote serie aan variaties getest. Voor een groot deel met een beeperkte dataset (50k zinnen). Helaas om tot de conclusie te komen dat het oorspronkelijke model met een extra Dropout layer en een conv layer met bereik 7 nog het beste werkt. Tevens is het bijvoorbeeld sneller dan een eenvoudig gru model.(full data conv: 961s gru: 2386s)

Hierbij een overzicht van de uitgevoerde tests:

0 Model_attention(), Datalower + adjusted punctualities. best val_acc : 0.953899987757206
1 Model:conv(), Datalower + adjusted punctualities. best val_acc : 0.9536999876499176
2 Model:bi(), Datalower + adjusted punctualities. best val_acc : 0.9497999875545502
3   F1 :  0.7710 Model:conv() + F1 (Model:bi() F10.7404, Datalower + adjusted punctualities. best val_acc : 0.9503999890089035
4   F1 :  0.7732 Model:conv() + Conv1D layer to 7. best val_acc : 0.9475999900698662
5   F1 :  0.7197 Model:conv() + add Maxpooling + add SeqSelfAttention. best val_acc : 0.9496999888420105
6   F1 :  0.6876 Model:conv() + slow learning:optimizer=Adam(lr=0.0001) best val_acc : 0.9425999903678894
7   F1 :  0.7362 Model:conv() + Adamax best val_acc : 0.950499990105629
8   F1 :  0.7656 Model:conv() + input_length200  best val_acc : 0.9486999864578247
9   F1 :  0.7254 Model:conv() + preprocess no eol best val_acc : 0.9531999888420105
10  F1 :  0.7577 Model:conv() + expanded eol best val_acc : 0.9498999876379967
11  F1 :  0.7393 Model:conv() + keep more patience(5) + 10 epochs best val_acc : 0.9478999860882759
12  F1 :  0.7606 Model:conv() + back to best test best val_acc : 0.9492999871969223
13  F1 :  0.7384 Model:conv() + back to best test(2) best val_acc : 0.950899987399578
14  F1 :  0.7548 Model:conv() + back to best test(3) best val_acc : 0.9519999876618386
15  F1 :  0.7617 Model:conv() + reloading best model best val_acc : 0.9534999892115593
16  F1 :  0.7524 Model:conv() + Conv1D backto 5 best val_acc : 0.9479999871253967
17  F1 :  0.7370 Model:conv() + Conv1D to 9 and 1024 hidden best val_acc : 0.9527999883294106
18  F1 :  0.7555 Model:conv() + Conv1D to 7 and 1024 hidden best val_acc : 0.953199989259243
19  F1 :  0.7580 Model:conv() + Dropout(.5) best val_acc : 0.9489999877214432
20  F1 :  0.7383 Model:gru() + Dropout(.5) best val_acc : 0.9483999890089035
21  F1 :  0.7814 Model:gru() + units from 32 to 128 best val_acc : 0.9478999906182289
22  F1 :  0.7610 Model:gru() + units from 32 to 128-retest gru best val_acc : 0.9533999870419503
23  F1 :  0.7713 Model:gru() + units from 128 to 256 best val_acc : 0.9524999901056289
24  F1 :  0.6871 Model:gru() + units from 128 to 256- retest best val_acc : 0.9507999865412712
25  F1 :  0.7328 Model:gru() + units from 128 to 256- retest 2 - random_state=0 best val_acc : 0.9533999865055084
26  F1 :  0.7746 Model:gru() + units back to 128 - random_state=0 best val_acc : 0.953399988412857
27  F1 :  0.7593 Model:gru() + units back to 128 - random_state=0 - retest best val_acc : 0.9515999898314476
28  F1 :  0.7617 Model:gru() random_state=0 - retest(2) same numpy randomstate best val_acc : 0.9531999880671501
29  F1 :  0.7626 Model:gru() random_state=0 - retest(2) same numpy randomstate best val_acc : 0.9528999896645546
30  F1 :  0.7587 Model:conv() random_state=0  same numpy randomstate best val_acc : 0.9545999875664711
31  F1 :  0.7301 Model:conv() remove dropoutlayer (.5) best val_acc : 0.9543999876976014
32  F1 :  0.7322 Model:gru() add dropout + MaxPooling  best val_acc : 0.9429999912977218
33  F1 :  0.7651 Model:gru() (no dropout)  + MaxPooling  best val_acc : 0.9505999882221222
34  F1 :  0.7562 Model:gru() (no dropout)  + MaxPooling retest best val_acc : 0.9501999878287315
35  F1 :  0.7557 Model:gru2() best val_acc : 0.9496999884843826
36  F1 :  0.7589 Model:gru2() including conv layer best val_acc : 0.950699988424778
37  F1 :  0.8049 Model:gru() - full data best val_acc : 0.9505727423971995
38  F1 :  0.8058 Model:conv() - full data best val_acc : 0.946965844508675
39  F1 :  0.6837 Model:conv() - + glove (btw full data conv: 961s gru: 2386s) best val_acc : 0.9486999891996384
40  F1 :  0.7486 Model:conv() - + glove (btw full data conv: 961s gru: 2386s) best val_acc : 0.9550999863147736
41  F1 :  0.8047 Model:conv() - + glove full data - trainable emb layer best val_acc : 0.9481459817551817
42  F1 :  0.5725 Model:conv() - + glove full data best val_acc non trainable : 0.9276404074803888

Glove (pretrained embeddings) lijkt zo op het eerste gezicht weinig toe te voegen. Het is beter als de embedded layer trainable is.


dinsdag 16 april 2019

3 - more NLP

Ok, het model werkt dus maar ik had een iets beter positie op de ranglijst gehoopt. Dan maar een kijken of we e.e.a. kunnen opschroeven.

Dit is de uitgangsnorm: 94.92% val_acc

Epoch 2/20
1443899/1443899 [==============================] - 972s 673us/step - loss: 0.1309 - acc: 0.9518 - val_loss: 0.1399 - val_acc: 0.9492

Eerst maar eens kijken of we de data beter kunnen opschonen. Ik haal mer puntuaties eruit. Laat de einde regel sumbolen staan (vervang door punt) en ook de quotes maak ik eenduidig omdat ik denk dat dat kan helpen bij een tetere interpretatie. Tevens maak ik alles lowercase. Bij een test op de train resultaten scoort hij 3.77% fout. O.a. in dit soort regels:

1 0 these folks and their attorneys are a safety threat to all of society they should stay in jail .  0.04372574
1 0 i advise the feds to follow the money that is given to these anti american religious sovereign terrorists .  0.0523168
1 0 mmmmm you had me at cheap and mediocre .  0.283443
1 0 ltd needs to be neutered .  0.19635834
1 0 you re such a douche . you have no idea what you re talking about .  0.3822083
1 0 this is pretty much exactly how i feel . damn .  0.46514317
1 0 attorneys politicians and preachers doing what they do best .patting themselves and each other on the back .  0.02539003
1 0 i agree with you . obama is inflammatory and disrespectful .  0.019637559
0 1 most of the bums i see downtown won t walk   feet to throw trash in a trash can . these will do no good at all . end needle exchanges and stop giving he employment resistant free needles 0.6297242
0 1 to be fair i hear the same nonsense from the minority over the top hillary supporters . there is no lack of bernie baggers and hillary bots screaming nonsense .  0.532752
1 0 snitch 0.0067454237
1 0 what are supposed to see in the pic . the behind of a guy in a suit . really . ok .  0.02872668
1 0 jp says . " trump is a product of many angry mostly white americans " racist stereotyping duly noted .  0.39688396

  De eerste waarde is de werkelijke classifucatie en de 2e de voorspelde. Achteraan staat de oorsprongkelijke kans.

De aanpassingen leveren helaas niet veel verbeteringen op. Sterker nog we lijken iets achteruit te zijn gegaan:

Epoch 2/5
1443899/1443899 [==============================] - 912s 632us/step - loss: 0.1303 - acc: 0.9520 - val_loss: 0.1402 - val_acc: 0.9490

94.9% val_acc . Maar dat kunnen verschillen in initiatie zijn. Even in de gaten houden.



maandag 15 april 2019

2 - More NLP

Het model blijkt toch behoorlijk te werken. Alleen zo goed dat het maar 1 epoch nodig heeft om een behoorlijke validatie nauwkeurigheid te halen. Daarna gaat die 'overfitten' zo te zien.:

1443899/1443899 [==============================] - 1029s 712us/step - loss: 0.1504 - acc: 0.9461 - val_loss: 0.1406 - val_acc: 0.9486

Epoch 00001: val_loss improved from inf to 0.14065, saving model to model-best.h5
Epoch 2/20
1443899/1443899 [==============================] - 1018s 705us/step - loss: 0.1274 - acc: 0.9526 - val_loss: 0.1538 - val_acc: 0.9462

Epoch 00002: val_loss did not improve from 0.14065
Epoch 3/20
1443899/1443899 [==============================] - 1023s 708us/step - loss: 0.1084 - acc: 0.9601 - val_loss: 0.1549 - val_acc: 0.9443

Eens kijken of een paar dropout layers kan helpen om e.e.a. iets meer robuust te krijgen.

Uiteindelijk 'leen' ik een SpatialDropout layer uit ene ander voorbeeld. Ik haal een behoorlijke validation accuracy van bijna 95%

Tijd om de zaak eens aan Kaggle aan te bieden. Het is een 'Kernals only' competitie en dat heb ik nog nooit gedaan. Het blijkt noodzakelijk om de 'SelfAttention' layer bij de code op te nemen omdat dat niet standaard Keras is. Dat lukt uiteindelijk en de code is nu aan het draaien op de server. Spannend!!!

Net boven de benchmark. Valt een beetje tegen maar ik mag niet klagen voor een eerste ruwe test:

zondag 14 april 2019

1 - More NLP

Met de feitelijk succesvolle afsluiting van 'Matters that matter', waar het laatst gevonden model nu in de praktijk wordt getest, is het keuk om te kijken of het model ook bij andere nlp taken goed functioneerd. Ik vind het ongelovelijk dat het model in 2 a 3 epochs al zo snel bij zo'n hoge validatie nauwkeurigheid weet te komen. Is dit een super model voor nlp taken? Of is de data zo 'voorspelbaar'?

def Model_attention_conv():
model = Sequential()
model.add(Embedding(vocab_size, 256, input_length=input_length))
model.add(Conv1D(512, 5, activation='relu'))
model.add(MaxPooling1D())
model.add(SeqSelfAttention(attention_activation='sigmoid'))
model.add(Flatten())
model.add(Dense(labels_max, activation='sigmoid'))
return model

Ik kijk bij Kaggle of er nog een nlp uitdaging bij is gekomen. En ja hoor, er is er net weer een gestart:

Jigsaw Unintended Bias in Toxicity Classification
Detect toxicity across a diverse range of conversations


Oke, dit gaat dus over ongewenst taalgebruik in online conversaties. Leuk om ons model eens mee te testen.
Een voorbeeld van 'toxic' in de kolom 'insult' :

"haha you guys are a bunch of losers."

Met een score van 0.89.

De verschillende types toxic taalgebruik zijn wel geklassificeerd maar de contest gaat alleen over toxic ja/nee. Hierbij is > .5 toxic.

Het tokenizen en 'padding' (naar de jiuste lengte brengen) laat ik deze keer aan de Keras routins daarvoor over. En na het aanpassen van de  loss functie naar kleinste kwardratische afwijking  (mean squared error) draait het model al snel.

Model creation ...
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
embedding_1 (Embedding)      (None, 100, 256)          90746368
_________________________________________________________________
conv1d_1 (Conv1D)            (None, 96, 512)           655872
_________________________________________________________________
max_pooling1d_1 (MaxPooling1 (None, 48, 512)           0
_________________________________________________________________
seq_self_attention_1 (SeqSel (None, 48, 512)           32833
_________________________________________________________________
flatten_1 (Flatten)          (None, 24576)             0
_________________________________________________________________
dense_1 (Dense)              (None, 1)                 24577
=================================================================
Total params: 91,459,650
Trainable params: 91,459,650
Non-trainable params: 0

Helaas vallen de resultaten zwaar tegen. De loss en val_loss lijken zich niet te verbeteren ondanks bijvoorbeeld het aanpassen van de learning rate of de optimizer. (Adam naar stochastic gradient descent (SDG) . Vreemd. De aangeboden data lijkt toch goed te zijn.

In navolging van een voorbeeld kernel bij Kaggle maak ik de voorspelde uitkomensten digitaal: 0 voor < .5 en 1 voor groter >= 5.

y_train = np.where(train['target'] >= 0.5, 1, 0)

Tevens pas ik daarvoor de loss functie aan naar de 'binary_crossentropy'

Ook pas ik de manier van tokenizen aan:

Van
print('Reading data ...')
path = 'C:\\Users\\DirkW\\Documents\\Jigsaw\\'
train = pd.read_csv('C:\\Users\\DirkW\\Documents\\Jigsaw\\train.csv', encoding="ISO-8859-1") #encoding='utf-8')
train = train.fillna("")
x_train = preprocess(train['comment_text'])
x_train = x_train.astype(str, errors='ignore').values.tolist()
x_train = [''.join(x) for x in x_train]

test = pd.read_csv('C:\\Users\\DirkW\\Documents\\Jigsaw\\test.csv', encoding="ISO-8859-1")
test = test.fillna("")
x_test= preprocess(test['comment_text'])
#x_test = x_test.astype(str, errors='ignore').values.tolist()
#x_test = [''.join(x) for x in x_test]

print('Tokenizing data ...')
'''
'''
tokenizer = Tokenizer(num_words=50000)
vocab_size = len(tokenizer.word_index) + 1
tokenizer.fit_on_texts(x_train)

X_train = tokenizer.texts_to_sequences(x_train)
X_test = tokenizer.texts_to_sequences(x_test)

print('Padding data ...')
X_train = pad_sequences(X_train, padding='post', maxlen=input_length)
X_test = pad_sequences(X_test, padding='post', maxlen=input_length)

naar

train = pd.read_csv('C:\\Users\\DirkW\\Documents\\Jigsaw\\train.csv', encoding="ISO-8859-1") #encoding='utf-8')
train = train.fillna("")
x_train = preprocess(train['comment_text'])

tokenizer = text.Tokenizer()
tokenizer.fit_on_texts(list(x_train) + list(x_test))
vocab_size = len(tokenizer.word_index) + 1
x_train = tokenizer.texts_to_sequences(x_train)
x_test = tokenizer.texts_to_sequences(x_test)
x_train = sequence.pad_sequences(x_train, maxlen=input_length)
x_test = sequence.pad_sequences(x_test, maxlen=input_length)

De tokenizer gebruikt nu zowel train als test teksten. Ik heb geen maximaal aantal woorden meer opgegeven en de 'moeilijke ombouw stappen zijn eruit:

x_train = x_train.astype(str, errors='ignore').values.tolist()
x_train = [''.join(x) for x in x_train]

De loss lijkt nu in ieder geval te verbeteren. Helaas de validation loss nog niet. Die wordt vooralsnog alleen maar slechter:

1443899/1443899 [==============================] - 1033s 715us/step - loss: 0.1502 - val_loss: 0.1394

Epoch 00001: val_loss improved from inf to 0.13939, saving model to model-best.h5
Epoch 2/20
1443899/1443899 [==============================] - 1019s 706us/step - loss: 0.1275 - val_loss: 0.1397

Epoch 00002: val_loss did not improve from 0.13939
Epoch 3/20
1443899/1443899 [==============================] - 1031s 714us/step - loss: 0.1092 - val_loss: 0.1516

Epoch 00003: val_loss did not improve from 0.13939
Epoch 4/20
 533050/1443899 [==========>...................] - ETA: 10:33 - loss: 0.0847

Maar ... we zijn nog maar bij de 4e epoch. Wie weet ... Het duurt nu wel lang: 1030 sec per epoch!





1443899/1443899 [==============================] - 1033s 715us/step - loss: 0.1502 - val_loss: 0.1394

Epoch 00001: val_loss improved from inf to 0.13939, saving model to model-best.h5
Epoch 2/20
1443899/1443899 [==============================] - 1019s 706us/step - loss: 0.1275 - val_loss: 0.1397

Epoch 00002: val_loss did not improve from 0.13939
Epoch 3/20
1443899/1443899 [==============================] - 1031s 714us/step - loss: 0.1092 - val_loss: 0.1516

Epoch 00003: val_loss did not improve from 0.13939
Epoch 4/20
1443899/1443899 [==============================] - 1029s 712us/step - loss: 0.0900 - val_loss: 0.1696

Epoch 00004: val_loss did not improve from 0.13939
Epoch 5/20
1443899/1443899 [==============================] - 1015s 703us/step - loss: 0.0725 - val_loss: 0.1871

Epoch 00005: val_loss did not improve from 0.13939
Epoch 6/20
1443899/1443899 [==============================] - 1006s 697us/step - loss: 0.0574 - val_loss: 0.2166

Epoch 00006: val_loss did not improve from 0.13939
Epoch 00006: early stopping

Jigsaw Unintended Bi

as in Toxicity Classification

Detect toxicity across a diverse range of conversations

Jigsaw Unintended Bias in Toxicity Classification

Detect toxicity across a diverse range of conversations