CNTK - Set di dati esauriti

In questo capitolo verrà spiegato come misurare le prestazioni dei set di dati esauriti.

Nelle sezioni precedenti, abbiamo discusso di vari metodi per convalidare le prestazioni del nostro NN, ma i metodi che abbiamo discusso sono quelli che si occupano dei set di dati che si adattano alla memoria.

Qui, sorge la domanda sui set di dati esauriti, perché nello scenario di produzione, abbiamo bisogno di molti dati per l'addestramento NN. In questa sezione, discuteremo come misurare le prestazioni quando si lavora con sorgenti minibatch e loop minibatch manuale.

Fonti di minibatch

Mentre lavoriamo con set di dati fuori memoria, cioè sorgenti minibatch, abbiamo bisogno di una configurazione leggermente diversa per la perdita, oltre che della metrica, rispetto alla configurazione che abbiamo usato mentre lavoravamo con set di dati piccoli, cioè set di dati in memoria. Per prima cosa, vedremo come impostare un modo per fornire dati al trainer del modello NN.

Di seguito sono riportati i passaggi di implementazione -

Step 1 - Primo, da cntk.Il modulo io importa i componenti per creare il sorgente minibatch come segue:

from cntk.io import StreamDef, StreamDefs, MinibatchSource, CTFDeserializer,
 INFINITY_REPEAT

Step 2 - Successivamente, crea una nuova funzione denominata say create_datasource. Questa funzione avrà due parametri, ovvero nome file e limite, con un valore predefinito diINFINITELY_REPEAT.

def create_datasource(filename, limit =INFINITELY_REPEAT)

Step 3 - Ora, all'interno della funzione, utilizzando StreamDefclass crea una definizione di flusso per le etichette che legge dal campo delle etichette che ha tre caratteristiche. Dobbiamo anche impostareis_sparse per False come segue -

labels_stream = StreamDef(field=’labels’, shape=3, is_sparse=False)

Step 4 - Successivamente, crea per leggere le caratteristiche archiviate dal file di input, crea un'altra istanza di StreamDef come segue.

feature_stream = StreamDef(field=’features’, shape=4, is_sparse=False)

Step 5 - Ora, inizializza il file CTFDeserializerclasse di istanza. Specificare il nome del file e gli stream che dobbiamo deserializzare come segue:

deserializer = CTFDeserializer(filename, StreamDefs(labels=
label_stream, features=features_stream)

Step 6 - Successivamente, dobbiamo creare un'istanza di minisourceBatch utilizzando il deserializzatore come segue -

Minibatch_source = MinibatchSource(deserializer, randomize=True, max_sweeps=limit)
return minibatch_source

Step 7- Infine, dobbiamo fornire formazione e fonte di test, che abbiamo creato anche nelle sezioni precedenti. Stiamo usando il set di dati del fiore di iris.

training_source = create_datasource(‘Iris_train.ctf’)
test_source = create_datasource(‘Iris_test.ctf’, limit=1)

Una volta creato MinibatchSourceAd esempio, dobbiamo addestrarlo. Possiamo usare la stessa logica di addestramento usata quando lavoravamo con piccoli set di dati in memoria. Qui useremoMinibatchSource esempio, come input per il metodo train sulla funzione di perdita come segue:

Di seguito sono riportati i passaggi di implementazione -

Step 1 - Per registrare l'output della sessione di allenamento, importare prima il file ProgressPrinter a partire dal cntk.logging modulo come segue -

from cntk.logging import ProgressPrinter

Step 2 - Successivamente, per impostare la sessione di formazione, importa il file trainer e training_session a partire dal cntk.train modulo come segue -

from cntk.train import Trainer, training_session

Step 3 - Ora, dobbiamo definire un insieme di costanti come minibatch_size, samples_per_epoch e num_epochs come segue -

minbatch_size = 16
samples_per_epoch = 150
num_epochs = 30
max_samples = samples_per_epoch * num_epochs

Step 4 - Successivamente, per sapere come leggere i dati durante l'addestramento in CNTK, dobbiamo definire una mappatura tra la variabile di input per la rete e gli stream nella sorgente del minibatch.

input_map = {
   features: training_source.streams.features,
   labels: training_source.streams.labels
}

Step 5 - Accanto a registrare l'output del processo di addestramento, inizializza il file progress_printer variabile con una nuova ProgressPrinteresempio. Inoltre, inizializza il filetrainer e fornirgli il modello come segue -

progress_writer = ProgressPrinter(0)
trainer: training_source.streams.labels

Step 6 - Infine, per avviare il processo di formazione, dobbiamo richiamare il file training_session funzionare come segue:

session = training_session(trainer,
   mb_source=training_source,
   mb_size=minibatch_size,
   model_inputs_to_streams=input_map,
   max_samples=max_samples,
   test_config=test_config)
session.train()

Dopo aver addestrato il modello, possiamo aggiungere la convalida a questa configurazione utilizzando un file TestConfig oggetto e assegnarlo al file test_config argomento della parola chiave del train_session funzione.

Di seguito sono riportati i passaggi di implementazione -

Step 1 - Per prima cosa, dobbiamo importare il file TestConfig class dal modulo cntk.train come segue -

from cntk.train import TestConfig

Step 2 - Ora, dobbiamo creare una nuova istanza di TestConfig con il test_source come input -

Test_config = TestConfig(test_source)

Esempio completo

from cntk.io import StreamDef, StreamDefs, MinibatchSource, CTFDeserializer, INFINITY_REPEAT
def create_datasource(filename, limit =INFINITELY_REPEAT)
labels_stream = StreamDef(field=’labels’, shape=3, is_sparse=False)
feature_stream = StreamDef(field=’features’, shape=4, is_sparse=False)
deserializer = CTFDeserializer(filename, StreamDefs(labels=label_stream, features=features_stream)
Minibatch_source = MinibatchSource(deserializer, randomize=True, max_sweeps=limit)
return minibatch_source
training_source = create_datasource(‘Iris_train.ctf’)
test_source = create_datasource(‘Iris_test.ctf’, limit=1)
from cntk.logging import ProgressPrinter
from cntk.train import Trainer, training_session
minbatch_size = 16
samples_per_epoch = 150
num_epochs = 30
max_samples = samples_per_epoch * num_epochs
input_map = {
   features:   training_source.streams.features,
   labels: training_source.streams.labels
 }
progress_writer = ProgressPrinter(0)
trainer: training_source.streams.labels
session = training_session(trainer,
   mb_source=training_source,
   mb_size=minibatch_size,
   model_inputs_to_streams=input_map,
   max_samples=max_samples,
   test_config=test_config)
session.train()
from cntk.train import TestConfig
Test_config = TestConfig(test_source)

Produzione

-------------------------------------------------------------------
average   since   average   since  examples
loss      last    metric    last
------------------------------------------------------
Learning rate per minibatch: 0.1
1.57      1.57     0.214    0.214   16
1.38      1.28     0.264    0.289   48
[………]
Finished Evaluation [1]: Minibatch[1-1]:metric = 69.65*30;

Minibatch manuale loop

Come si vede sopra, è facile misurare le prestazioni del nostro modello NN durante e dopo l'allenamento, utilizzando le metriche durante l'addestramento con API regolari in CNTK. Ma, d'altra parte, le cose non saranno così facili mentre si lavora con un ciclo minibatch manuale.

Qui, stiamo usando il modello fornito di seguito con 4 input e 3 output dal set di dati Iris Flower, creato anche nelle sezioni precedenti

from cntk import default_options, input_variable
from cntk.layers import Dense, Sequential
from cntk.ops import log_softmax, relu, sigmoid
from cntk.learners import sgd
model = Sequential([
   Dense(4, activation=sigmoid),
   Dense(3, activation=log_softmax)
])
features = input_variable(4)
labels = input_variable(3)
z = model(features)

Successivamente, la perdita per il modello è definita come la combinazione della funzione di perdita di entropia incrociata e la metrica di misura F come utilizzata nelle sezioni precedenti. Useremo il filecriterion_factory utility, per crearlo come oggetto funzione CNTK come mostrato di seguito -

import cntk
from cntk.losses import cross_entropy_with_softmax, fmeasure
@cntk.Function
def criterion_factory(outputs, targets):
   loss = cross_entropy_with_softmax(outputs, targets)
   metric = fmeasure(outputs, targets, beta=1)
   return loss, metric
loss = criterion_factory(z, labels)
learner = sgd(z.parameters, 0.1)
label_mapping = {
   'Iris-setosa': 0,
   'Iris-versicolor': 1,
   'Iris-virginica': 2
}

Ora, poiché abbiamo definito la funzione di perdita, vedremo come possiamo usarla nel trainer, per impostare una sessione di allenamento manuale.

Di seguito sono riportati i passaggi di implementazione:

Step 1 - Per prima cosa, dobbiamo importare i pacchetti richiesti come numpy e pandas per caricare e preelaborare i dati.

import pandas as pd
import numpy as np

Step 2 - Successivamente, per registrare le informazioni durante l'allenamento, importare il file ProgressPrinter class come segue -

from cntk.logging import ProgressPrinter

Step 3 - Quindi, dobbiamo importare il modulo trainer dal modulo cntk.train come segue -

from cntk.train import Trainer

Step 4 - Successivamente, crea una nuova istanza di ProgressPrinter come segue -

progress_writer = ProgressPrinter(0)

Step 5 - Ora, dobbiamo inizializzare il trainer con i parametri la perdita, lo studente e il progress_writer come segue -

trainer = Trainer(z, loss, learner, progress_writer)

Step 6- Successivamente, per addestrare il modello, creeremo un ciclo che itererà sul set di dati trenta volte. Questo sarà il ciclo di allenamento esterno.

for _ in range(0,30):

Step 7- Ora, dobbiamo caricare i dati dal disco usando i panda. Quindi, per caricare il set di dati inmini-batches, impostare il chunksize argomento della parola chiave a 16.

input_data = pd.read_csv('iris.csv',
names=['sepal_length', 'sepal_width','petal_length','petal_width', 'species'],
index_col=False, chunksize=16)

Step 8 - Ora, crea un ciclo di addestramento interno per iterare su ciascuno dei file mini-batches.

for df_batch in input_data:

Step 9 - Ora all'interno di questo ciclo, leggi le prime quattro colonne usando il iloc indicizzatore, come il features da cui allenarsi e convertirli in float32 -

feature_values = df_batch.iloc[:,:4].values
feature_values = feature_values.astype(np.float32)

Step 10 - Ora, leggi l'ultima colonna come le etichette da cui allenarti, come segue:

label_values = df_batch.iloc[:,-1]

Step 11 - Successivamente, useremo vettori one-hot per convertire le stringhe dell'etichetta nella loro presentazione numerica come segue -

label_values = label_values.map(lambda x: label_mapping[x])

Step 12- Dopodiché, prendi la presentazione numerica delle etichette. Quindi, convertili in un array numpy, quindi è più facile lavorare con loro come segue:

label_values = label_values.values

Step 13 - Ora, dobbiamo creare un nuovo array numpy che abbia lo stesso numero di righe dei valori dell'etichetta che abbiamo convertito.

encoded_labels = np.zeros((label_values.shape[0], 3))

Step 14 - Ora, per creare etichette con codifica singola, seleziona le colonne in base ai valori delle etichette numeriche.

encoded_labels[np.arange(label_values.shape[0]), label_values] = 1.

Step 15 - Infine, dobbiamo invocare il file train_minibatch metodo sul trainer e fornire le caratteristiche e le etichette elaborate per il minibatch.

trainer.train_minibatch({features: feature_values, labels: encoded_labels})

Esempio completo

from cntk import default_options, input_variable
from cntk.layers import Dense, Sequential
from cntk.ops import log_softmax, relu, sigmoid
from cntk.learners import sgd
model = Sequential([
   Dense(4, activation=sigmoid),
   Dense(3, activation=log_softmax)
])
features = input_variable(4)
labels = input_variable(3)
z = model(features)
import cntk
from cntk.losses import cross_entropy_with_softmax, fmeasure
@cntk.Function
def criterion_factory(outputs, targets):
   loss = cross_entropy_with_softmax(outputs, targets)
   metric = fmeasure(outputs, targets, beta=1)
   return loss, metric
loss = criterion_factory(z, labels)
learner = sgd(z.parameters, 0.1)
label_mapping = {
   'Iris-setosa': 0,
   'Iris-versicolor': 1,
   'Iris-virginica': 2
}
import pandas as pd
import numpy as np
from cntk.logging import ProgressPrinter
from cntk.train import Trainer
progress_writer = ProgressPrinter(0)
trainer = Trainer(z, loss, learner, progress_writer)
for _ in range(0,30):
   input_data = pd.read_csv('iris.csv',
      names=['sepal_length', 'sepal_width','petal_length','petal_width', 'species'],
      index_col=False, chunksize=16)
for df_batch in input_data:
   feature_values = df_batch.iloc[:,:4].values
   feature_values = feature_values.astype(np.float32)
   label_values = df_batch.iloc[:,-1]
label_values = label_values.map(lambda x: label_mapping[x])
label_values = label_values.values
   encoded_labels = np.zeros((label_values.shape[0], 3))
   encoded_labels[np.arange(label_values.shape[0]), 
label_values] = 1.
   trainer.train_minibatch({features: feature_values, labels: encoded_labels})

Produzione

-------------------------------------------------------------------
average    since    average   since  examples
loss       last      metric   last
------------------------------------------------------
Learning rate per minibatch: 0.1
1.45       1.45     -0.189    -0.189   16
1.24       1.13     -0.0382    0.0371  48
[………]

Nell'output sopra, abbiamo ottenuto sia l'output per la perdita che la metrica durante l'allenamento. È perché abbiamo combinato una metrica e una perdita in un oggetto funzione e abbiamo utilizzato una stampante di avanzamento nella configurazione del trainer.

Ora, per valutare le prestazioni del modello, dobbiamo eseguire lo stesso compito dell'addestramento del modello, ma questa volta dobbiamo usare un Evaluatoristanza per testare il modello. È mostrato nel seguente codice Python -

from cntk import Evaluator
evaluator = Evaluator(loss.outputs[1], [progress_writer])
input_data = pd.read_csv('iris.csv',
   names=['sepal_length', 'sepal_width','petal_length','petal_width', 'species'],
index_col=False, chunksize=16)
for df_batch in input_data:
   feature_values = df_batch.iloc[:,:4].values
   feature_values = feature_values.astype(np.float32)
   label_values = df_batch.iloc[:,-1]
   label_values = label_values.map(lambda x: label_mapping[x])
   label_values = label_values.values
   encoded_labels = np.zeros((label_values.shape[0], 3))
   encoded_labels[np.arange(label_values.shape[0]), label_values] = 1.
   evaluator.test_minibatch({ features: feature_values, labels:
      encoded_labels})
evaluator.summarize_test_progress()

Ora, otterremo un output simile al seguente -

Produzione

Finished Evaluation [1]: Minibatch[1-11]:metric = 74.62*143;