TF.slim--学習ノート

11809 ワード

F-Slimの利点:slimは軽量レベルのtensorflowライブラリとして、モデルの構築、トレーニング、テストをより簡単にします.
1.使用方法:import tensorflow.contrib.slim as slim
2.構成部品:arg_scope:ユーザーが同じarg_scopeではデフォルトのパラメータdata,evaluation,layers,learning,losses,metrics,nets,queues,regularization,variablesを使用します.
  • 定義モデルslimでは、variables、layers、scopesを組み合わせてモデルを簡潔に定義できます.(1)variables:variables.pyに定義されています.weight変数を生成し、truncated normalで初期化し、l 2を使用して正規化し、CPU上に配置します.次のコードだけでいいです.
  • weights = slim.variable('weights', shape=[10, 10, 3 , 3],                         
    
                            initializer=tf.truncated_normal_initializer(stddev=0.1), 
    
                                 regularizer=slim.l2_regularizer(0.05),
    
                                 device='/CPU:0')
    
    

    原生tensorflowには、一般変数と局所変数の2つの変数が含まれています.ほとんどの変数は通常の変数で、生成されるとsaverを使用してハードディスクに格納できます.ローカル変数はsessionにのみ存在し、保存されません.slimは変数タイプをさらに区別し,モデルのパラメータを表すmodel variablesを定義した.モデル変数は,生きている微調整を訓練することによって学習され,生きていることは評価や前伝にcheckpointファイルからロードできる.非モデルパラメータglobal_のような実際の前伝に不要なパラメータstep.同様に,移動平均はモデルパラメータを反応させたが,それ自体はモデルパラメータではなかった.例は次のとおりです.
      # Model Variables     
      weights = slim.model_variable('weights',
                                    shape=[10, 10, 3 , 3],
                                    initializer=tf.truncated_normal_initializer(stddev=0.1),
                                    regularizer=slim.l2_regularizer(0.05),
                                    device='/CPU:0')
      model_variables = slim.get_model_variables()
      # model_variables  weights
      # Regular variables     
      my_var = slim.variable('my_var',
                             shape=[20, 1],
                             initializer=tf.zeros_initializer())
      regular_variables_and_model_variables = slim.get_variables()
      #get_variables()           
    

    私たちがslimのlayersを通ったり、slimを直接使ったりします.model_variableが変数を作成すると、tfはこの変数をtfに加える.GraphKeys.MODEL_VARIABLESという集合では,独自の変数を構築する必要がある場合,以下のコードでモデルパラメータに加えることができる.
      my_model_variable = CreateViaCustomCode()
    
      # Letting TF-Slim know about the additional variable.
      slim.add_model_variable(my_model_variable)
    

    (2)layers:一般的なレイヤを抽象化してカプセル化し、repeatとstack操作を提供することで、ネットワークの定義をより容易にする.以下のコードは、repeatを用いて3つのボリューム積層net=slim.repeat(net,3,slim.conv 2 d,256,[3,3],scope='conv 3')repeatが同じ操作の同じパラメータの繰り返しだけでなく、scopeを展開する.例のscopeは'conv 3/conv 3_に展開される1', 'conv3/conv3_2' and 'conv3/conv3_3'. slim.stack操作により、同じ操作を異なるパラメータでいくつかの層に繰り返し作用させることができ、これらの層の入出力時に直列に接続されている.例:
      slim.stack(x, slim.fully_connected, [32, 64, 128], scope='fc')
      slim.stack(x, slim.conv2d, [(32, [3, 3]), (32, [1, 1]), (64, [3, 3]), (64, [1, 1])], scope='core')
    

    3)scopes:tensorflowのnameを除くscopeとvariable_scope, tf.slimにarg_が追加されましたscopeオペレーション.このオペレータは、このscopeで定義されたオペレーションにパラメータを共有させることができます.すなわち、パラメータを作成しない場合は、デフォルトのパラメータを使用します.パラメータをローカルに上書きできます.コードをより簡潔にするには、次のようにします.
      with slim.arg_scope([slim.conv2d], padding='SAME',
                            weights_initializer=tf.truncated_normal_initializer(stddev=0.01)
                            weights_regularizer=slim.l2_regularizer(0.0005)):
          net = slim.conv2d(inputs, 64, [11, 11], scope='conv1')
          net = slim.conv2d(net, 128, [11, 11], padding='VALID', scope='conv2')
          net = slim.conv2d(net, 256, [11, 11], scope='conv3')
    

    さらに、複数のarg_をネストすることもできます.scopeでは、次のような複数の操作が使用されます.
    with slim.arg_scope([slim.conv2d, slim.fully_connected],
                            activation_fn=tf.nn.relu,
                            weights_initializer=tf.truncated_normal_initializer(stddev=0.01),
                            weights_regularizer=slim.l2_regularizer(0.0005)):
        with slim.arg_scope([slim.conv2d], stride=1, padding='SAME'):
          net = slim.conv2d(inputs, 64, [11, 11], 4, padding='VALID', scope='conv1')
          net = slim.conv2d(net, 256, [5, 5],
                            weights_initializer=tf.truncated_normal_initializer(stddev=0.03),
                            scope='conv2')
          net = slim.fully_connected(net, 1000, activation_fn=None, scope='fc')
    

    この例では、最初のarg_scopeはweights_initializerと
    def vgg16(inputs):
      with slim.arg_scope([slim.conv2d, slim.fully_connected],
                          activation_fn=tf.nn.relu,
                          weights_initializer=tf.truncated_normal_initializer(0.0, 0.01),
                          weights_regularizer=slim.l2_regularizer(0.0005)):
        net = slim.repeat(inputs, 2, slim.conv2d, 64, [3, 3], scope='conv1')
        net = slim.max_pool2d(net, [2, 2], scope='pool1')
        net = slim.repeat(net, 2, slim.conv2d, 128, [3, 3], scope='conv2')
        net = slim.max_pool2d(net, [2, 2], scope='pool2')
        net = slim.repeat(net, 3, slim.conv2d, 256, [3, 3], scope='conv3')
        net = slim.max_pool2d(net, [2, 2], scope='pool3')
        net = slim.repeat(net, 3, slim.conv2d, 512, [3, 3], scope='conv4')
        net = slim.max_pool2d(net, [2, 2], scope='pool4')
        net = slim.repeat(net, 3, slim.conv2d, 512, [3, 3], scope='conv5')
        net = slim.max_pool2d(net, [2, 2], scope='pool5')
        net = slim.fully_connected(net, 4096, scope='fc6')
        net = slim.dropout(net, 0.5, scope='dropout6')
        net = slim.fully_connected(net, 4096, scope='fc7')
        net = slim.dropout(net, 0.5, scope='dropout7')
        net = slim.fully_connected(net, 1000, activation_fn=None, scope='fc8')
      return net
    
  • 訓練モデルTensorflowのモデル訓練にはモデル,損失関数,勾配計算,およびlossの勾配反復に従ってパラメータを更新する必要がある.(1)losses既存のloss:
  • を使用
    loss = slim.losses.softmax_cross_entropy(predictions, labels)
    

    マルチタスク学習のlossでは、次の操作を実行できます.
    # Define the loss functions and get the total loss.
    classification_loss = slim.losses.softmax_cross_entropy(scene_predictions, scene_labels)
    sum_of_squares_loss = slim.losses.sum_of_squares(depth_predictions, depth_labels)
    
    # The following two lines have the same effect:
    total_loss = classification_loss + sum_of_squares_loss
    total_loss = slim.losses.get_total_loss(add_regularization_losses=False)
    

    自分で定義したlossを使用し、slimのloss管理メカニズムを使用したい場合は、次の操作を行います.
    pose_loss = MyCustomLossFunction(pose_predictions, pose_labels)
    slim.losses.add_loss(pose_loss) 
    total_loss = slim.losses.get_total_loss()
    #total_loss    pose_loss
    

    (2)トレーニングサイクルslimはlearning.pyでは、簡単で有用なトレーニングモデルのツールが提供されています.私たちはslimを呼び出すだけです.learning.create_train_opとslim.learning.trainは最適化プロセスを完了することができます.
    g = tf.Graph()
    
    # Create the model and specify the losses...
    ...
    
    total_loss = slim.losses.get_total_loss()
    optimizer = tf.train.GradientDescentOptimizer(learning_rate)
    
    # create_train_op ensures that each time we ask for the loss, the update_ops
    # are run and the gradients being computed are applied too.
    train_op = slim.learning.create_train_op(total_loss, optimizer)
    logdir = ... # Where checkpoints are stored.
    
    slim.learning.train(
        train_op,
        logdir,
        number_of_steps=1000,#    
        save_summaries_secs=300,# summary    
        save_interval_secs=600)#        
    

    (3)訓練の例:
    import tensorflow as tf
    
    slim = tf.contrib.slim
    vgg = tf.contrib.slim.nets.vgg
    
    ...
    
    train_log_dir = ...
    if not tf.gfile.Exists(train_log_dir):
      tf.gfile.MakeDirs(train_log_dir)
    
    with tf.Graph().as_default():
      # Set up the data loading:
      images, labels = ...
    
      # Define the model:
      predictions = vgg.vgg16(images, is_training=True)
    
      # Specify the loss function:
      slim.losses.softmax_cross_entropy(predictions, labels)
    
      total_loss = slim.losses.get_total_loss()
      tf.summary.scalar('losses/total_loss', total_loss)
    
      # Specify the optimization scheme:
      optimizer = tf.train.GradientDescentOptimizer(learning_rate=.001)
    
      # create_train_op that ensures that when we evaluate it to get the loss,
      # the update_ops are done and the gradient updates are computed.
      train_tensor = slim.learning.create_train_op(total_loss, optimizer)
    
      # Actually runs training.
      slim.learning.train(train_tensor, train_log_dir)
    
  • 既存モデルに従って微調整(1)tf.train.Saver()を用いてcheckpointからモデル
  • を復元する.
    # Create some variables.
    v1 = tf.Variable(..., name="v1")
    v2 = tf.Variable(..., name="v2")
    ...
    # Add ops to restore all the variables.
    restorer = tf.train.Saver()
    
    # Add ops to restore some variables.
    restorer = tf.train.Saver([v1, v2])
    
    # Later, launch the model, use the saver to restore variables from disk, and
    # do some work with the model.
    with tf.Session() as sess:
      # Restore variables from disk.
      restorer.restore(sess, "/tmp/model.ckpt")
      print("Model restored.")
      # Do some work with the model
      ...
    

    (2)部分回復モデルパラメータ
    # Create some variables.
    v1 = slim.variable(name="v1", ...)
    v2 = slim.variable(name="nested/v2", ...)
    ...
    
    # Get list of variables to restore (which contains only 'v2'). These are all
    # equivalent methods:
    variables_to_restore = slim.get_variables_by_name("v2")
    # or
    variables_to_restore = slim.get_variables_by_suffix("2")
    # or
    variables_to_restore = slim.get_variables(scope="nested")
    # or
    variables_to_restore = slim.get_variables_to_restore(include=["nested"])
    # or
    variables_to_restore = slim.get_variables_to_restore(exclude=["v1"])
    
    # Create the saver which will be used to restore the variables.
    restorer = tf.train.Saver(variables_to_restore)
    
    with tf.Session() as sess:
      # Restore variables from disk.
      restorer.restore(sess, "/tmp/model.ckpt")
      print("Model restored.")
      # Do some work with the model
      ...
    

    3)図の変数名とcheckpoint中の変数名が異なる場合、リカバリモデルパラメータcheckpointファイルから変数をリカバリすると、Saverはcheckpointファイルで変数名にナビゲートし、現在の図の変数にマッピングする.前の例では、Saverを作成し、パラメータとして変数リストを提供しました.このときcheckpointファイルに位置決め変数名は、パラメータとして与えられる変数毎に暗黙的にvar.opである.nameで得られた.この方式は、checkpointファイルの変数名と同時に、図がうまく機能します.名前が異なる場合は、checkpointファイルの変数名を図の各変数にマッピングする辞書をSaverに提供する必要があります.例は次のとおりです.
    # Assuming that 'conv1/weights' should be restored from 'vgg16/conv1/weights'
    def name_in_checkpoint(var):
      return 'vgg16/' + var.op.name
    
    # Assuming that 'conv1/weights' and 'conv1/bias' should be restored from 'conv1/params1' and 'conv1/params2'
    def name_in_checkpoint(var):
      if "weights" in var.op.name:
        return var.op.name.replace("weights", "params1")
      if "bias" in var.op.name:
        return var.op.name.replace("bias", "params2")
    
    variables_to_restore = slim.get_model_variables()
    variables_to_restore = {name_in_checkpoint(var):var for var in variables_to_restore}
    restorer = tf.train.Saver(variables_to_restore)
    
    with tf.Session() as sess:
      # Restore variables from disk.
      restorer.restore(sess, "/tmp/model.ckpt")
    (4)                
          1000  imagenet       20  Pascal VOC     ,        ,   :
    image, label = MyPascalVocDataLoader(...)
    images, labels = tf.train.batch([image, label], batch_size=32)
    
    # Create the model
    predictions = vgg.vgg_16(images)
    
    train_op = slim.learning.create_train_op(...)
    
    # Specify where the Model, trained on ImageNet, was saved.
    model_path = '/path/to/pre_trained_on_imagenet.checkpoint'
    
    # Specify where the new model will live:
    log_dir = '/path/to/my_pascal_model_dir/'
    
    # Restore only the convolutional layers:
    variables_to_restore = slim.get_variables_to_restore(exclude=['fc6', 'fc7', 'fc8'])
    init_fn = assign_from_checkpoint_fn(model_path, variables_to_restore)
    
    # Start training.
    slim.learning.train(train_op, log_dir, init_fn=init_fn)