Bonjour. Dans cet article, j'expliquerai le style d'écriture de base et la grammaire de TensorFlow (TF). La cible est pour ceux qui sont nouveaux sur TF et qui n'ont pas beaucoup écrit Python.
En toile de fond, j'ai correctement écrit le code Python lorsque j'ai touché TF. Puisqu'il s'agit d'une note laissée à ce moment-là, cela peut aider des personnes similaires à comprendre TF.
J'ai utilisé "Évaluer le salaire des joueurs de baseball professionnels avec un réseau neuronal" du sergent-sorcier comme exemple de code. .. Merci pour votre permission de publier.
import tensorflow as tf
import numpy
J'utilise également numpy, alors n'oubliez pas de l'importer.
SCORE_SIZE = 33
HIDDEN_UNIT_SIZE = 32
TRAIN_DATA_SIZE = 90
SCORE_SIZE: Dimension des données d'entrée HIDDEN_UNIT_SIZE: Nombre de nœuds de couche cachée (couche intermédiaire) TRAIN_DATA_SIZE: nombre d'échantillons de données d'entraînement Vous pouvez définir vous-même le nom de la variable!
raw_input = numpy.loadtxt(open(`input.csv`), delimiter=`,`)
[salary, score] = numpy.hsplit(raw_input, [1])
numpy.loadtxt: fonction de chargement de données dans la bibliothèque numpy.
delimiter est une spécification de délimiteur de données. L'auteur a stocké les données dans input.csv. http://goo.gl/h5g8cJ raw_input stocke les données de type tableau.
numpy.hsplit: fonction qui place une ligne de division dans la direction verticale (direction de la colonne) et divise le tableau dans la direction horizontale (direction de la ligne).
raw_input: tableau à fractionner [1]: La ligne de démarcation de la division. Sélectionnez la 0ème colonne et affectez-la au salaire, puis affectez la 1ère colonne au score. Par conséquent, le salaire est un vecteur du nombre de composants = nombre de personnes (= 94), et le score est un tableau de 94 x 33. Notez que le salaire correspond aux données de l'enseignant et le score aux données d'entrée. http://goo.gl/hoMyGH
[salary_train, salary_test] = numpy.vsplit(salary, [TRAIN_DATA_SIZE])
[score_train, score_test] = numpy.vsplit(score, [TRAIN_DATA_SIZE])
numpy.vsplit: une fonction qui insère un scalpel horizontalement et divise le tableau verticalement.
salaire_train: Vecteur avec 89 composants salaire_test: vecteur avec 5 composants score_train: tableau 89 x 33 score_test: tableau 5 x 33
def inference(score_placeholder):
with tf.name_scope('hidden1') as scope:
hidden1_weight = tf.Variable(tf.truncated_normal([SCORE_SIZE, HIDDEN_UNIT_SIZE], stddev=0.1), name=`hidden1_weight`)
hidden1_bias = tf.Variable(tf.constant(0.1, shape=[HIDDEN_UNIT_SIZE]), name=`hidden1_bias`)
hidden1_output = tf.nn.relu(tf.matmul(score_placeholder, hidden1_weight) + hidden1_bias)
with tf.name_scope('output') as scope:
output_weight = tf.Variable(tf.truncated_normal([HIDDEN_UNIT_SIZE, 1], stddev=0.1), name=`output_weight`)
output_bias = tf.Variable(tf.constant(0.1, shape=[1]), name=`output_bias`)
output = tf.matmul(hidden1_output, output_weight) + output_bias
return tf.nn.l2_normalize(output, 0)
inférence: nom de la fonction (facultatif) score_placeholder: Données définies dans le code ci-dessous.
Pour les données de type espace réservé, spécifiez les données / données de mise à jour (c'est-à-dire les données d'entrée et les données de l'enseignant) qui seront la source de l'apprentissage. C'est un type de données propre à TF. Dans TF, lors de la mise à jour des apprentissages, les données d'origine sont reprises par un mécanisme appelé feed. Le type d'espace réservé est lié au flux et les données d'entrée seront reflétées dans les calculs associés. http://goo.gl/uhHk3o
with tf.name_scope('hidden1') as scope:
avec: syntaxe python. Une instruction qui ne transfère pas les instructions suivantes à des commandes en dehors du contexte. tf.name_scope: fonction de gestion des noms TF. Un groupe de contexte est formé pour les instructions imbriquées sous cette fonction.
L'avantage de la gestion des noms est le dessin. TensorFlow peut illustrer le modèle de l'apprenant construit sur TensorBoard. La gestion des noms facilite la compréhension de la sortie du dessin. Ici, les actions d'affectation de pondération et de biais suivantes sont imbriquées sous la fonction name_scope. Autrement dit, il définit que ces instructions sont dans le contexte de «hidden1», un calcul de paramètre de couche cachée. http://goo.gl/AYodFB
hidden1_weight = tf.Variable(tf.truncated_normal([SCORE_SIZE, HIDDEN_UNIT_SIZE], stddev=0.1), name=`hidden1_weight`)
hidden1_bias = tf.Variable(tf.constant(0.1, shape=[HIDDEN_UNIT_SIZE]), name=`hidden1_bias`)
hidden1_output = tf.nn.relu(tf.matmul(score_placeholder, hidden1_weight) + hidden1_bias)
C'est un calcul de ** couche d'entrée → couche cachée **.
tf.Variable: La classe de variable TF peut être appliquée
En plus de générer en tant que variable, il a diverses fonctions. Par exemple, la commande assign peut écraser la valeur d'une variable. (Les détails sont liés ci-dessous) http://goo.gl/nUJafs
tf.truncated_normal: renvoie un nombre aléatoire normalement distribué
[SCORE_SIZE, HIDDEN_UNIT_SIZE]: La taille du tableau des nombres aléatoires souhaités. stddev: spécifiez l'écart type de la distribution normale. Dans la distribution normale standard, spécifiez "mean = 0.0, stddev = 1.0". La valeur initiale du poids NN $ {\ bf W} $ est générée par des nombres aléatoires. A ce stade, ce programme peut être interprété comme un NN sans pré-apprentissage. hidden1_weight peut être interprété comme une matrice avec un poids de $ {\ bf W} $. nom nomme simplement l'exécution de cette fonction. http://goo.gl/oZkcvs
tf.constant: fonction pour générer des constantes
0,1: Génère la constante 0,1. forme: la taille qui rend la constante. Créez uniquement le nombre d'unités de calque masquées (HIDDEN_UNIT_SIZE) et remplacez-les par hidden1_bias. hidden1_bias est le terme de biais de la couche masquée, et ici la valeur initiale est fixée à 0,1.
tf.nn.relu: une fonction qui calcule ReLU, qui est l'une des fonctions d'activation. (Cet article a pour but d'expliquer le code, veuillez donc apprendre la signification de ReLU séparément m (_ _) m)
tf.matmul: Une fonction qui calcule le produit des matrices (vecteurs) (ou le produit interne si ce sont des vecteurs)
Ici, le produit de la matrice score_placeholder et de la matrice hidden1_weight est calculé. Comme vous pouvez le voir dans la définition ci-dessous, cette définition est valable car le nombre de colonnes dans score_placeholder est défini comme SCORE_SIZE. En conséquence, le résultat du calcul du nombre d'unités est calculé en tant que vecteur en sortie.
with tf.name_scope('output') as scope:
output_weight = tf.Variable(tf.truncated_normal([HIDDEN_UNIT_SIZE, 1], stddev=0.1), name=`output_weight`)
output_bias = tf.Variable(tf.constant(0.1, shape=[1]), name=`output_bias`)
output = tf.matmul(hidden1_output, output_weight) + output_bias
return tf.nn.l2_normalize(output, 0)
C'est un calcul de ** couche cachée → couche de sortie **. la sortie est calculée en scalaire. En d'autres termes, l'unité de la couche de sortie est 1, qui est l'objectif de comparaison avec le salaire annuel du joueur (données de l'enseignant). Dans ce cas, la fonction d'activation est transformée en un mappage uniforme pour la couche de sortie. tf.nn.l2_normalize: Fonction qui calcule et renvoie la normalisation
S'il s'agit d'un vecteur, divisez chaque composante du vecteur par la norme. (Transformation où la magnitude du vecteur devient 1) Il en va de même pour les matrices et les tenseurs. S'il s'agit d'un scalaire, 1 est renvoyé. Ici, comme les données d'origine sont également normalisées, il est nécessaire de comparer les valeurs normalisées. https://goo.gl/NEFajc
def loss(output, salary_placeholder, loss_label_placeholder):
with tf.name_scope('loss') as scope:
loss = tf.nn.l2_loss(output - tf.nn.l2_normalize(salary_placeholder, 0))
tf.scalar_summary(loss_label_placeholder, loss)
return loss
tf.nn.l2_loss: une fonction qui calcule l'erreur quadratique.
Notez qu'il existe des restrictions sur le type de données. Les principales fonctions d'erreur sont la ** fonction d'erreur carrée ** et la ** fonction d'erreur d'entropie croisée **. La fonction d'erreur carrée est utilisée pour la tâche de prédiction numérique et la fonction d'erreur d'entropie croisée est utilisée pour la tâche de classification. La méthode pour spécifier salaire_placeholder consiste à saisir les données de salaire comme données d'enseignant dans cette variable pour chaque mise à jour. http://goo.gl/V67M7c
tf.scalar_summary: une fonction qui attache une chaîne de caractères au scalaire cible et enregistre la signification de la valeur.
loss_label_placeholder est défini ci-dessous comme un espace réservé de chaîne. http://goo.gl/z7JWNe
def training(loss):
with tf.name_scope('training') as scope:
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(loss)
return train_step
tf.train.GradientDescentOptimizer: une classe qui stocke les algorithmes SGD.
0,01: représente le coefficient d'apprentissage ε minimiser (perte): Tricky, mais une fonction stockée dans une classe appelée tf.train.GradientDescentOptimizer qui minimise la variable cible (perte dans ce cas) Puisqu'il s'agit d'un objet qui stocke le processus de calcul, le paramètre de poids mis à jour après le calcul différentiel est renvoyé. http://goo.gl/5XENkX
Dans TensorFlow, un groupe d'algorithmes liés à l'exécution de l'apprentissage est stocké dans une classe appelée Graph. Non seulement le calcul (session.run) mais aussi les informations nécessaires au dessin du graphe (session.graph) sont organisés comme son nom l'indique. (C'est pratique (・ ω <))
with tf.Graph().as_default():
salary_placeholder = tf.placeholder(`float`, [None, 1], name=`salary_placeholder`)
score_placeholder = tf.placeholder(`float`, [None, SCORE_SIZE], name=`score_placeholder`)
loss_label_placeholder = tf.placeholder(`string`, name=`loss_label_placeholder`)
avec tf.Graph (). as_default () :: Instruction déclarant la classe graph salaire_placeholder: un objet qui stocke les données annuelles des enseignants
[Aucun, 1]: signifie que le nombre de colonnes est 1 et que le nombre de lignes est arbitraire.
score_placeholder: objet pour stocker les données d'entrée loss_label_placeholder = Objet de stockage de chaîne de caractères à inclure / refléter dans les informations récapitulatives au moment de la sortie
feed_dict_train={
salary_placeholder: salary_train,
score_placeholder: score_train,
loss_label_placeholder: `loss_train`
}
feed_dict_train: Déclaration des données de type dictionnaire à consommer à chaque mise à jour de la formation
Stocké dans les données du dictionnaire (feed_dict_train). Pour que le TF puisse lire les données à chaque fois, le flux doit être mordu. http://goo.gl/00Ikjg ↑ Revue des données de type dictionnaire Entrez un Tensor temporaire pour la clé et une valeur initiale pour la valeur. Un ensemble de dictionnaires pour les données d'entraînement. Vous pouvez voir pourquoi vous avez besoin de ce type de dictionnaire dans session.run ci-dessous.
feed_dict_test={
salary_placeholder: salary_test,
score_placeholder: score_test,
loss_label_placeholder: `loss_test`
}
feed_dict_test: créer des données de dictionnaire pour les données de test La configuration est la même que ci-dessus.
python
output = inference(score_placeholder)
loss = loss(output, salary_placeholder, loss_label_placeholder)
training_op = training(loss)
Insérez l'inférence de la fonction de calcul NN de propagation avant dans la «sortie».
Insérez la fonction de calcul perte de la fonction d'erreur carrée dans loss
.
Insérez l'entraînement de la fonction d'exécution de l'algorithme SGD dans training_op
.
python
summary_op = tf.merge_all_summaries()
tf.merge_all_summaries: agrège les informations de la fonction Summary.
http://goo.gl/wQo8Rz
init = tf.initialize_all_variables()
Affectez la fonction tf.initialize_all_variables qui initialise toutes les variables à init. ** Le moment de la déclaration d'initialisation est important. ** Si vous ne déclarez pas après avoir défini toutes les variables requises, une erreur sera renvoyée.
http://goo.gl/S58XJ2
best_loss = float(`inf`)
Déclarez best_loss, un nombre à virgule flottante. Il y a un endroit pour mettre à jour l'erreur ci-dessous. Nous utilisons best_loss pour cette valeur, mais le best_loss initial est supérieur à tout nombre (inf; infinity) car nous devons toujours inclure la perte de valeur initiale.
with tf.Session() as sess:
Session est une classe de base dans Graph, et contient des instructions liées à l'exécution en général. Si Session n'est pas déclarée, tous les traitements liés aux objets tf ne démarreront pas.
http://goo.gl/pDZeLI
summary_writer = tf.train.SummaryWriter('data', graph_def=sess.graph_def)
tf.train.SummaryWriter: une fonction qui écrit des informations récapitulatives dans un fichier d'événements.
sess.run(init)
sess.run: fonction de base supplémentaire.
Exécutez l'instruction écrite dans le premier argument. Sous Windows, c'est comme .exe!
for step in range(10000):
sess.run(training_op, feed_dict=feed_dict_train)
loss_test = sess.run(loss, feed_dict=feed_dict_test)
pour l'étape dans la plage (10000): répétez 10000 fois. "Apprentissage des données pour 89 personnes et test des données pour 5 personnes." C'est une fois! feed_dict = feed_dict_train: option importante pour session.run
Le système d'alimentation qui a été expliqué à plusieurs reprises ici. Ici, les données nécessaires sont prises et le calcul de mise à jour d'apprentissage est effectué.
if loss_test < best_loss:
best_loss = loss_test
best_match = sess.run(output, feed_dict=feed_dict_test)
Uniquement lorsque la valeur d'erreur minimale est mise à jour, enregistrez la valeur d'erreur et la couche de sortie (salaire annuel estimé).
if step % 100 == 0:
summary_str = sess.run(summary_op, feed_dict=feed_dict_test)
summary_str += sess.run(summary_op, feed_dict=feed_dict_train)
summary_writer.add_summary(summary_str, step)
Une instruction pour collecter des informations récapitulatives une fois toutes les 100 étapes. En outre, écrivez les informations collectées dans le fichier d'événements.
print sess.run(tf.nn.l2_normalize(salary_placeholder, 0), feed_dict=feed_dict_test)
print best_match
Affichez les données des enseignants et les données de couche de sortie très précises pour chaque étape