[PYTHON] J'ai touché le Tensorboard de TensorFlow

Le Earth Defense Force 4.1 que j'ai acheté avec désinvolture est amusant et Thunder! Je vais dire. Il est normal que les fourmis viennent régulièrement, mais ne vous contentez pas de mordre!

Je me demande s'il est populaire de publier un tel cadre tel que l'apprentissage automatique ces jours-ci, et Microsoft a publié DMLT dans le même but. Tensorflow a pris les devants, mais je ne sais pas combien de breuvages il contient, et j'ai l'impression que je ne peux même pas le sortir, mais je ne peux pas le dire avant de le toucher. Il y a de nombreuses fois où je ne comprends pas le système d'apprentissage automatique même si je le touche.

Pour le moment, il peut être installé normalement, mais il vaut mieux voir la page officielle de cette zone. La recommandation officielle est virtualenv. Plus tard, j'ai été dupe parce que je ne suis pas Pythonista, mais Tensorflow n'est actuellement que pour 2.7. Le support de la série 3.x est également mentionné comme un problème, et il semble que le support soit en cours, donc je pense qu'il sortira bientôt.

http://tensorflow.org/get_started/os_setup.md

Tutoriel Tensorflow

Je pense que Tensorflow est devenu un sujet brûlant en raison de ses nombreux tutoriels. Nous fournissons officiellement des méthodes d'apprentissage automatique général (débutant) et d'apprentissage à l'aide du réseau convolutionnel.

Le contenu est entièrement en anglais, mais si vous recherchez des mots liés aux mathématiques, vous n'aurez pas beaucoup de problèmes. Pour le moment, je mettrai le Débutant et le Profond que j'ai fait avec des commentaires.

Beginner

# coding: utf-8
import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

import tensorflow as tf

#Espace réservé. Une variable pour stocker une certaine valeur. Le premier nombre de vecteurs bidimensionnels est Aucun car il s'agit d'un nombre arbitraire.
#La deuxième dimension est 784, le nombre de pixels de MNIST
x = tf.placeholder("float", [None, 784])

#W est le W. La raison pour laquelle la première dimension du vecteur bidimensionnel est le nombre de pixels est que l'ordre de la disposition de MNIST est index → pixel, et c'est une matrice.
#Si ce n'est pas le premier lors de la multiplication, le résultat ne sera pas un vecteur à 10 colonnes
W = tf.Variable(tf.zeros([784, 10]))
#C'est un vecteur unidimensionnel. Peu importe que ce soit une ligne ou une colonne, c'est juste un problème d'index.
b = tf.Variable(tf.zeros([10]))

#W et b sont tous deux considérés comme variables, mais dans la méthode de descente de gradient subséquente, la méthode de propagation de l'erreur de retour automatiquement
#Il sera mis à jour à chaque fois. Si vous n'utilisez pas la méthode de rétropropagation, vous ne serez pas affecté à la variable.
#La variable reste à sa valeur par défaut.

#matmul est une multiplication matricielle. L'ordre va de x à W en raison de la forme de la matrice.
#Les vecteurs unidimensionnels peuvent être ajoutés tels quels, donc ajoutez le résultat et b tels quels, et appliquez softmax au résultat.
#Par conséquent.
#Le résultat de softmax est un vecteur car il est le résultat de l'exécution de softmax pour chaque élément du vecteur résultant.
y = tf.nn.softmax(tf.matmul(x, W) + b + a)

#L'étiquette correcte pour y. Chaque étiquette est un vecteur de l'élément 10.
y_ = tf.placeholder("float", [None, 10])

#Le résultat de la multiplication de chaque élément de y par le vecteur logarithmique et chaque ligne de l'étiquette = scalaire est ajouté pour toutes les lignes, et le signe du résultat est déterminé.
cross_entropy = -tf.reduce_sum(y_*tf.log(y))

# #Optimisation des graphes par algorithme de rétropropagation en utilisant la méthode de descente de gradient. Jolie boîte noire
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)

#Initialisez toutes les variables. La session est une chose de type contextuel pour exécuter réellement un programme TensorFlow.
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)

writer = tf.train.SummaryWriter("./log", sess.graph_def)

#Il répète le processus d'acquisition aléatoire de 100 éléments de l'ensemble de données MNIST et d'exécution de la formation sur eux.
#Où x et y_Il semble que la raison pour laquelle la valeur est entrée uniquement dans est que le nombre inconnu = Aucun est entré ici, et il ne peut pas être utilisé à moins que cela ne soit confirmé.
#Espace réservé pour cela.
#Alors ici chacun[100, 784]Quand[100, 10]の行列が設定されるこQuandになる。
for i in range(1000):
    batch_xs, batch_ys = mnist.train.next_batch(100)

    sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})

#Le résultat d'apprentissage y et l'étiquette y_Dans chacun des vecteurs de, l'indice qui prend la valeur maximale est comparé.
#1 se trouve sur une étiquette = ce nombre, et en même temps, c'est toujours la valeur maximale.
#Par rapport à cela, la valeur la plus élevée dans le résultat de la formation = quelle valeur est jugée dans l'image, les index sont donc les mêmes.
#Juge
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))

# true/faux à 1.0/0.Diffuser à 0 et faire la moyenne des résultats ajoutés
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))

sess.run(accuracy, feed_dict={x:mnist.test.images, y_: mnist.test.labels}))

Deep

# coding: utf-8
import input_data
mnist = input_data.read_data_sets('MNIST_data', one_hot=True)

import tensorflow as tf
sess = tf.InteractiveSession()

x = tf.placeholder("float", [None, 784])
y_ = tf.placeholder("float", [None, 10])

#Créez une variable de pondération avec la forme spécifiée.
def weight_variable(shape):
    #stddev est l'écart type. tronqué_normal est la moyenne spécifiée (0 par défaut)
    #Et, à partir de l'écart type passé (par défaut 1), une valeur supérieure à deux fois l'écart type
    #Tronquer pour revenir
    initial = tf.truncated_normal(shape, stddev=0.1)
    return tf.Variable(initial)

def bias_variable(shape):
    initial = tf.constant(0.1, shape=shape)
    return tf.Variable(initial)

#Créez un nœud de calcul pour la convolution bidimensionnelle.
#Puisqu'il s'agit d'une convolution bidimensionnelle, la valeur d'entrée est créée en convolvant la valeur dans l'unité bidimensionnelle = largeur et hauteur.
# tf.nn.conv2d est un tenseur à quatre dimensions d'une forme d'entrée et de filtre.
#Faire du contenu de l'entrée un patch dans l'unité de largeur et de hauteur spécifiée par le filtre,
#Filtrez chaque patch pour réduire les dimensions.
#Pour les foulées, le premier et le dernier élément doivent toujours être 1. 2e et 3e
#L'élément est réellement utilisé et l'intervalle auquel la fenêtre à corriger est déplacée est spécifié.
#Ici, Stride vaut 1 pour les deux, donc il se déplace de 1 dans les directions horizontale et verticale.
#Ainsi, l'entrée et la sortie auront la même taille.
def conv2d(x, W):
    return tf.nn.conv2d(x, W, strides=[1,1,1,1], padding='SAME')

#Regroupez la valeur maximale dans la plage 2x2 de valeurs d'entrée. Peut-être.
#La taille du noyau et la taille des bandes sont de 2x2, donc seulement la plus grande de la gamme 2x2
#Image à quitter. Donc, si vous le mettez ici, la taille de l'image sera exactement divisée par deux.
def max_pool_2x2(x):
    return tf.nn.max_pool(x, ksize=[1,2,2,1],
                          strides=[1,2,2,1], padding='SAME')

#Première couche.
# weight_de variable[5,5,1,32]C'est parce que les deux premières dimensions sont la taille du patch une fois plié.
#La troisième dimension est le nombre de canaux d'entrée et la quatrième dimension est le nombre de canaux de sortie.
W_conv1 = weight_variable([5,5,1,32])
#Le nombre de canaux de sortie est de 32.
b_conv1 = bias_variable([32])

#Remodeler x. Quant à la façon de remodeler, elle prend cette forme parce qu'une forme à quatre dimensions est passée.
#La première valeur est aplatie, de sorte que toutes les valeurs de x sont développées unidimensionnellement.
#Les 2ème et 3ème dimensions sont respectivement la largeur et la hauteur de l'image, et la 4ème dimension est le nombre de canaux de couleur.
#Quel type de valeur est x? La version aplatie de l'image 28x28 est contenue dans un tableau unidimensionnel.
#C'est un tableau à deux dimensions. Convertissez la pièce 784 en 28x28, et enfin un élément dedans,
#C'est sous la forme de.
x_image = tf.reshape(x, [-1,28,28,1])

# weight,x_image,Appliquez un biais à la fonction ReLU pour regrouper les résultats.
#Lorsque ce processus est effectué, la taille de chaque donnée corrigée est divisée par deux.
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
h_pool1 = max_pool_2x2(h_conv1)

#La deuxième couche. La taille du patch reste la même, mais le nombre de canaux d'entrée et de sortie est respectivement de 32x et 2x.
W_conv2 = weight_variable([5,5,32,64])
b_conv2 = weight_variable([64])

#Notez que le premier argument de conv2d est le premier pool de couches. En faisant cela, la première couche
#A partir de chaque valeur du pool de résultats de convolution, les canaux d'entrée et de sortie correspondants
#Vous pouvez à nouveau vous connecter et patcher le résultat patché.
h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
h_pool2 = max_pool_2x2(h_conv2)

# h_Les données de pool2 ont respectivement 28 largeurs et 28 hauteurs./2/2 =Il est 7.
#Puisqu'il y a 64 canaux de sortie dans la deuxième couche, celui dans lequel cette quantité est alignée est la première dimension.
#La deuxième dimension est le nombre de neurones qui le calculent.
W_fc1 = weight_variable([7 * 7 * 64, 1024])
#Cela recevra également le même nombre de neurones que Weight
b_fc1 = bias_variable([1024])

# h_Au stade de pool2[-1,7,7,1]Puisqu'il est organisé dans l'ordre de 64 pièces chacun
#Convertir en un tableau bidimensionnel qui se chevauche
h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
#Maintenant, multipliez les matrices bidimensionnelles, et par conséquent[-1, 1024]J'ai obtenu un tableau bidimensionnel de. C'est virtuellement
#Est le résultat de.
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)

#Créez une couche d'abandon pour réduire le surajustement.
keep_prob = tf.placeholder("float")
#Par défaut, la probabilité que chaque élément soit conservé ou indépendant
#Abandonné au hasard.
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)

#A partir de là, les valeurs utilisées sont différentes, mais fondamentalement les mêmes.
#Puisqu'il s'agit d'une lecture en termes de couches, les valeurs réellement utilisées sont extraites du réseau convolutif.
W_fc2 = weight_variable([1024, 10])
b_fc2 = bias_variable([10])

y_conv = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)

#À partir de là, c'est presque le même que le modèle à une couche. Cependant, Optimizer est ADAM. Qu'est-ce qu'ADAM
#Je ne suis pas sûr.
cross_entropy = -tf.reduce_sum(y_ * tf.log(y_conv))
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
correct_prediction = tf.equal(tf.argmax(y_conv,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
sess.run(tf.initialize_all_variables())

#20000 fois et ainsi de suite, mais c'est environ la moitié abandonné en cours de route
#Parce que je suppose.
#Quand je l'exécute, je ne sais pas pourquoi, mais je devrais pouvoir utiliser 8 threads, mais je n'utilise que 4 threads
#C'était dans un état. Peut-être le nombre de processeurs (echo/proc/Parce qu'il y en a quatre dans cpuinfo)?
# Core i7-4790 @ 3.Environ 40 minutes à 60 GHz(!)Ça prend à peu près.
for i in range(20000):
    batch = mnist.train.next_batch(50)
    if i % 100 == 0:
        train_accuracy = accuracy.eval(feed_dict={
            x:batch[0], y_: batch[1], keep_prob: 1.0})
        print("step %d, training accuracy %g"%(i, train_accuracy))
    train_step.run(feed_dict={x:batch[0], y_:batch[1], keep_prob:0.5})

print("test accuracy %g"%accuracy.eval(feed_dict={x:mnist.test.images, y_:mnist.test.labels, keep_prob: 1.0}))

writer = tf.train.SummaryWriter("./log", sess.graph_def)

Mise en garde

J'ai ajouté des commentaires, mais j'ai également inclus ce qui est écrit dans ma compréhension et ma documentation. Alors veuillez me pardonner toute erreur.

Vitesse d'exécution

Débutant et Profond (version convolutionnelle), bien que le nombre de boucles soit différent, la différence de vitesse est extrêmement plus rapide en Débutant. Je n'ai rien fait de plus.

Quand je l'ai essayé sur ma machine (Core i7-4790 @ 3.60 GHz, mémoire 16GiB), le résultat était le suivant. À propos, le nombre de parallèles dans le processeur dans TensorFlow est probablement déterminé par le nombre de cœurs de processeur eux-mêmes, et il semble que les choses de type Hyperthread ne soient pas prises en compte.

Beginner       :Environ 5 secondes
Deep(CPU Only) :40 minutes(!?)

C'était un résultat choquant. Je voulais vraiment l'essayer avec GPU Enabled, mais le SDK CUDA qui va dans mon Gentoo n'est pas assez ou trop avancé, donc il me semblait que je devais commencer par installer CUDA lui-même, donc je vais le laisser pour le moment. Peut-être que le côté profond ne sera pas pratique à moins que cela ne soit fait avec un GPU ou dans l'environnement distribué dont parle Tensorflow.

Précautions lors de l'utilisation de Tensorboard

Il a ça! J'ai montré le décor que j'ai utilisé crunchy dans la vidéo, mais bien sûr, il peut être utilisé. Je ne suis pas le seul à penser à tort que c'était une application de bureau.

Il y a deux choses à garder à l'esprit lors de l'utilisation de Tensorboard, et si vous voulez juste voir le graphique au moment de l'exécution, vous n'avez pas besoin de quelque chose comme le graphique officiel.

writer = tf.train.SummaryWriter("./log", sess.graph_def)

OK. Cela créera un fichier dans . / Log appelé events.out.tfevents. . à chaque exécution. Cela peut être fait si la taille est étrangement grande.

Un autre, Tensorboard lui-même est un type d'application qui démarre un serveur à partir de la ligne de commande et obtient l'accès, mais lors de la spécification de ce répertoire, il devait être ** chemin complet **. Je pensais que c'était un piège ...

Configuration du Tensorboard

Si vous regardez ces choses ces jours-ci, pourquoi les faites-vous? J'étais inquiet, alors j'ai regardé derrière.

La bibliothèque que j'utilise est

J'ai entendu dagre pour la première fois, mais cela semble être une bibliothèque pour créer des graphiques dirigés.

Et ce qui m'a le plus surpris personnellement, c'est que je me souviens l'avoir vu plusieurs fois au travail.

    <link rel="import" href="external/polymer/polymer.html">

Quand j'ai vu la ligne. ** Polymère! ** Je me suis accidentellement précipité dedans. C'est Google ...

Et le corps de Tensorboard est encore plus surprenant,

/// <reference path="../../../typings/tsd.d.ts" />

N'y a-t-il pas une ligne qui dit ...! C'était une combinaison de TypeScript + Polymer. Certes, Polymer a une sensation de mouvement net même si vous faites quelque chose de similaire à React, il peut donc convenir à de telles applications qui sont susceptibles d'être lourdes.

Je n'ai pas vu la source originale, mais je pense qu'elle a été faite en vulcanisant \ * .ts et \ * .html en termes de composition. Vu qu'il est utilisé à cette échelle, je pense qu'il est normal d'utiliser Polymer. Cependant, Tensorboard ne fonctionnait que sur Chrome, alors soyez prudent à ce sujet.

Résumé du nom de l'impression

C'est la première fois que je touche à un tel cadre, mais je pense que c'est assez intuitif. Je pense qu'il est préférable de pouvoir calculer des matrices et des vecteurs, mais je pense que le fait que l'addition, la soustraction, la multiplication et la division soient assez intuitives est assez agréable pour les personnes qui doivent programmer des formules mathématiques.

Personnellement, j'étais satisfait de l'ajustement gluant du Tensorboard. J'ai peur que si une telle chose sort en open source, la demande d'écrans augmentera à nouveau.

Essayons un peu plus de didacticiel et voyons à quel point ce sera plus rapide si vous utilisez réellement le GPU. Si j'ai le temps, j'essaierai DMLT.

Recommended Posts

J'ai touché le Tensorboard de TensorFlow
J'ai touché HaikuFinder
J'ai touché Flask
J'ai touché AWS Chalice
J'ai essayé de toucher l'API Qiita
J'ai touché Bergeronnette (2). Introduction des extensions django.
J'ai touché Tensorflow et keras
J'ai touché PyAuto pendant un moment
J'ai touché quelque chose qui s'appelle Touch Designer
J'ai touché "Orator" alors j'ai fait une note
J'ai touché à l'outil de préparation de données Paxata