CNTK - Set di dati in memoria e di grandi dimensioni

In questo capitolo, impareremo come lavorare con i set di dati in memoria e di grandi dimensioni in CNTK.

Formazione con piccoli set di dati in memoria

Quando parliamo di inserire dati nel trainer CNTK, ci possono essere molti modi, ma dipenderà dalla dimensione del set di dati e dal formato dei dati. I set di dati possono essere piccoli in memoria o grandi set di dati.

In questa sezione, lavoreremo con i set di dati in memoria. Per questo, utilizzeremo i seguenti due framework:

  • Numpy
  • Pandas

Usare gli array Numpy

Qui, lavoreremo con un set di dati generato casualmente basato su numpy in CNTK. In questo esempio, simuleremo i dati per un problema di classificazione binaria. Supponiamo di avere una serie di osservazioni con 4 caratteristiche e di voler prevedere due possibili etichette con il nostro modello di deep learning.

Esempio di implementazione

Per questo, prima dobbiamo generare un insieme di etichette contenente una rappresentazione vettoriale a caldo delle etichette, che vogliamo prevedere. Può essere fatto con l'aiuto dei seguenti passaggi:

Step 1 - Importa il file numpy pacchetto come segue -

import numpy as np
num_samples = 20000

Step 2 - Successivamente, genera una mappatura dell'etichetta utilizzando np.eye funzionare come segue:

label_mapping = np.eye(2)

Step 3 - Ora usando np.random.choice funzione, raccogliere i 20000 campioni casuali come segue:

y = label_mapping[np.random.choice(2,num_samples)].astype(np.float32)

Step 4 - Ora finalmente usando la funzione np.random.random, genera un array di valori in virgola mobile casuali come segue -

x = np.random.random(size=(num_samples, 4)).astype(np.float32)

Una volta generato un array di valori a virgola mobile casuali, dobbiamo convertirli in numeri a virgola mobile a 32 bit in modo che possa essere abbinato al formato previsto da CNTK. Seguiamo i passaggi seguenti per farlo:

Step 5 - Importa le funzioni del livello Denso e Sequenziale dal modulo cntk.layers come segue:

from cntk.layers import Dense, Sequential

Step 6- Ora, dobbiamo importare la funzione di attivazione per i livelli nella rete. Importiamo il filesigmoid come funzione di attivazione -

from cntk import input_variable, default_options
from cntk.ops import sigmoid

Step 7- Ora, dobbiamo importare la funzione di perdita per addestrare la rete. Cerchiamo di importarebinary_cross_entropy come funzione di perdita -

from cntk.losses import binary_cross_entropy

Step 8- Successivamente, dobbiamo definire le opzioni predefinite per la rete. Qui forniremo il filesigmoidfunzione di attivazione come impostazione predefinita. Inoltre, crea il modello utilizzando la funzione di livello sequenziale come segue:

with default_options(activation=sigmoid):
model = Sequential([Dense(6),Dense(2)])

Step 9 - Successivamente, inizializza un file input_variable con 4 funzioni di input che fungono da input per la rete.

features = input_variable(4)

Step 10 - Ora, per completarlo, dobbiamo collegare le caratteristiche variabili a NN.

z = model(features)

Quindi, ora abbiamo un NN, con l'aiuto dei seguenti passaggi, addestriamolo utilizzando il set di dati in memoria -

Step 11 - Per addestrare questo NN, prima dobbiamo importare lo studente da cntk.learnersmodulo. Importeremosgd studente come segue -

from cntk.learners import sgd

Step 12 - Insieme a questo importa il file ProgressPrinter a partire dal cntk.logging modulo pure.

from cntk.logging import ProgressPrinter
progress_writer = ProgressPrinter(0)

Step 13 - Successivamente, definire una nuova variabile di input per le etichette come segue:

labels = input_variable(2)

Step 14 - Per addestrare il modello NN, quindi, dobbiamo definire una perdita utilizzando il binary_cross_entropyfunzione. Inoltre, fornire il modello ze la variabile delle etichette.

loss = binary_cross_entropy(z, labels)

Step 15 - Successivamente, inizializza il file sgd studente come segue -

learner = sgd(z.parameters, lr=0.1)

Step 16- Infine, chiama il metodo train sulla funzione di perdita. Inoltre, fornisci i dati di input, il filesgd learner e il progress_printer.−

training_summary=loss.train((x,y),parameter_learners=[learner],callbacks=[progress_writer])

Esempio di implementazione completo

import numpy as np
num_samples = 20000
label_mapping = np.eye(2)
y = label_mapping[np.random.choice(2,num_samples)].astype(np.float32)
x = np.random.random(size=(num_samples, 4)).astype(np.float32)
from cntk.layers import Dense, Sequential
from cntk import input_variable, default_options
from cntk.ops import sigmoid
from cntk.losses import binary_cross_entropy
with default_options(activation=sigmoid):
   model = Sequential([Dense(6),Dense(2)])
features = input_variable(4)
z = model(features)
from cntk.learners import sgd
from cntk.logging import ProgressPrinter
progress_writer = ProgressPrinter(0)
labels = input_variable(2)
loss = binary_cross_entropy(z, labels)
learner = sgd(z.parameters, lr=0.1)
training_summary=loss.train((x,y),parameter_learners=[learner],callbacks=[progress_writer])

Produzione

Build info:
     Built time: *** ** **** 21:40:10
     Last modified date: *** *** ** 21:08:46 2019
     Build type: Release
     Build target: CPU-only
     With ASGD: yes
     Math lib: mkl
     Build Branch: HEAD
     Build SHA1:ae9c9c7c5f9e6072cc9c94c254f816dbdc1c5be6 (modified)
     MPI distribution: Microsoft MPI
     MPI version: 7.0.12437.6
-------------------------------------------------------------------
average   since   average   since examples
loss      last    metric    last
------------------------------------------------------
Learning rate per minibatch: 0.1
1.52      1.52      0         0     32
1.51      1.51      0         0     96
1.48      1.46      0         0    224
1.45      1.42      0         0    480
1.42       1.4      0         0    992
1.41      1.39      0         0   2016
1.4       1.39      0         0   4064
1.39      1.39      0         0   8160
1.39      1.39      0         0  16352

Utilizzo di Pandas DataFrames

Gli array Numpy sono molto limitati in ciò che possono contenere e rappresentano uno dei modi più semplici per archiviare i dati. Ad esempio, un singolo array n-dimensionale può contenere dati di un singolo tipo di dati. D'altra parte, per molti casi reali abbiamo bisogno di una libreria in grado di gestire più di un tipo di dati in un singolo set di dati.

Una delle librerie Python chiamata Pandas semplifica il lavoro con questo tipo di set di dati. Introduce il concetto di un DataFrame (DF) e ci consente di caricare set di dati da disco memorizzati in vari formati come DF. Ad esempio, possiamo leggere DF archiviati come CSV, JSON, Excel, ecc.

Puoi imparare la libreria Python Pandas in modo più dettagliato su https://www.tutorialspoint.com/python_pandas/index.htm.

Esempio di implementazione

In questo esempio, useremo l'esempio della classificazione di tre possibili specie di fiori di iris in base a quattro proprietà. Abbiamo creato questo modello di deep learning anche nelle sezioni precedenti. Il modello è il seguente:

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

Il modello sopra contiene un livello nascosto e un livello di output con tre neuroni per abbinare il numero di classi che possiamo prevedere.

Successivamente, useremo il train metodo e lossfunzione per addestrare la rete. Per questo, prima dobbiamo caricare e preelaborare il set di dati iris, in modo che corrisponda al layout e al formato dati previsti per NN. Può essere fatto con l'aiuto dei seguenti passaggi:

Step 1 - Importa il file numpy e Pandas pacchetto come segue -

import numpy as np
import pandas as pd

Step 2 - Quindi, usa il file read_csv funzione per caricare il set di dati in memoria -

df_source = pd.read_csv(‘iris.csv’, names = [‘sepal_length’, ‘sepal_width’,
 ‘petal_length’, ‘petal_width’, ‘species’], index_col=False)

Step 3 - Ora, dobbiamo creare un dizionario che mapperà le etichette nel set di dati con la loro rappresentazione numerica corrispondente.

label_mapping = {‘Iris-Setosa’ : 0, ‘Iris-Versicolor’ : 1, ‘Iris-Virginica’ : 2}

Step 4 - Ora, usando iloc indicizzatore su DataFrame, seleziona le prime quattro colonne come segue:

x = df_source.iloc[:, :4].values

Step 5- Successivamente, dobbiamo selezionare le colonne delle specie come etichette per il set di dati. Può essere fatto come segue:

y = df_source[‘species’].values

Step 6 - Ora, dobbiamo mappare le etichette nel set di dati, cosa che può essere eseguita utilizzando label_mapping. Inoltre, usaone_hot codifica per convertirli in array di codifica one-hot.

y = np.array([one_hot(label_mapping[v], 3) for v in y])

Step 7 - Successivamente, per utilizzare le funzionalità e le etichette mappate con CNTK, dobbiamo convertirle entrambe in float -

x= x.astype(np.float32)
y= y.astype(np.float32)

Come sappiamo, le etichette vengono memorizzate nel set di dati come stringhe e CNTK non può funzionare con queste stringhe. Questo è il motivo, ha bisogno di vettori codificati a caldo che rappresentino le etichette. Per questo, possiamo definire una funzione sayone_hot come segue -

def one_hot(index, length):
result = np.zeros(length)
result[index] = index
return result

Ora, abbiamo l'array numpy nel formato corretto, con l'aiuto dei seguenti passaggi possiamo usarli per addestrare il nostro modello -

Step 8- Innanzitutto, dobbiamo importare la funzione di perdita per addestrare la rete. Cerchiamo di importarebinary_cross_entropy_with_softmax come funzione di perdita -

from cntk.losses import binary_cross_entropy_with_softmax

Step 9 - Per addestrare questo NN, dobbiamo anche importare lo studente da cntk.learnersmodulo. Importeremosgd studente come segue -

from cntk.learners import sgd

Step 10 - Insieme a questo importa il file ProgressPrinter a partire dal cntk.logging modulo pure.

from cntk.logging import ProgressPrinter
progress_writer = ProgressPrinter(0)

Step 11 - Successivamente, definire una nuova variabile di input per le etichette come segue:

labels = input_variable(3)

Step 12 - Per addestrare il modello NN, quindi, dobbiamo definire una perdita utilizzando il binary_cross_entropy_with_softmaxfunzione. Fornisci anche il modello ze la variabile delle etichette.

loss = binary_cross_entropy_with_softmax (z, labels)

Step 13 - Successivamente, inizializza il file sgd studente come segue -

learner = sgd(z.parameters, 0.1)

Step 14- Infine, chiama il metodo train sulla funzione di perdita. Inoltre, fornisci i dati di input, il filesgd learner e il progress_printer.

training_summary=loss.train((x,y),parameter_learners=[learner],callbacks=
[progress_writer],minibatch_size=16,max_epochs=5)

Esempio di implementazione completo

from cntk.layers import Dense, Sequential
from cntk import input_variable, default_options
from cntk.ops import sigmoid, log_softmax
from cntk.losses import binary_cross_entropy
model = Sequential([
Dense(4, activation=sigmoid),
Dense(3, activation=log_softmax)
])
features = input_variable(4)
z = model(features)
import numpy as np
import pandas as pd
df_source = pd.read_csv(‘iris.csv’, names = [‘sepal_length’, ‘sepal_width’, ‘petal_length’, ‘petal_width’, ‘species’], index_col=False)
label_mapping = {‘Iris-Setosa’ : 0, ‘Iris-Versicolor’ : 1, ‘Iris-Virginica’ : 2}
x = df_source.iloc[:, :4].values
y = df_source[‘species’].values
y = np.array([one_hot(label_mapping[v], 3) for v in y])
x= x.astype(np.float32)
y= y.astype(np.float32)
def one_hot(index, length):
result = np.zeros(length)
result[index] = index
return result
from cntk.losses import binary_cross_entropy_with_softmax
from cntk.learners import sgd
from cntk.logging import ProgressPrinter
progress_writer = ProgressPrinter(0)
labels = input_variable(3)
loss = binary_cross_entropy_with_softmax (z, labels)
learner = sgd(z.parameters, 0.1)
training_summary=loss.train((x,y),parameter_learners=[learner],callbacks=[progress_writer],minibatch_size=16,max_epochs=5)

Produzione

Build info:
     Built time: *** ** **** 21:40:10
     Last modified date: *** *** ** 21:08:46 2019
     Build type: Release
     Build target: CPU-only
     With ASGD: yes
     Math lib: mkl
     Build Branch: HEAD
     Build SHA1:ae9c9c7c5f9e6072cc9c94c254f816dbdc1c5be6 (modified)
     MPI distribution: Microsoft MPI
     MPI version: 7.0.12437.6
-------------------------------------------------------------------
average    since    average   since   examples
loss        last     metric   last
------------------------------------------------------
Learning rate per minibatch: 0.1
1.1         1.1        0       0      16
0.835     0.704        0       0      32
1.993      1.11        0       0      48
1.14       1.14        0       0     112
[………]

Formazione con set di dati di grandi dimensioni

Nella sezione precedente, abbiamo lavorato con piccoli set di dati in memoria utilizzando Numpy e panda, ma non tutti i set di dati sono così piccoli. Specialmente i set di dati contenenti immagini, video, campioni sonori sono grandi.MinibatchSourceè un componente, in grado di caricare i dati in blocchi, fornito da CNTK per lavorare con set di dati così grandi. Alcune delle caratteristiche diMinibatchSource i componenti sono i seguenti:

  • MinibatchSource può impedire l'overfitting di NN randomizzando automaticamente i campioni letti dall'origine dati.

  • Ha una pipeline di trasformazione incorporata che può essere utilizzata per aumentare i dati.

  • Carica i dati su un thread in background separato dal processo di addestramento.

Nelle sezioni seguenti, esploreremo come utilizzare un'origine minibatch con dati esauriti per lavorare con set di dati di grandi dimensioni. Esploreremo anche come possiamo usarlo per nutrire per l'addestramento di un NN.

Creazione dell'istanza MinibatchSource

Nella sezione precedente, abbiamo utilizzato l'esempio del fiore di iris e lavorato con un piccolo set di dati in memoria utilizzando Pandas DataFrames. In questo caso, sostituiremo il codice che utilizza i dati di un DF panda conMinibatchSource. Innanzitutto, dobbiamo creare un'istanza diMinibatchSource con l'aiuto dei seguenti passaggi:

Esempio di implementazione

Step 1 - Primo, da cntk.io modulo importa i componenti per il minibatchsource come segue:

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

Step 2 - Ora, usando StreamDef class, crea una definizione di flusso per le etichette.

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

Step 3 - 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 4 - Ora, dobbiamo provvedere iris.ctf file come input e inizializza il file deserializer come segue -

deserializer = CTFDeserializer(‘iris.ctf’, StreamDefs(labels=
label_stream, features=features_stream)

Step 5 - Infine, dobbiamo creare un'istanza di minisourceBatch usando deserializer come segue -

Minibatch_source = MinibatchSource(deserializer, randomize=True)

Creazione di un'istanza MinibatchSource: esempio di implementazione completo

from cntk.io import StreamDef, StreamDefs, MinibatchSource, CTFDeserializer, INFINITY_REPEAT
labels_stream = StreamDef(field=’labels’, shape=3, is_sparse=False)
feature_stream = StreamDef(field=’features’, shape=4, is_sparse=False)
deserializer = CTFDeserializer(‘iris.ctf’, StreamDefs(labels=label_stream, features=features_stream)
Minibatch_source = MinibatchSource(deserializer, randomize=True)

Creazione del file MCTF

Come hai visto sopra, stiamo prendendo i dati dal file "iris.ctf". Ha il formato di file chiamato CNTK Text Format (CTF). È obbligatorio creare un file CTF per ottenere i dati perMinibatchSourceistanza che abbiamo creato sopra. Vediamo come possiamo creare un file CTF.

Esempio di implementazione

Step 1 - Innanzitutto, dobbiamo importare i pacchetti panda e numpy come segue -

import pandas as pd
import numpy as np

Step 2- Successivamente, dobbiamo caricare il nostro file di dati, cioè iris.csv in memoria. Quindi, conservalo nel filedf_source variabile.

df_source = pd.read_csv(‘iris.csv’, names = [‘sepal_length’, ‘sepal_width’, ‘petal_length’, ‘petal_width’, ‘species’], index_col=False)

Step 3 - Ora, usando ilocindicizzatore come caratteristiche, prendi il contenuto delle prime quattro colonne. Inoltre, utilizza i dati della colonna delle specie come segue:

features = df_source.iloc[: , :4].values
labels = df_source[‘species’].values

Step 4- Successivamente, dobbiamo creare una mappatura tra il nome dell'etichetta e la sua rappresentazione numerica. Può essere fatto creandolabel_mapping come segue -

label_mapping = {‘Iris-Setosa’ : 0, ‘Iris-Versicolor’ : 1, ‘Iris-Virginica’ : 2}

Step 5 - Ora, converti le etichette in un set di vettori con codifica one-hot come segue -

labels = [one_hot(label_mapping[v], 3) for v in labels]

Ora, come abbiamo fatto prima, crea una funzione di utilità chiamata one_hotper codificare le etichette. Può essere fatto come segue:

def one_hot(index, length):
result = np.zeros(length)
result[index] = 1
return result

Dato che abbiamo caricato e preelaborato i dati, è ora di salvarli su disco nel formato di file CTF. Possiamo farlo con l'aiuto del seguente codice Python -

With open(‘iris.ctf’, ‘w’) as output_file:
for index in range(0, feature.shape[0]):
feature_values = ‘ ‘.join([str(x) for x in np.nditer(features[index])])
label_values = ‘ ‘.join([str(x) for x in np.nditer(labels[index])])
output_file.write(‘features {} | labels {} \n’.format(feature_values, label_values))

Creazione di un file MCTF - Esempio di implementazione completo

import pandas as pd
import numpy as np
df_source = pd.read_csv(‘iris.csv’, names = [‘sepal_length’, ‘sepal_width’, ‘petal_length’, ‘petal_width’, ‘species’], index_col=False)
features = df_source.iloc[: , :4].values
labels = df_source[‘species’].values
label_mapping = {‘Iris-Setosa’ : 0, ‘Iris-Versicolor’ : 1, ‘Iris-Virginica’ : 2}
labels = [one_hot(label_mapping[v], 3) for v in labels]
def one_hot(index, length):
result = np.zeros(length)
result[index] = 1
return result
With open(‘iris.ctf’, ‘w’) as output_file:
for index in range(0, feature.shape[0]):
feature_values = ‘ ‘.join([str(x) for x in np.nditer(features[index])])
label_values = ‘ ‘.join([str(x) for x in np.nditer(labels[index])])
output_file.write(‘features {} | labels {} \n’.format(feature_values, label_values))

Alimentazione dei dati

Una volta creato MinibatchSource,Ad 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:

Esempio di implementazione

Step 1 - Per registrare l'output della sessione di formazione, importare prima ProgressPrinter da 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,

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

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

input_map = {
     features: minibatch.source.streams.features,
     labels: minibatch.source.streams.features
}

Step 5 - Successivamente, per registrare l'output del processo di addestramento, inizializzare il file progress_printer variabile con una nuova ProgressPrinter esempio come segue -

progress_writer = ProgressPrinter(0)

Step 6 - Infine, dobbiamo invocare il metodo train sulla perdita come segue -

train_history = loss.train(minibatch_source,
parameter_learners=[learner],
  model_inputs_to_streams=input_map,
callbacks=[progress_writer],
epoch_size=samples_per_epoch,
max_epochs=num_epochs)

Alimentazione dei dati - Esempio di implementazione completo

from cntk.logging import ProgressPrinter
from cntk.train import Trainer, training_session
minbatch_size = 16
samples_per_epoch = 150
num_epochs = 30
input_map = {
   features: minibatch.source.streams.features,
   labels: minibatch.source.streams.features
}
progress_writer = ProgressPrinter(0)
train_history = loss.train(minibatch_source,
parameter_learners=[learner],
model_inputs_to_streams=input_map,
callbacks=[progress_writer],
epoch_size=samples_per_epoch,
max_epochs=num_epochs)

Produzione

-------------------------------------------------------------------
average   since   average   since  examples
loss      last     metric   last
------------------------------------------------------
Learning rate per minibatch: 0.1
1.21      1.21      0        0       32
1.15      0.12      0        0       96
[………]