CNTK - Regressione della rete neurale

Il capitolo ti aiuterà a comprendere la regressione della rete neurale rispetto a CNTK.

introduzione

Come sappiamo, per prevedere un valore numerico da una o più variabili predittive, utilizziamo la regressione. Facciamo un esempio di previsione del valore mediano di una casa in una delle 100 città. Per fare ciò, abbiamo dati che includono:

  • Una statistica del crimine per ogni città.

  • L'età delle case in ogni città.

  • Una misura della distanza da ogni città a una posizione privilegiata.

  • Il rapporto studenti-insegnanti in ogni città.

  • Una statistica demografica razziale per ogni città.

  • Il valore mediano della casa in ogni città.

Sulla base di queste cinque variabili predittive, vorremmo prevedere il valore della casa mediana. E per questo possiamo creare un modello di regressione lineare sulla falsariga di -

Y = a0+a1(crime)+a2(house-age)+(a3)(distance)+(a4)(ratio)+(a5)(racial)

Nell'equazione sopra -

Y è un valore mediano previsto

a0 è una costante e

a1 fino a a5 sono tutte costanti associate ai cinque predittori discussi sopra.

Abbiamo anche un approccio alternativo per l'utilizzo di una rete neurale. Creerà un modello di previsione più accurato.

Qui creeremo un modello di regressione della rete neurale utilizzando CNTK.

Caricamento del set di dati

Per implementare la regressione della rete neurale utilizzando CNTK, utilizzeremo il set di dati dei valori delle case dell'area di Boston. Il set di dati può essere scaricato da UCI Machine Learning Repository, disponibile all'indirizzohttps://archive.ics.uci.edu/ml/machine-learning-databases/housing/. Questo set di dati ha un totale di 14 variabili e 506 istanze.

Tuttavia, per il nostro programma di implementazione utilizzeremo sei delle 14 variabili e 100 istanze. Su 6, 5 come predittori e uno come valore da prevedere. Da 100 casi, ne useremo 80 per la formazione e 20 per scopi di test. Il valore che vogliamo prevedere è il prezzo medio di una casa in una città. Vediamo i cinque predittori che useremo:

  • Crime per capita in the town - Ci aspetteremmo che valori più piccoli fossero associati a questo predittore.

  • Proportion of owner - unità occupate costruite prima del 1940 - Ci aspetteremmo che valori più piccoli fossero associati a questo predittore perché un valore maggiore significa una casa più vecchia.

  • Weighed distance of the town to five Boston employment centers.

  • Area school pupil-to-teacher ratio.

  • An indirect metric of the proportion of black residents in the town.

Preparazione di file di formazione e test

Come abbiamo fatto prima, prima dobbiamo convertire i dati grezzi in formato CNTK. Utilizzeremo i primi 80 elementi di dati a scopo di addestramento, quindi il formato CNTK delimitato da tabulazioni è il seguente:

|predictors 1.612820 96.90 3.76 21.00 248.31 |medval 13.50
|predictors 0.064170 68.20 3.36 19.20 396.90 |medval 18.90
|predictors 0.097440 61.40 3.38 19.20 377.56 |medval 20.00
. . .

I prossimi 20 elementi, anch'essi convertiti in formato CNTK, verranno utilizzati a scopo di test.

Costruire il modello di regressione

Per prima cosa, dobbiamo elaborare i file di dati in formato CNTK e per questo utilizzeremo la funzione di supporto denominata create_reader come segue -

def create_reader(path, input_dim, output_dim, rnd_order, sweeps):
x_strm = C.io.StreamDef(field='predictors', shape=input_dim, is_sparse=False)
y_strm = C.io.StreamDef(field='medval', shape=output_dim, is_sparse=False)
streams = C.io.StreamDefs(x_src=x_strm, y_src=y_strm)
deserial = C.io.CTFDeserializer(path, streams)
mb_src = C.io.MinibatchSource(deserial, randomize=rnd_order, max_sweeps=sweeps)
return mb_src

Successivamente, dobbiamo creare una funzione di supporto che accetti un oggetto mini-batch CNTK e calcoli una metrica di precisione personalizzata.

def mb_accuracy(mb, x_var, y_var, model, delta):
   num_correct = 0
   num_wrong = 0
   x_mat = mb[x_var].asarray()
   y_mat = mb[y_var].asarray()
for i in range(mb[x_var].shape[0]):
  v = model.eval(x_mat[i])
  y = y_mat[i]
if np.abs(v[0,0] – y[0,0]) < delta:
   num_correct += 1
else:
   num_wrong += 1
return (num_correct * 100.0)/(num_correct + num_wrong)

Ora, dobbiamo impostare gli argomenti dell'architettura per il nostro NN e fornire anche la posizione dei file di dati. Può essere fatto con l'aiuto del seguente codice python -

def main():
print("Using CNTK version = " + str(C.__version__) + "\n")
input_dim = 5
hidden_dim = 20
output_dim = 1
train_file = ".\\...\\" #provide the name of the training file(80 data items)
test_file = ".\\...\\" #provide the name of the test file(20 data items)

Ora, con l'aiuto della seguente riga di codice, il nostro programma creerà l'NN non addestrato -

X = C.ops.input_variable(input_dim, np.float32)
Y = C.ops.input_variable(output_dim, np.float32)
with C.layers.default_options(init=C.initializer.uniform(scale=0.01, seed=1)):
hLayer = C.layers.Dense(hidden_dim, activation=C.ops.tanh, name='hidLayer')(X)
oLayer = C.layers.Dense(output_dim, activation=None, name='outLayer')(hLayer)
model = C.ops.alias(oLayer)

Ora, una volta creato il modello doppio non addestrato, dobbiamo impostare un oggetto algoritmo Learner. Useremo SGD learner esquared_error funzione di perdita -

tr_loss = C.squared_error(model, Y)
max_iter = 3000
batch_size = 5
base_learn_rate = 0.02
sch=C.learning_parameter_schedule([base_learn_rate, base_learn_rate/2], minibatch_size=batch_size, epoch_size=int((max_iter*batch_size)/2))
learner = C.sgd(model.parameters, sch)
trainer = C.Trainer(model, (tr_loss), [learner])

Ora, una volta terminato con l'oggetto Algoritmo di apprendimento, dobbiamo creare una funzione di lettura per leggere i dati di addestramento -

rdr = create_reader(train_file, input_dim, output_dim, rnd_order=True, sweeps=C.io.INFINITELY_REPEAT)
boston_input_map = { X : rdr.streams.x_src, Y : rdr.streams.y_src }

Ora è il momento di addestrare il nostro modello NN -

for i in range(0, max_iter):
curr_batch = rdr.next_minibatch(batch_size, input_map=boston_input_map) trainer.train_minibatch(curr_batch)
if i % int(max_iter/10) == 0:
mcee = trainer.previous_minibatch_loss_average
acc = mb_accuracy(curr_batch, X, Y, model, delta=3.00)
print("batch %4d: mean squared error = %8.4f, accuracy = %5.2f%% " \ % (i, mcee, acc))

Una volta terminato l'addestramento, valutiamo il modello utilizzando elementi di dati di test:

print("\nEvaluating test data \n")
rdr = create_reader(test_file, input_dim, output_dim, rnd_order=False, sweeps=1)
boston_input_map = { X : rdr.streams.x_src, Y : rdr.streams.y_src }
num_test = 20
all_test = rdr.next_minibatch(num_test, input_map=boston_input_map)
acc = mb_accuracy(all_test, X, Y, model, delta=3.00)
print("Prediction accuracy = %0.2f%%" % acc)

Dopo aver valutato l'accuratezza del nostro modello NN addestrato, lo useremo per fare una previsione su dati invisibili -

np.set_printoptions(precision = 2, suppress=True)
unknown = np.array([[0.09, 50.00, 4.5, 17.00, 350.00], dtype=np.float32)
print("\nPredicting median home value for feature/predictor values: ")
print(unknown[0])
pred_prob = model.eval({X: unknown)
print("\nPredicted value is: ")
print(“$%0.2f (x1000)” %pred_value[0,0])

Modello di regressione completo

import numpy as np
import cntk as C
def create_reader(path, input_dim, output_dim, rnd_order, sweeps):
x_strm = C.io.StreamDef(field='predictors', shape=input_dim, is_sparse=False)
y_strm = C.io.StreamDef(field='medval', shape=output_dim, is_sparse=False)
streams = C.io.StreamDefs(x_src=x_strm, y_src=y_strm)
deserial = C.io.CTFDeserializer(path, streams)
mb_src = C.io.MinibatchSource(deserial, randomize=rnd_order, max_sweeps=sweeps)
return mb_src
def mb_accuracy(mb, x_var, y_var, model, delta):
num_correct = 0
num_wrong = 0
x_mat = mb[x_var].asarray()
y_mat = mb[y_var].asarray()
for i in range(mb[x_var].shape[0]):
   v = model.eval(x_mat[i])
   y = y_mat[i]
if np.abs(v[0,0] – y[0,0]) < delta:
   num_correct += 1
else:
   num_wrong += 1
return (num_correct * 100.0)/(num_correct + num_wrong)
def main():
print("Using CNTK version = " + str(C.__version__) + "\n")
input_dim = 5
hidden_dim = 20
output_dim = 1
train_file = ".\\...\\" #provide the name of the training file(80 data items)
test_file = ".\\...\\" #provide the name of the test file(20 data items)
X = C.ops.input_variable(input_dim, np.float32)
Y = C.ops.input_variable(output_dim, np.float32)
with C.layers.default_options(init=C.initializer.uniform(scale=0.01, seed=1)):
hLayer = C.layers.Dense(hidden_dim, activation=C.ops.tanh, name='hidLayer')(X)
oLayer = C.layers.Dense(output_dim, activation=None, name='outLayer')(hLayer)
model = C.ops.alias(oLayer)
tr_loss = C.squared_error(model, Y)
max_iter = 3000
batch_size = 5
base_learn_rate = 0.02
sch = C.learning_parameter_schedule([base_learn_rate, base_learn_rate/2], minibatch_size=batch_size, epoch_size=int((max_iter*batch_size)/2))
learner = C.sgd(model.parameters, sch)
trainer = C.Trainer(model, (tr_loss), [learner])
rdr = create_reader(train_file, input_dim, output_dim, rnd_order=True, sweeps=C.io.INFINITELY_REPEAT)
boston_input_map = { X : rdr.streams.x_src, Y : rdr.streams.y_src }
for i in range(0, max_iter):
curr_batch = rdr.next_minibatch(batch_size, input_map=boston_input_map) trainer.train_minibatch(curr_batch)
if i % int(max_iter/10) == 0:
   mcee = trainer.previous_minibatch_loss_average
   acc = mb_accuracy(curr_batch, X, Y, model, delta=3.00)
   print("batch %4d: mean squared error = %8.4f, accuracy = %5.2f%% " \ % (i, mcee, acc))
   print("\nEvaluating test data \n")
   rdr = create_reader(test_file, input_dim, output_dim, rnd_order=False, sweeps=1)
   boston_input_map = { X : rdr.streams.x_src, Y : rdr.streams.y_src }
   num_test = 20
all_test = rdr.next_minibatch(num_test, input_map=boston_input_map)
acc = mb_accuracy(all_test, X, Y, model, delta=3.00)
print("Prediction accuracy = %0.2f%%" % acc)
np.set_printoptions(precision = 2, suppress=True)
unknown = np.array([[0.09, 50.00, 4.5, 17.00, 350.00], dtype=np.float32)
print("\nPredicting median home value for feature/predictor values: ")
print(unknown[0])
pred_prob = model.eval({X: unknown)
print("\nPredicted value is: ")
print(“$%0.2f (x1000)” %pred_value[0,0])
if __name__== ”__main__”:
   main()

Produzione

Using CNTK version = 2.7
batch 0: mean squared error = 385.6727, accuracy = 0.00%
batch 300: mean squared error = 41.6229, accuracy = 20.00%
batch 600: mean squared error = 28.7667, accuracy = 40.00%
batch 900: mean squared error = 48.6435, accuracy = 40.00%
batch 1200: mean squared error = 77.9562, accuracy = 80.00%
batch 1500: mean squared error = 7.8342, accuracy = 60.00%
batch 1800: mean squared error = 47.7062, accuracy = 60.00%
batch 2100: mean squared error = 40.5068, accuracy = 40.00%
batch 2400: mean squared error = 46.5023, accuracy = 40.00%
batch 2700: mean squared error = 15.6235, accuracy = 60.00%
Evaluating test data
Prediction accuracy = 64.00%
Predicting median home value for feature/predictor values:
[0.09 50. 4.5 17. 350.]
Predicted value is:
$21.02(x1000)

Salvataggio del modello addestrato

Questo set di dati del valore di Boston Home contiene solo 506 elementi di dati (tra i quali ne abbiamo citati solo 100). Pertanto, l'addestramento del modello di regressore NN richiede solo pochi secondi, ma l'addestramento su un set di dati di grandi dimensioni con centinaia o migliaia di elementi di dati può richiedere ore o addirittura giorni.

Possiamo salvare il nostro modello, in modo da non doverlo conservare da zero. Con l'aiuto del seguente codice Python, possiamo salvare il nostro NN addestrato -

nn_regressor = “.\\neuralregressor.model” #provide the name of the file
model.save(nn_regressor, format=C.ModelFormat.CNTKv2)

Di seguito sono riportati gli argomenti della funzione save () utilizzata sopra:

  • Il nome del file è il primo argomento di save()funzione. Può anche essere scritto insieme al percorso del file.

  • Un altro parametro è il format parametro che ha un valore predefinito C.ModelFormat.CNTKv2.

Caricamento del modello addestrato

Dopo aver salvato il modello addestrato, è molto facile caricare quel modello. Abbiamo solo bisogno di usare la funzione load (). Controlliamo questo nel seguente esempio:

import numpy as np
import cntk as C
model = C.ops.functions.Function.load(“.\\neuralregressor.model”)
np.set_printoptions(precision = 2, suppress=True)
unknown = np.array([[0.09, 50.00, 4.5, 17.00, 350.00], dtype=np.float32)
print("\nPredicting area median home value for feature/predictor values: ")
print(unknown[0])
pred_prob = model.eval({X: unknown)
print("\nPredicted value is: ")
print(“$%0.2f (x1000)” %pred_value[0,0])

Il vantaggio del modello salvato è che una volta caricato un modello salvato, può essere utilizzato esattamente come se il modello fosse appena stato addestrato.