2017-05-14 46 views
5

Tôi đang sử dụng tf.estimator.Estimator để đào tạo một mô hình:Dự đoán từ mô hình lưu với `tf.estimator.Estimator` trong Tensorflow

def model_fn(features, labels, mode, params, config): 

    input_image = features["input_image"] 

    eval_metric_ops = {} 
    predictions = {} 

    # Create model 
    with tf.name_scope('Model'): 

     W = tf.Variable(tf.zeros([784, 10]), name="W") 
     b = tf.Variable(tf.zeros([10]), name="b") 
     logits = tf.nn.softmax(tf.matmul(input_image, W, name="MATMUL") + b, name="logits") 

    loss = None 
    train_op = None 

    if mode != tf.estimator.ModeKeys.PREDICT: 
     loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=labels, logits=logits)) 
     train_op = tf.contrib.layers.optimize_loss(loss=loss, 
                 global_step=tf.contrib.framework.get_global_step(), 
                 learning_rate=params["learning_rate"], 
                 optimizer=params["optimizer"]) 
    # Add prediction 
    classes = tf.as_string(tf.argmax(input=logits, axis=1, name="class")) 
    with tf.name_scope('Predictions'): 
     predictions["logits"] = logits 
     predictions["classes"] = classes 

    export_outputs = {"classes": tf.estimator.export.ClassificationOutput(classes=classes)} 
    export_outputs = {"classes": tf.estimator.export.PredictOutput({"labels": classes})} 

    spec = tf.estimator.EstimatorSpec(mode=mode, 
             predictions=predictions, 
             loss=loss, 
             train_op=train_op, 
             eval_metric_ops=eval_metric_ops, 
             export_outputs=export_outputs, 
             training_chief_hooks=None, 
             training_hooks=None, 
             scaffold=None) 
    return spec 

def input_fn(dataset, n=10): 

    return dataset.images[:n], dataset.labels[:n] 


model_params = {"learning_rate": 1e-3, 
       "optimizer": "Adam"} 

#run_path = os.path.join(runs_path, datetime.now().strftime("%Y-%m-%d-%H-%M-%S")) 
run_path = os.path.join(runs_path, "run1") 
if os.path.exists(run_path): 
    shutil.rmtree(run_path) 

estimator = tf.estimator.Estimator(model_fn=model_fn, model_dir=run_path, params=model_params) 


# Train 
inputs = lambda: input_fn(mnist.train, n=15) 
estimator.train(input_fn=inputs, steps=1000) 

Model và trọng lượng được lưu một cách chính xác trong quá trình đào tạo.

Bây giờ tôi muốn tải lại mô hình + trọng số trong tập lệnh khác để tạo dự đoán.

Nhưng tôi không biết cách xác định đầu vào vì tôi không có tham chiếu đến nó trong hàm model_fn.

# Get some data to predict 
input_data = mnist.test.images[:5] 

tf.reset_default_graph() 
run_path = os.path.join(runs_path, "run1") 

# Load the model (graph) 
input_checkpoint = os.path.join(run_path, "model.ckpt-1000") 
saver = tf.train.import_meta_graph(input_checkpoint + '.meta', clear_devices=True) 

# Restore the weights 
sess = tf.InteractiveSession() 
saver.restore(sess, input_checkpoint) 
graph = sess.graph 

# Get the op to compute for prediction 
predict_op = graph.get_operation_by_name("Predictions/class") 

# predictions = sess.run(predict_op, feed_dict=????) 

Đây là những gì trả graph.get_collection("variables"):

[<tf.Variable 'global_step:0' shape=() dtype=int64_ref>, 
<tf.Variable 'Model/W:0' shape=(784, 10) dtype=float32_ref>, 
<tf.Variable 'Model/b:0' shape=(10,) dtype=float32_ref>, 
<tf.Variable 'OptimizeLoss/learning_rate:0' shape=() dtype=float32_ref>, 
<tf.Variable 'OptimizeLoss/beta1_power:0' shape=() dtype=float32_ref>, 
<tf.Variable 'OptimizeLoss/beta2_power:0' shape=() dtype=float32_ref>, 
<tf.Variable 'OptimizeLoss/Model/W/Adam:0' shape=(784, 10) dtype=float32_ref>, 
<tf.Variable 'OptimizeLoss/Model/W/Adam_1:0' shape=(784, 10) dtype=float32_ref>, 
<tf.Variable 'OptimizeLoss/Model/b/Adam:0' shape=(10,) dtype=float32_ref>, 
<tf.Variable 'OptimizeLoss/Model/b/Adam_1:0' shape=(10,) dtype=float32_ref>] 

Tôi có cần phải chỉ định một tf.placeholder cho đầu vào? Nhưng sau đó làm thế nào Tensorflow biết đầu vào nên nuôi giữ chỗ cụ thể này?

Ngoài ra nếu tôi chỉ định một cái gì đó như features = tf.constant(features, name="input") ở đầu mô hình, tôi không thể sử dụng nó vì nó không phải là một Tensor mà là một hoạt động.


EDIT

Sau khi điều tra nhiều hơn, tôi đã thấy rằng tôi cần phải lưu mô hình của tôi bằng cách sử dụng phương pháp Estimator.export_savedmodel() (và không tái sử dụng các trạm kiểm soát tự động lưu trong đào tạo với các ước lượng.

feature_spec = {"input_image": tf.placeholder(dtype=tf.float32, shape=[None, 784])} 

input_receiver_fn = tf.estimator.export.build_raw_serving_input_receiver_fn(feature_spec) 
estimator.export_savedmodel(model_path, input_receiver_fn, as_text=True) 

Sau đó, tôi đã cố gắng tải mô hình và thực hiện dự đoán nhưng tôi không biết cách nạp mô hình bằng hình ảnh gumpy của mình:

preds = sess.run("class", feed_dict={"input_image": input_data}) 

Và lỗi trừ:

/home/hadim/local/conda/envs/ws/lib/python3.6/site-packages/tensorflow/python/client/session.py in run(self, fetches, feed_dict, options, run_metadata) 
    776  try: 
    777  result = self._run(None, fetches, feed_dict, options_ptr, 
--> 778       run_metadata_ptr) 
    779  if run_metadata: 
    780   proto_data = tf_session.TF_GetBuffer(run_metadata_ptr) 

/home/hadim/local/conda/envs/ws/lib/python3.6/site-packages/tensorflow/python/client/session.py in _run(self, handle, fetches, feed_dict, options, run_metadata) 
    931   except Exception as e: 
    932    raise TypeError('Cannot interpret feed_dict key as Tensor: ' 
--> 933        + e.args[0]) 
    934 
    935   if isinstance(subfeed_val, ops.Tensor): 

TypeError: Cannot interpret feed_dict key as Tensor: The name 'input_image' looks like an (invalid) Operation name, not a Tensor. Tensor names must be of the form "<op_name>:<output_index>". 
+0

[Ví dụ về hàm export_savedmodel] (https://stackoverflow.com/a/48329456/4268517) –

Trả lời

1

Tên của tensor đầu vào của bạn có lẽ là input_image:0.

Bạn có thể liệt kê các chữ ký của mô hình đã lưu của bạn bằng cách gọi:

print(estimator.signature_def[tf.saved_model.signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY])

Điều đó sẽ liệt kê các tensors đầu vào/đầu ra dự kiến.

+0

'input_image: 0' không hoạt động và đối tượng' Ước tính 'không có thuộc tính' signature_def''. Tôi đang sử dụng TF 1.1.0. – HadiM

-1

Tôi đang làm việc với tf.contrib.learn.Estimator. Như tôi thấy, cú pháp và chữ ký của phương thức gần như giống nhau vì vậy tôi tin rằng sự khác biệt có liên quan đến một số phiên bản Tensorflow. Vì vậy, bạn có thể tạo Công cụ Ước tính như bình thường với một cái gì đó giống như

estimator = learn.Estimator(
     model_fn=your_model, 
     model_dir="tmp", 
     config=tf.contrib.learn.RunConfig(
      save_checkpoints_steps=10, 
      save_summary_steps=10, 
      save_checkpoints_secs=None 
     ) 
    ) 

Sau đó, bạn làm tàu ​​như estimator.fit(input_fn=input_function, steps=100)

Và sau đó bạn có thể làm những dự đoán gọi

estimator .predict(prediction) 

Mote, có một lừa, liên quan đến số known issue của Tensorflow.Gọi predict không đúng cách khởi tạo Công cụ Ước tính, vì vậy bạn cần phải gọi

estimator.evaluate(x=prediction, y=label_array, steps=1) 

trước khi gọi predict.

Hy vọng điều này sẽ hữu ích.

+3

Câu hỏi của tôi là về việc dự đoán từ một mô hình đã lưu trước đó trên đĩa. – HadiM

+0

Khi bạn tạo trình ước tính cung cấp "model_dir", mô hình được đào tạo của bạn được tải từ đĩa (thư mục được cung cấp trong tham số này). Vì vậy, bạn có thể đưa ra dự đoán sau đó. –

+0

Xin lỗi vì không rõ ràng nhưng ý tưởng của tôi là tải mô hình "bất kỳ" từ đĩa mà không có mã nguồn 'model_fn'. Nó dường như không thể như vậy. – HadiM

0

Đối với TypeError, tôi giải quyết nó theo cách này.

Thứ nhất, tên giữ chỗ:

feature_spec = {"input_image": tf.placeholder(dtype=tf.float32, shape=[None, 784], name='input_image')} 

Sau đó, bạn có thể sử dụng nó như thế này:

feed_dict={"input_image:0": input_data} 

Hy vọng nó có thể giúp ai đó.

Các vấn đề liên quan