Når man designer arkitekturen til kunstigt neurale netværk, findes der en række parametre, der kan tunes. Det er faktisk en kunst i sig selv at finde den rigtige kombination af disse parametre for at opnå den højeste nøjagtighed og det laveste loss. I dette blogindlæg tester vi brugen af Talos til hyperparameter optimering af et neuralt netværk.

Loss og nøjagtigheds diagram

Ligesom vi har GridSearchCV til hyperparameteroptimering inden for scikit-learn algoritmer som Decision Trees / Random Forest og Support Vector Machine, kan Talos anvendes på Keras-modeller. Talos fungerer på samme måde som GridSearchCV ved at teste alle mulige kombinationer af de parametre, du har introduceret, og vælger den bedste model, baseret på hvilken parameter, du har bedt den om enten at optimere eller reducere.

Hvad er Talos?

Talos blev udgivet den 11. maj 2018 og er siden blevet opgraderet syv gange. Det fungerer for Python 2 og Python 3 og følger en POD (Prepare, Optimize, Deploy) arbejdsgang for at skabe en fleksibel og effektiv rørledning med avancerede forudsigelsesresultater. Når du kører koden med Talos i scan-kommandoen, testes alle mulige kombinationer i et eksperiment. Den bedste model gemmes derefter og kan anvendes, ligesom hvis du lavede et neuralt netværk ved hjælp af Keras.

Designe et Neuralt Netværk med Talos

Vi bruger kreditkortsvindel datasættet for dette eksperiment.
Vi dropper features: tid og beløb, og definerer X og y, ligesom vi gjorde i forrige blogindlæg. Vi opdeler derefter vores datasæt i træn, valider og test og bruger SMOTE-oversamplingsstrategi til at løse problemet med ubalanceret datasæt.

Nu begynder vi at lege med vores neurale netværksarkitektur. Vi definerer alle parametre, som vi ønsker, at vores model skal teste i følgende kode:

Definer parametere
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
from keras.activations import relu, elu

p = {'activation1':[relu, elu],
     'activation2':[relu, elu],
     'optimizer': ['Adam', "RMSprop"],
     'losses': ['logcosh', keras.losses.binary_crossentropy],
     'first_hidden_layer': [10, 8, 6],
     'second_hidden_layer': [2, 4, 6],
     'batch_size': [100, 1000, 10000],
     'epochs': [10, 15]}

Vi ønsker at teste, om relu eller elu er de bedste aktiveringsfunktioner for de skjulte lag, og test Adam og RMSprop som optimizers. I det originale blogindlæg brugte vi en tensorflow-optimizer. Talos understøtter imidlertid ikke denne aktiveringsfunktion, da den stammer fra Tensorflow og ikke Keras. Vi ønsker også at teste, om logcosh eller binary_crossentropy er de bedste loss funktioner. Til arkitekturen ønsker vi at teste, om det første skjulte lag skal have 10, 8 eller 6 neuroner, og det andet skjulte lag skal have 2, 4 eller 6 neuroner. Hvis vi ønskede at teste, hvor mange skjulte lag vores neurale netværksarkitektur skulle have, kan vi designe en anden parameter til test af dette. For at kunne køre eksperimentet bliver vi imidlertid nødt til at tilføje testen for skjulte lag i en parameterordbog for sig selv (se Talos)

Vi tester desuden størrelsen på batches og antallet af epoker for at se, hvilken model der er bedst.

Til test designer vi vores neurale netværksarkitektur, næsten på samme måde som når vi designer et neuralt netværk ved hjælp af Keras, bortset fra at vi bruger params til at kalde vores parametre defineret ovenfor:

Design det neurale netværk arkitektur
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.activations import sigmoid
from talos import early_stopper

def fraud_model(X_train, y_train, x_val, y_val, params):
    model = Sequential()
    model.add(Dense(params['first_hidden_layer'], 
                    input_shape=(29,), 
                    activation=params['activation1'], 
                    use_bias=True))
    model.add(Dropout(0.2))
    model.add(Dense(params['second_hidden_layer'], 
                    activation=params['activation2'], 
                    use_bias=True))
    model.add(Dropout(0.1))
    model.add(Dense(1, activation=sigmoid))

    model.compile(optimizer=params['optimizer'], 
                  loss=params['losses'], 
                  metrics=[keras.metrics.binary_accuracy])
    history = model.fit(X_train_resampled, 
                    y_train_resampled,
                    batch_size=params['batch_size'],
                    epochs=params['epochs'],
                    verbose=1,
                    validation_data=[X_val_resampled, y_val_resampled],
                    callbacks=[early_stopper(epochs=params['epochs'], 
                                                    mode='moderate', 
                                                    monitor='val_loss')])
    return history, model

Ved hjælp af kommandoen Scan begynder vi at konfigurere eksperimentet

Brug Scan kommandoen
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from talos import Scan

h = Scan(X_train_resampled, 
         y_train_resampled, 
         model=fraud_model, 
         params=p, 
         grid_downsample=0.1,
         print_params=True, 
         dataset_name="creditcardfraud", 
         experiment_no='1', 
         reduction_metric="val_loss", 
         reduce_loss=True)

Når vi kører eksperimentet, kan vi bruge Early Stopper eller Live-kommandoen som Callbacks.
Live gør det muligt for os at følge nøjagtighedsresultatet og tabet af hver epoke ved hjælp af et visualiseringspanel. Det gør det let at se præstationern for hver kombination. Outputet ligner det billede, der er visualiseret ovenfor.
Når vi kører scanningskommandoen, har vi i alt 86 eksperimenter baseret på alle ovenstående kombinationer.

Det næste trin er at bruge kommandoen Reporting til at evaluere eksperimenterne. Reporting gemmer en CSV-fil, hvor hvert eksperiment gemmes med dets resultater. I denne fil kan du se runder_epoker, val_loss, val_accuracy, train loss, testnøjagtighed, aktiveringsfunktion og antallet af neuroner til første og andet skjult lag, optimerings- og loss funktionen, batchstørrelse og antal epoker.
Ved at udskrive best_params til val_loss visualiseres de eksperimenter med det laveste loss. I vores tilfælde giver kombinationen nedenunder en trænings loss på 0,0329 og en træningsnøjagtighed på 92%.

  • Neuroner i første skjulte lag: 10
  • Neuroner i andet skjulte lag: 2
  • Aktiveringsfunktion første skjulte lag: elu
  • Aktiveringsfunktion andet skjulte lag: elu
  • Optimizer: Adam
  • Loss funktion: Logcosh
  • Epoker: 15
  • Batch størrelse: 10000

Vi er nu klar til at evaluere modellen. Vi ønsker at evaluere den model, der har den laveste val_loss, defineret af den metriske parameter.

Evaluate
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
from talos import Evaluate

e = ta.Evaluate(h)
evaluation = e.evaluate(X_test, 
                        y_test, 
                        model_id=None, 
                        folds=folds, 
                        shuffle=True, 
                        metric='val_loss', 
                        asc=True)

Hvis vi finder eksperimentet tilfredsstillende, kan vi nu Deploy modellen.

Deploy
1
2
3
from talos import Deploy

model = Deploy(h, "creditcardfraud_1", metric="val_loss", asc=True)

Deploy-kommando forbereder en zip-fil, der kan overføres til et andet miljø eller system. zip-filerne giver os oplysninger om eksperimentet i “creditcardfraud_1_results.csv”, modellens vægte, gemt som “creditcardfraud_1_model.h5, og modellen i json-format:” creditcardfraud_1_model.json ”.

Når vi har brugt kommandoen Deploy, kan vi få adgang til modellen og bruge den til produktion ved hjælp af kommandoen Restore.

Restore
1
2
3
from talos import Restore

model = Restore('creditcardfraud_1.zip')

Konklusion

Talos er en nyttig pakke til at løse komplekse neurale netværksmodeller og beslutte den rigtige kombination af parametrene. Den bedste model kan findes ved at køre koden én gang i stedet for at køre koden efter hver ændring af en enkelt parameter. Dette sparer os tid og gør det lettere for os at finde de bedste kombinationer med de laveste tabsværdier. Når man for eksempel laver en LSTM-model (Long Short-Term Memory), findes der en større mængde parametre, som man kan tunes, og i dette tilfælde kan det være nyttigt at bruge Talos til at finde de bedste værdier, den rigtige mængde af neuroner, og antallet af LSTM-lag.

Vi skal dog sørge for at huske på, at hvis vi har at gøre med ubalanceret datasæt, er nøjagtighedsresultater og loss værdier ikke nok. Det kan være en god ide at bruge ROC AUC-score som en tuning metric ved træning for at sikre, at vores model ikke diskriminerer den mindre gruppe (i vores tilfælde de svigagtige transaktioner). Endelig giver rapportfilen en betydelig indsigt i, hvor godt hver parameterkombination fungerer og er nyttig til dokumentation.

// Maria Hvid, Machine Learning Engineer @ neurospace