CNTK - Régression du réseau neuronal
Ce chapitre vous aidera à comprendre la régression du réseau neuronal en ce qui concerne CNTK.
introduction
Comme nous savons que, pour prédire une valeur numérique à partir d'une ou plusieurs variables prédictives, nous utilisons la régression. Prenons un exemple de prédiction de la valeur médiane d'une maison dans, disons, l'une des 100 villes. Pour ce faire, nous avons des données qui incluent -
Une statistique de criminalité pour chaque ville.
L'âge des maisons dans chaque ville.
Une mesure de la distance entre chaque ville et un emplacement privilégié.
Le ratio élèves-enseignant dans chaque ville.
Une statistique démographique raciale pour chaque ville.
La valeur médiane des maisons dans chaque ville.
Sur la base de ces cinq variables prédictives, nous aimerions prédire la valeur médiane des maisons. Et pour cela, nous pouvons créer un modèle de régression linéaire le long des lignes de -
Y = a0+a1(crime)+a2(house-age)+(a3)(distance)+(a4)(ratio)+(a5)(racial)
Dans l'équation ci-dessus -
Y est une valeur médiane prédite
a0 est une constante et
a1 à a5 sont toutes des constantes associées aux cinq prédicteurs dont nous avons discuté ci-dessus.
Nous avons également une approche alternative d'utilisation d'un réseau neuronal. Cela créera un modèle de prédiction plus précis.
Ici, nous allons créer un modèle de régression de réseau neuronal en utilisant CNTK.
Chargement de l'ensemble de données
Pour implémenter la régression du réseau neuronal à l'aide de CNTK, nous utiliserons l'ensemble de données des valeurs des maisons de la région de Boston. L'ensemble de données peut être téléchargé à partir du référentiel UCI Machine Learning qui est disponible surhttps://archive.ics.uci.edu/ml/machine-learning-databases/housing/. Cet ensemble de données a un total de 14 variables et 506 instances.
Mais, pour notre programme de mise en œuvre, nous allons utiliser six des 14 variables et 100 instances. Sur 6, 5 en tant que prédicteurs et un en tant que valeur à prédire. Sur 100 instances, nous en utiliserons 80 pour la formation et 20 pour les tests. La valeur que nous voulons prédire est le prix médian des logements dans une ville. Voyons les cinq prédicteurs que nous utiliserons -
Crime per capita in the town - Nous nous attendrions à ce que des valeurs plus petites soient associées à ce prédicteur.
Proportion of owner - unités occupées construites avant 1940 - Nous nous attendrions à ce que des valeurs plus petites soient associées à ce prédicteur, car une valeur plus élevée signifie une maison plus ancienne.
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.
Préparation des fichiers de formation et de test
Comme nous l'avons fait auparavant, nous devons d'abord convertir les données brutes au format CNTK. Nous allons utiliser les 80 premiers éléments de données à des fins de formation, le format CNTK délimité par des tabulations est donc le suivant -
|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
. . .
Les 20 éléments suivants, également convertis au format CNTK, seront utilisés à des fins de test.
Construire un modèle de régression
Tout d'abord, nous devons traiter les fichiers de données au format CNTK et pour cela, nous allons utiliser la fonction d'assistance nommée create_reader comme suit -
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
Ensuite, nous devons créer une fonction d'assistance qui accepte un objet mini-batch CNTK et calcule une métrique de précision personnalisée.
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)
Maintenant, nous devons définir les arguments d'architecture pour notre NN et également fournir l'emplacement des fichiers de données. Cela peut être fait à l'aide du code python suivant -
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)
Maintenant, avec l'aide de la ligne de code suivante, notre programme créera le NN non entraîné -
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)
Maintenant, une fois que nous avons créé le modèle dual non entraîné, nous devons configurer un objet d'algorithme d'apprentissage. Nous allons utiliser l'apprenant SGD etsquared_error fonction de perte -
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])
Maintenant, une fois que nous avons terminé avec l'objet algorithme d'apprentissage, nous devons créer une fonction de lecture pour lire les données d'apprentissage -
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 }
Maintenant, il est temps de former notre modèle 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))
Une fois que nous avons terminé l'entraînement, évaluons le modèle à l'aide d'éléments de données de 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)
Après avoir évalué la précision de notre modèle NN formé, nous l'utiliserons pour faire une prédiction sur des données invisibles -
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])
Modèle de régression complet
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()
Production
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)
Enregistrer le modèle entraîné
Cet ensemble de données sur la valeur Boston Home ne contient que 506 éléments de données (parmi lesquels nous n'en avons poursuivi que 100). Par conséquent, il ne faudrait que quelques secondes pour entraîner le modèle de régresseur NN, mais l'entraînement sur un vaste ensemble de données contenant des centaines ou des milliers d'éléments de données peut prendre des heures, voire des jours.
Nous pouvons sauvegarder notre modèle afin de ne pas avoir à le conserver à partir de zéro. Avec l'aide du code Python suivant, nous pouvons enregistrer notre NN formé -
nn_regressor = “.\\neuralregressor.model” #provide the name of the file
model.save(nn_regressor, format=C.ModelFormat.CNTKv2)
Voici les arguments de la fonction save () utilisée ci-dessus -
Le nom de fichier est le premier argument de save()fonction. Il peut également être écrit avec le chemin du fichier.
Un autre paramètre est le format paramètre qui a une valeur par défaut C.ModelFormat.CNTKv2.
Chargement du modèle entraîné
Une fois que vous avez enregistré le modèle entraîné, il est très facile de charger ce modèle. Nous n'avons besoin que de la fonction load (). Vérifions cela dans l'exemple suivant -
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])
L'avantage du modèle enregistré est qu'une fois que vous chargez un modèle enregistré, il peut être utilisé exactement comme si le modèle venait d'être entraîné.