[PYTHON] Code du didacticiel TensorFlow pour vous empêcher de tomber

Dans ce qui précède, j'ai mentionné que le document de Deep Learning Framework "TensorFlow" est difficile. Dans cet article, je voudrais essayer de résoudre MNIST (Handwritten Number Classification Problem) en utilisant le réseau à deux couches de TensorFlow.

Motivation - Je veux combler le fossé entre les débutants et les experts

En parcourant le didacticiel TensorFlow, il semble qu'il y ait un saut de niveau assez technique, avec "MNIST pour les débutants" d'abord et ensuite "Deep MNIST pour les experts".

--Pour les débutants ... Régression Softmax (multi-classe par fonction softmax, régression logistique)

Ne serait-il pas préférable de le comprendre étape par étape en insérant un modèle de réseau multicouche (MLP) au lieu de soudainement CNN (réseau neuronal convolutif)? Dans cet article, j'ai créé un code de didacticiel qui comble une telle lacune. Les caractéristiques sont les suivantes.

(Ce que vous faites peut être proche de l'exemple de code "mnist.py" pour le modèle entièrement connecté dans le référentiel GitHub TensorFlow, mais nous visions un code court facile à comprendre.)

Description du code

Ci-dessous, je voudrais regarder le code pour chaque partie.

import tensorflow as tf

# Import data
import input_data
mnist = input_data.read_data_sets("../MNIST_data/", one_hot=True)

Tout d'abord, import du module nécessaire. Si c'est vrai, il aurait peut-être été préférable de lire "input_data.py", mais comme il contient pas mal de fonctions, cette fois sans analyser le contenu J'ai décidé de l'utiliser comme une boîte noire.

Vient ensuite la préparation des variables à utiliser.

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

w_h = tf.Variable(tf.random_normal([784, 625], mean=0.0, stddev=0.05))
w_o = tf.Variable(tf.random_normal([625, 10], mean=0.0, stddev=0.05))
b_h = tf.Variable(tf.zeros([625]))
b_o = tf.Variable(tf.zeros([10]))

x et y_ sont des espaces réservés pour stocker les données d'entraînement (données de test), et w_h, w_o, b_h, b_o sont des paramètres d'apprentissage (poids et biais, couche cachée et couche de sortie). L'initialisation aléatoire se fait avec "tf.random_normal ()" qui génère des nombres aléatoires avec une distribution normale. Les paramètres du nombre aléatoire ont été fixés à moyenne = 0,0 et stddev = 0,05 selon la norme approximative de «petite valeur». (Pour le biais, initialisez avec zéro.)

# Create the model
def model(X, w_h, b_h, w_o, b_o):
    h = tf.sigmoid(tf.matmul(X, w_h) + b_h)
    pyx = tf.nn.softmax(tf.matmul(h, w_o) + b_o)
    
    return pyx

y_hypo = model(x, w_h, b_h, w_o, b_o)

# Cost Function basic term
cross_entropy = -tf.reduce_sum(y_*tf.log(y_hypo))

C'est la partie importante de ce code, la partie qui décrit le modèle du réseau neuronal.

La couche masquée calcule un prédicteur linéaire à partir de la valeur de la couche d'entrée et la place dans la fonction sigmoïde.

\textbf{u} ^{(h)} = \textbf{w} ^{(h)} \textbf{z} ^{(i)} + \textbf{b}^{(h)}
\textbf{z} ^{(h)} = f^{(h)}(\textbf{u}^{(h)})
f^{(h)}  \ : \ Sigmoid()\ ...\ \texttt{activation function}

Le calque de sortie calcule un prédicteur linéaire à partir de la valeur du calque masqué et le place dans la fonction Softmax.

\textbf{u} ^{(o)} = \textbf{w} ^{(o)} \textbf{z} ^{(h)} + \textbf{b}^{(o)}
\textbf{z} ^{(o)} = f^{(o)} (\textbf{u} ^{(o)})
f^{(o)} \ :\ Softmax()\ ...\ \texttt{activation function} 

(Ce qui précède est le contenu de def model ())

Calculez la valeur y_hypo de votre propre modèle avec ce modèle et trouvez la valeur d'entropie croisée avec l'étiquette de données d'apprentissage y_ (C'est la partie principale de la fonction de coût.)

Ensuite, le terme de régularisation est calculé.

# Regularization terms (weight decay)
L2_sqr = tf.nn.l2_loss(w_h) + tf.nn.l2_loss(w_o)
lambda_2 = 0.01

Pour le terme de régularisation, la norme carrée (L2_sqr) (atténuation du poids) a été utilisée. TensorFlow prend en charge "tf.nn.l2_loss ()" pour calculer cela.

# the loss and accuracy
loss = cross_entropy + lambda_2 * L2_sqr
train_step = tf.train.GradientDescentOptimizer(0.001).minimize(loss)
correct_prediction = tf.equal(tf.argmax(y_hypo,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))

C'est là que la définition de l'optimiseur et les valeurs numériques associées sont calculées. L'optimiseur évalue une fonction de coût avec un terme régulier ajouté. Nous avons choisi la méthode d'optimisation de la descente de gradient et avons fixé son taux d'apprentissage à 0,001. De plus, la formule permettant d'évaluer le résultat de la classification et de calculer sa précision est décrite.

# Train
init = tf.initialize_all_variables()

with tf.Session() as sess:
    sess.run(init)
    print('Training...')
    for i in range(20001):
        batch_xs, batch_ys = mnist.train.next_batch(100)
        train_step.run({x: batch_xs, y_: batch_ys})
        if i % 2000 == 0:
            train_accuracy = accuracy.eval({x: batch_xs, y_: batch_ys})
            print('  step, accurary = %6d: %6.3f' % (i, train_accuracy))

Après avoir initialisé les variables, démarrez une session et apprenez les paramètres à l'aide des données d'entraînement. Cette fois, le calcul du nombre prédéterminé de répétitions (20 000 fois +) est effectué sans effectuer de jugement de convergence ni d'interruption anticipée.

Lorsque la formation est terminée, la précision du classificateur est calculée à l'aide des données de test.

# (with tf.Session() as sess:Sera à l'intérieur)

    # Test trained model
    print('accuracy = ', accuracy.eval({x: mnist.test.images, y_: mnist.test.labels}))

Statut de republication et d'exécution du code

Le code expliqué ci-dessus est résumé et affiché à nouveau. (Environ 60 lignes de code.)

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import tensorflow as tf

# Import data
import input_data
mnist = input_data.read_data_sets("../MNIST_data/", one_hot=True)

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

w_h = tf.Variable(tf.random_normal([784, 625], mean=0.0, stddev=0.05))
w_o = tf.Variable(tf.random_normal([625, 10], mean=0.0, stddev=0.05))
b_h = tf.Variable(tf.zeros([625]))
b_o = tf.Variable(tf.zeros([10]))

# Create the model
def model(X, w_h, b_h, w_o, b_o):
    h = tf.sigmoid(tf.matmul(X, w_h) + b_h)
    pyx = tf.nn.softmax(tf.matmul(h, w_o) + b_o)
    
    return pyx

y_hypo = model(x, w_h, b_h, w_o, b_o)

# Cost Function basic term
cross_entropy = -tf.reduce_sum(y_*tf.log(y_hypo))

# Regularization terms (weight decay)
L2_sqr = tf.nn.l2_loss(w_h) + tf.nn.l2_loss(w_o)
lambda_2 = 0.01

# the loss and accuracy
loss = cross_entropy + lambda_2 * L2_sqr
train_step = tf.train.GradientDescentOptimizer(0.001).minimize(loss)
correct_prediction = tf.equal(tf.argmax(y_hypo,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))

# Train
init = tf.initialize_all_variables()

with tf.Session() as sess:
    sess.run(init)
    print('Training...')
    for i in range(20001):
        batch_xs, batch_ys = mnist.train.next_batch(100)
        train_step.run({x: batch_xs, y_: batch_ys})
        if i % 2000 == 0:
            train_accuracy = accuracy.eval({x: batch_xs, y_: batch_ys})
            print('  step, accurary = %6d: %6.3f' % (i, train_accuracy))

    # Test trained model
    print('accuracy = ', accuracy.eval({x: mnist.test.images, y_: mnist.test.labels}))

(Remarque: les trois premières lignes de __future__ ... sont des déclarations de compatibilité avec Python-3.)

La situation dans laquelle ce code est exécuté est la suivante.

Training...
  step, accurary =      0:  0.130
  step, accurary =   2000:  0.900
  step, accurary =   4000:  0.910
  step, accurary =   6000:  0.930
  step, accurary =   8000:  0.920
  step, accurary =  10000:  0.960
  step, accurary =  12000:  0.950
  step, accurary =  14000:  0.950
  step, accurary =  16000:  0.960
  step, accurary =  18000:  0.960
  step, accurary =  20000:  0.960
accuracy =  0.9546

La précision de la classification des données d'essai était de 95,46%. Comme prévu, la valeur était presque intermédiaire entre la valeur calculée par la fonction Softmax (91%) et la précision par le réseau neuronal convolutif (99,2%). (On a le sentiment de viser un peu.)

Ce que vous voulez faire comme prochaine étape

--Classification dans d'autres ensembles de données. (Cela signifie que les données sont autres que "MNIST".) --Visualisation graphique par "TensorBoard".

(J'étudie toujours, mais j'espère pouvoir partager le code TensoFlow tout en l'essayant petit à petit.)

Références (site Web)

Recommended Posts

Code du didacticiel TensorFlow pour vous empêcher de tomber
Comment exécuter du code TensorFlow 1.0 en 2.0
Tutoriel du didacticiel TensorFlow
Apprenez à gonfler des images à partir du code TensorFlow
Préparation à l'utilisation de Tensorflow (Anaconda) avec Visual Studio Code
J'ai essayé de porter le code écrit pour TensorFlow sur Theano