恢复使用tf.estimator训练的模型并通过feed_dict

时间:2018-02-08 07:13:10

标签: python tensorflow tensorflow-serving tensorflow-datasets tensorflow-estimator

我用tf.estimator训练了一个resnet,在训练过程中保存了模型。保存的文件包含.data.index.meta。我想加载这个模型并获得新图像的预测。使用tf.data.Dataset在训练期间将数据输入模型。我已经密切关注了here给出的resnet实现。

我想使用feed_dict恢复模型并将输入提供给节点。

首次尝试

  #rebuild input pipeline
  images, labels = input_fn(data_dir, batch_size=32, num_epochs=1)

  #rebuild graph
  prediction= imagenet_model_fn(images,labels,{'batch_size':32,'data_format':'channels_first','resnet_size':18},mode = tf.estimator.ModeKeys.EVAL).predictions 

  saver  = tf.train.Saver()
  with tf.Session() as sess:
    ckpt = tf.train.get_checkpoint_state(r'./model')
    saver.restore(sess, ckpt.model_checkpoint_path)
    while True:
    try:
        pred,im= sess.run([prediction,images])
        print(pred)
    except tf.errors.OutOfRangeError:
      break

我使用classifier.evaluate提供了在同一模型上评估的数据集,但上述方法给出了错误的预测。对于所有图像,模型给出相同的类和概率1.0。

第二次尝试

saver = tf.train.import_meta_graph(r'.\resnet\model\model-3220.meta')
sess = tf.Session()
saver.restore(sess,tf.train.latest_checkpoint(r'.\resnet\model'))
graph = tf.get_default_graph()
inputImage = graph.get_tensor_by_name('image:0')
logits= graph.get_tensor_by_name('logits:0')

#Get prediction
print(sess.run(logits,feed_dict={inputImage:newimage}))

classifier.evaluate相比,这也给出了错误的预测。我甚至可以在没有sess.run(logits)的情况下运行feed_dict

第三次尝试

def serving_input_fn():
  receiver_tensor = {'feature': tf.placeholder(shape=[None, 384, 256, 3], dtype=tf.float32)}
  features = {'feature': receiver_tensor['images']}
return tf.estimator.export.ServingInputReceiver(features, receiver_tensor)

失败了

Traceback (most recent call last):
  File "imagenet_main.py", line 213, in <module>
    tf.app.run(argv=[sys.argv[0]] + unparsed)
  File "C:\Users\Photogauge\Anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\platform\app.py", line 124, in run
    _sys.exit(main(argv))
  File "imagenet_main.py", line 204, in main
    resnet.resnet_main(FLAGS, imagenet_model_fn, input_fn)
  File "C:\Users\Photogauge\Desktop\iprings_images\models-master\models-master\official\resnet\resnet.py", line 527, in resnet_main
    classifier.export_savedmodel(export_dir_base=r"C:\Users\Photogauge\Desktop\iprings_images\models-master\models-master\official\resnet\export", serving_input_receiver_fn=serving_input_fn)
  File "C:\Users\Photogauge\Anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\estimator\estimator.py", line 528, in export_savedmodel
    config=self.config)
  File "C:\Users\Photogauge\Anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\estimator\estimator.py", line 725, in _call_model_fn
    model_fn_results = self._model_fn(features=features, **kwargs)
  File "imagenet_main.py", line 200, in imagenet_model_fn
    loss_filter_fn=None)
  File "C:\Users\Photogauge\Desktop\iprings_images\models-master\models-master\official\resnet\resnet.py", line 433, in resnet_model_fn
    tf.argmax(labels, axis=1), predictions['classes'])
  File "C:\Users\Photogauge\Anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\util\deprecation.py", line 316, in new_func
    return func(*args, **kwargs)
  File "C:\Users\Photogauge\Anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\ops\math_ops.py", line 208, in argmax
    return gen_math_ops.arg_max(input, axis, name=name, output_type=output_type)
  File "C:\Users\Photogauge\Anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\ops\gen_math_ops.py", line 508, in arg_max
    name=name)
  File "C:\Users\Photogauge\Anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\framework\op_def_library.py", line 528, in _apply_op_helper
    (input_name, err))
ValueError: Tried to convert 'input' to a tensor and failed. Error: None values not supported.

我用于培训和构建模型的代码如下:

解析数据集的规范:

def parse_record(raw_record, is_training):
  keys_to_features = {
      'image/encoded':
          tf.FixedLenFeature((), tf.string, default_value=''),
      'image/class/label':
          tf.FixedLenFeature([], dtype=tf.int64, default_value=-1),
  }
  parsed = tf.parse_single_example(raw_record, keys_to_features)
  image = tf.image.decode_image(
      tf.reshape(parsed['image/encoded'], shape=[]),3)
  image = tf.image.convert_image_dtype(image, dtype=tf.float32)
  label = tf.cast(
      tf.reshape(parsed['image/class/label'], shape=[]),
      dtype=tf.int32)
  return image, tf.one_hot(label,2)

以下函数解析数据并创建培训批次

def input_fn(is_training, data_dir, batch_size, num_epochs=1):
  dataset = tf.data.Dataset.from_tensor_slices(
      filenames(is_training, data_dir))
  if is_training:
     dataset = dataset.shuffle(buffer_size=_FILE_SHUFFLE_BUFFER)
  dataset = dataset.flat_map(tf.data.TFRecordDataset)
  dataset = dataset.map(lambda value: parse_record(value, is_training),
                        num_parallel_calls=5)
  dataset = dataset.prefetch(batch_size)
  if is_training:
      dataset = dataset.shuffle(buffer_size=_SHUFFLE_BUFFER)
  dataset = dataset.repeat(num_epochs)
  dataset = dataset.batch(batch_size)

  iterator = dataset.make_one_shot_iterator()
  images, labels = iterator.get_next()
  return images, labels

如下所示创建分类器,用于训练集和验证集评估

classifier = tf.estimator.Estimator(
      model_fn=model_function, model_dir=flags.model_dir, config=run_config,
      params={
          'resnet_size': flags.resnet_size,
          'data_format': flags.data_format,
          'batch_size': flags.batch_size,
      })

    #Training cycle
     classifier.train(
         input_fn=lambda: input_function(
             training_phase=True, flags.data_dir, flags.batch_size, flags.epochs_per_eval),
         hooks=[logging_hook])
    # Evaluate the model 
    eval_results = classifier.evaluate(input_fn=lambda: input_function(
        training_phase=False, flags.data_dir, flags.batch_size))

这就是我尝试从模型中加载和获取预测的方法。

恢复已保存模型并对其进行推理的正确方法是什么。我想直接提供图片而不使用tf.data.Dataset

更新

  1. ckpt的值是在ckpt = tf.train.get_checkpoint_state(r'./model')运行

    之后

    model_checkpoint_path:&#34; ./ model \ model.ckpt-5980&#34; all_model_checkpoint_paths:&#34; ./ model \ model.ckpt-5060&#34; all_model_checkpoint_paths:&#34; ./ model \ model.ckpt-5061&#34; all_model_checkpoint_paths:&#34; ./ model \ model.ckpt-5520&#34; all_model_checkpoint_paths:&#34; ./ model \ model.ckpt-5521&#34; all_model_checkpoint_paths:&#34; ./ model \ model.ckpt-5980&#34;

  2. 当我尝试`saver.restore时,输出相同(sess,tf.train.latest_checkpoint(r&#39;。\ resnet \ model&#39;))

  3. 传递到saver.restore的完整路径会产生相同的输出 在所有情况下,同一模型model.ckpt-5980已恢复

2 个答案:

答案 0 :(得分:0)

注意:只要有更多信息,这个答案就会发生变化。我不确定这是最合适的方式,但感觉比仅使用评论更好。如果这是不合适的话,请随意对答案发表评论。

关于你的第二次尝试:

我对import_meta_graph方法没有多少经验,但如果sess.run(logits)没有抱怨,我认为元图也包含您的输入管道。

我刚刚进行的快速测试确认在加载元图时管道确实已经恢复。这意味着,您实际上并未通过feed_dict传递任何内容,因为输入来自检查点获取时使用的基于Dataset的管道。根据我的研究,我无法找到为图表提供不同输入功能的方法。

关于第一次尝试:

你的代码看起来对我来说,所以我怀疑加载的检查点文件是不正确的。我在评论中提出了一些澄清,我会在信息可用后立即更新此部分

答案 1 :(得分:0)

如果您有模型pb或pb.txt,那么推理很容易。使用预测模块,我们可以进行推理。有关详细信息,请查看here。对于图像数据,它将类似于下面的示例。希望这会有所帮助!!

示例代码:

import numpy as np
import matplotlib.pyplot as plt

def extract_data(index=0, filepath='data/cifar-10-batches-bin/data_batch_5.bin'):
    bytestream = open(filepath, mode='rb')
    label_bytes_length = 1
    image_bytes_length = (32 ** 2) * 3
    record_bytes_length = label_bytes_length + image_bytes_length
    bytestream.seek(record_bytes_length * index, 0)
    label_bytes = bytestream.read(label_bytes_length)
    image_bytes = bytestream.read(image_bytes_length)
    label = np.frombuffer(label_bytes, dtype=np.uint8)  
    image = np.frombuffer(image_bytes, dtype=np.uint8)
    image = np.reshape(image, [3, 32, 32])
    image = np.transpose(image, [1, 2, 0])
    image = image.astype(np.float32)
   result = {
     'image': image,
     'label': label,
   }
   bytestream.close()
   return result


    predictor_fn = tf.contrib.predictor.from_saved_model(
  export_dir = saved_model_dir, signature_def_key='predictions')
    N = 1000
    labels = []
    images = []
    for i in range(N):
       result = extract_data(i)
       images.append(result['image'])
       labels.append(result['label'][0])
    output = predictor_fn(
      {
        'images': images,
      }
    )