Bibliothèque pratique TF-Slim de Tensorflow

Bibliothèque pratique TF-Slim de Tensorflow

Plus tôt, j'ai écrit sur la bibliothèque de wrapper de Tensorflow.

MNIST sur Keras (backend TensorFlow) MNIST avec skflow

~~ Keras semble être facile à utiliser, mais il y en avait certains qui n'avaient pas Deconvolution (Transposed Convolution) etc., donc ~~ (Si vous regardez de plus près, vous pouvez utiliser Upsampling2D et Convolution2D) Lorsque je regardais le didacticiel pour étudier skflow et le Tensorflow brut, j'ai trouvé une bibliothèque utile cachée.

TensorFlow-Slim

Il semble que le dépôt Github ait été ajouté à partir de la version 0.9.

Certaines des contributions ne sont pas très bien annoncées, mais elles sont sympas, donc je pense que c'est une bonne idée de jeter un coup d'œil. Il dit qu'il ne le soutient pas officiellement et je ne sais pas ce qui se passera à l'avenir.

tensorflow/tensorflow/contrib/

Le contenu suivant peut changer considérablement à l'avenir.

Importation de TF-Slim

python


import tensorflow as tf
from tensorflow.contrib import slim

Initialisation du poids

python


weights = slim.variables.variable('weights',
                             shape=[10, 10, 3 , 3],
                             initializer=tf.truncated_normal_initializer(stddev=0.1),
                             regularizer=slim.l2_regularizer(0.05),
                             device='/CPU:0')

Cela dit que cela fonctionne, mais il semble que la méthode appelée variable n'est pas implémentée pour le moment, vous devrez donc peut-être apporter ce qui est à l'origine et l'importer.

models/inception/inception/

Définition de la couche

Les couches de ~~ (conv + pool) * 5, fc * 3 peuvent être écrites comme suit ~~ Comme écrit dans le README, c'était VGG16. conv2 pool conv2 pool conv3 pool conv3 pool conv3 pool fc3

python


with slim.arg_scope([slim.ops.conv2d, slim.ops.fc], stddev=0.01, weight_decay=0.0005):
  net = slim.ops.repeat_op(2, inputs, slim.ops.conv2d, 64, [3, 3], scope='conv1')
  net = slim.ops.max_pool(net, [2, 2], scope='pool1')
  net = slim.ops.repeat_op(2, net, slim.ops.conv2d, 128, [3, 3], scope='conv2')
  net = slim.ops.max_pool(net, [2, 2], scope='pool2')
  net = slim.ops.repeat_op(3, net, slim.ops.conv2d, 256, [3, 3], scope='conv3')
  net = slim.ops.max_pool(net, [2, 2], scope='pool3')
  net = slim.ops.repeat_op(3, net, slim.ops.conv2d, 512, [3, 3], scope='conv4')
  net = slim.ops.max_pool(net, [2, 2], scope='pool4')
  net = slim.ops.repeat_op(3, net, slim.ops.conv2d, 512, [3, 3], scope='conv5')
  net = slim.ops.max_pool(net, [2, 2], scope='pool5')
  net = slim.ops.flatten(net, scope='flatten5')
  net = slim.ops.fc(net, 4096, scope='fc6')
  net = slim.ops.dropout(net, 0.5, scope='dropout6')
  net = slim.ops.fc(net, 4096, scope='fc7')
  net = slim.ops.dropout(net, 0.5, scope='dropout7')
  net = slim.ops.fc(net, 1000, activation=None, scope='fc8')
return net

Vous pouvez également raccourcir conv * 3 + pool comme ceci

python


net = ...
for i in range(3):
  net = slim.ops.conv2d(net, 256, [3, 3], scope='conv3_' % (i+1))
net = slim.ops.max_pool(net, [2, 2], scope='pool3')

De plus, si vous utilisez la méthode de répétition fournie par slim

python


net = slim.ops.repeat_op(net, 3, slim.conv2d, 256, [3, 3], scope='conv3')
net = slim.ops.max_pool(net, [2, 2], scope='pool2')

Il semble que cela ajustera correctement la portée à «conv3 / conv3_1», «conv3 / conv3_2» et «conv3 / conv3_3».

fc * 3 a également les éléments suivants

python


x = slim.ops.fc(x, 32, scope='fc/fc_1')
x = slim.ops.fc(x, 64, scope='fc/fc_2')
x = slim.ops.fc(x, 128, scope='fc/fc_3')

Peut être écrit en une seule ligne

python


slim.stack(x, slim.fully_connected, [32, 64, 128], scope='fc')

Bien sûr, conv aussi

python


slim.stack(x, slim.ops.conv2d, [(32, [3, 3]), (32, [1, 1]), (64, [3, 3]), (64, [1, 1])], scope='core')

Il est écrit dans le README de OK et contrib, mais il n'y a pas d'implémentation. (Non écrit dans le fichier README d'Inception)

portée

Par exemple, s'il existe une telle couche de conv * 3

python


padding = 'SAME'
initializer = tf.truncated_normal_initializer(stddev=0.01)
regularizer = slim.losses.l2_regularizer(0.0005)
net = slim.ops.conv2d(inputs, 64, [11, 11], 4,
                      padding=padding,
                      weights_initializer=initializer,
                      weights_regularizer=regularizer,
                      scope='conv1')
net = slim.ops.conv2d(net, 128, [11, 11],
                      padding='VALID',
                      weights_initializer=initializer,
                      weights_regularizer=regularizer,
                      scope='conv2')
net = slim.ops.conv2d(net, 256, [11, 11],
                      padding=padding,
                      weights_initializer=initializer,
                      weights_regularizer=regularizer,
                      scope='conv3')

Si vous utilisez la portée préparée pour slim, vous ne pouvez décrire que les parties avec des arguments différents et omettre le reste.

python


with slim.arg_scope([slim.ops.conv2d], padding='SAME',
                    weights_initializer=tf.truncated_normal_initializer(stddev=0.01)
                    weights_regularizer=slim.losses.l2_regularizer(0.0005)):
  net = slim.ops.conv2d(inputs, 64, [11, 11], scope='conv1')
  net = slim.ops.conv2d(net, 128, [11, 11], padding='VALID', scope='conv2')
  net = slim.ops.conv2d(net, 256, [11, 11], scope='conv3')

En outre, chevaucher la portée

python


with slim.arg_scope([slim.ops.conv2d, slim.ops.fc],
                    activation_fn=tf.nn.relu,
                    weights_initializer=tf.truncated_normal_initializer(stddev=0.01),
                    weights_regularizer=slim.losses.l2_regularizer(0.0005)):
with arg_scope([slim.ops.conv2d], stride=1, padding='SAME'):
  net = slim.ops.conv2d(inputs, 64, [11, 11], 4, padding='VALID', scope='conv1')
  net = slim.ops.conv2d(net, 256, [5, 5],
                    weights_initializer=tf.truncated_normal_initializer(stddev=0.03),
                    scope='conv2')
  net = slim.ops.fc(net, 1000, activation_fn=None, scope='fc')

Après avoir défini ce qui est commun à conv et fc, vous pouvez définir ce qui s'applique uniquement à conv.

Fonction de perte

C'est acceptable

python


loss = slim.losses.cross_entropy_loss(predictions, labels)

Entraînement

slim.learning ne se trouve pas dans Inception et est présent dans slim dans contrib.

python


g = tf.Graph()

#Définir le modèle et la fonction de perte
# ...

total_loss = tf.get_collection(slim.losses.LOSSES_COLLECTION)
optimizer = tf.train.GradientDescentOptimizer(learning_rate)

train_op = slim.learning.create_train_op(total_loss, optimizer)
logdir = './stored_log/'

slim.learning.train(
    train_op,
    logdir,
    number_of_steps=1000,
    save_summaries_secs=300,
    save_interval_secs=600)

Impressions

Je pense que ce sera très pratique quand il pourra être utilisé. Je suis plutôt content que la v0.10 puisse être utilisée normalement.

Recommended Posts

Bibliothèque pratique TF-Slim de Tensorflow
Résumé de Tensorflow / Keras
Installation de TensorFlow, une bibliothèque d'apprentissage automatique de Google
Bibliothèque DNN (Deep Learning): Comparaison de chainer et TensorFlow (1)
Recommandation de la bibliothèque binpacking de python
Expérience de réglage des données Tensorflow
J'ai essayé de refactoriser le modèle CNN de TensorFlow en utilisant TF-Slim
Présentation de la configuration de la bibliothèque personnalisée
Résumé d'utilisation pratique de Flask
Installer une ancienne version de Tensorflow
Résumé des différentes opérations dans Tensorflow
Keras comme wrapper de Theano et TensorFlow
Tutoriel TensorFlow - Représentation vectorielle des mots (traduction)