6

(1) レイヤーを除くすべてのレイヤーに事前トレーニング済みの重みをロードすることにより、TFSlim を使用して VGG-16 ネットワークを微調整しようとしていますfc8。次のように TF-SLIm 関数を使用してこれを達成しました。

import tensorflow as tf
import tensorflow.contrib.slim as slim
import tensorflow.contrib.slim.nets as nets

vgg = nets.vgg

# Specify where the Model, trained on ImageNet, was saved.
model_path = 'path/to/vgg_16.ckpt'

# Specify where the new model will live:
log_dir = 'path/to/log/'

images = tf.placeholder(tf.float32, [None, 224, 224, 3])
predictions = vgg.vgg_16(images)

variables_to_restore = slim.get_variables_to_restore(exclude=['fc8'])
restorer = tf.train.Saver(variables_to_restore)




init = tf.initialize_all_variables()

with tf.Session() as sess:
   sess.run(init)
   restorer.restore(sess,model_path)
   print "model restored"

num_classesVGG16 モデルの を変更しない限り、これは正常に機能します。私がやりたいことは、num_classesを 1000 から 200 に変更することです。vgg16-modifiedを置き換える新しいクラスを定義してこの変更fc8を行うと、200 の出力を生成するようになるという印象を受けvariables_to_restore = slim.get_variables_to_restore(exclude=['fc8']) ました。 . ただし、テンソルフローは次元の不一致を訴えます:

InvalidArgumentError (see above for traceback): Assign requires shapes of both tensors to match. lhs shape= [1,1,4096,200] rhs shape= [1,1,4096,1000] 

では、実際にこれを行うにはどうすればよいでしょうか。TFSlim のドキュメントは本当に不完全で、いくつかのバージョンが Github に散在しているため、あまり役に立ちません。

4

1 に答える 1

10

スリムの復元方法を試すことができます — slim.assign_from_checkpoint.

スリム ソースに関連ドキュメントがあります: https://github.com/tensorflow/tensorflow/blob/129665119ea60640f7ed921f36db9b5c23455224/tensorflow/contrib/slim/python/slim/learning.py

対応部分:

*************************************************
* Fine-Tuning Part of a model from a checkpoint *
*************************************************
Rather than initializing all of the weights of a given model, we sometimes
only want to restore some of the weights from a checkpoint. To do this, one
need only filter those variables to initialize as follows:
  ...
  # Create the train_op
  train_op = slim.learning.create_train_op(total_loss, optimizer)
  checkpoint_path = '/path/to/old_model_checkpoint'
  # Specify the variables to restore via a list of inclusion or exclusion
  # patterns:
  variables_to_restore = slim.get_variables_to_restore(
      include=["conv"], exclude=["fc8", "fc9])
  # or
  variables_to_restore = slim.get_variables_to_restore(exclude=["conv"])
  init_assign_op, init_feed_dict = slim.assign_from_checkpoint(
      checkpoint_path, variables_to_restore)
  # Create an initial assignment function.
  def InitAssignFn(sess):
      sess.run(init_assign_op, init_feed_dict)
  # Run training.
  slim.learning.train(train_op, my_log_dir, init_fn=InitAssignFn)

アップデート

私は次のことを試しました:

import tensorflow as tf
import tensorflow.contrib.slim as slim
import tensorflow.contrib.slim.nets as nets
images = tf.placeholder(tf.float32, [None, 224, 224, 3])
predictions = nets.vgg.vgg_16(images)
print [v.name for v in slim.get_variables_to_restore(exclude=['fc8']) ]

そして、この出力を得ました(短縮):

[u'vgg_16/conv1/conv1_1/weights:0',
 u'vgg_16/conv1/conv1_1/biases:0',
 …
 u'vgg_16/fc6/weights:0',
 u'vgg_16/fc6/biases:0',
 u'vgg_16/fc7/weights:0',
 u'vgg_16/fc7/biases:0',
 u'vgg_16/fc8/weights:0',
 u'vgg_16/fc8/biases:0']

したがって、スコープにプレフィックスを付ける必要があるようですvgg_16

print [v.name for v in slim.get_variables_to_restore(exclude=['vgg_16/fc8']) ]

与えます(短縮):

[u'vgg_16/conv1/conv1_1/weights:0',
 u'vgg_16/conv1/conv1_1/biases:0',
 …
 u'vgg_16/fc6/weights:0',
 u'vgg_16/fc6/biases:0',
 u'vgg_16/fc7/weights:0',
 u'vgg_16/fc7/biases:0']

更新 2

エラーなしで実行される完全な例 (私のシステムで)。

import tensorflow as tf
import tensorflow.contrib.slim as slim
import tensorflow.contrib.slim.nets as nets

s = tf.Session(config=tf.ConfigProto(gpu_options={'allow_growth':True}))

images = tf.placeholder(tf.float32, [None, 224, 224, 3])
predictions = nets.vgg.vgg_16(images, 200)
variables_to_restore = slim.get_variables_to_restore(exclude=['vgg_16/fc8'])
init_assign_op, init_feed_dict = slim.assign_from_checkpoint('./vgg16.ckpt', variables_to_restore)
s.run(init_assign_op, init_feed_dict)

上記の例は、 1000 クラスの VGG16 モデルでvgg16.ckpt保存されたチェックポイントです。tf.train.Saver

200 クラス モデル ( fc8 を含む)のすべての変数でこのチェックポイントを使用すると、次のエラーが発生します。

init_assign_op, init_feed_dict = slim.assign_from_checkpoint('./vgg16.ckpt', slim.get_variables_to_restore())
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
      1 init_assign_op, init_feed_dict = slim.assign_from_checkpoint(
----> 2       './vgg16.ckpt', slim.get_variables_to_restore())

/usr/local/lib/python2.7/dist-packages/tensorflow/contrib/framework/python/ops/variables.pyc in assign_from_checkpoint(model_path, var_list)
    527     assign_ops.append(var.assign(placeholder_value))
    528
--> 529     feed_dict[placeholder_value] = var_value.reshape(var.get_shape())
    530
    531   assign_op = control_flow_ops.group(*assign_ops)

ValueError: total size of new array must be unchanged
于 2016-11-01T10:16:36.643 に答える