2017-05-14 26 views
5

Używam tf.estimator.Estimator trenować model:Info od modelu zapisywane `tf.estimator.Estimator` w 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) 

modelu i wagi są poprawnie zapisane podczas treningu.

Teraz chcę przeładować model + wagi w innym skrypcie, aby tworzyć prognozy.

Ale nie wiem, jak określić wejście, ponieważ nie mam odniesienia do niego w funkcji 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=????) 

Oto co zwraca 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>] 

Czy muszę podać tf.placeholder dla wejścia? Ale w jaki sposób Tensorflow wie, że dane wejściowe powinny zawierać ten konkretny symbol zastępczy?

Również jeśli podam na początku modelu coś w rodzaju features = tf.constant(features, name="input"), nie mogę go użyć, ponieważ nie jest to Tensor, ale Operacja.


EDIT

Po więcej dochodzenia, znalazłem, że muszę zapisać mój model stosując metodę Estimator.export_savedmodel() (a nie ponownie przy użyciu automatycznie zapisane punkty kontrolne podczas treningu z estymatora.

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) 

Potem próbował załadować model i zrobić prognozy, ale nie wiem, jak karmić model z moich numPy obrazów:

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

I z wyjątkiem błędu:

/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

[Przykład funkcji export_savedmodel] (https://stackoverflow.com/a/48329456/4268517) –

Odpowiedz

1

Nazwa Twojego Tensor wejściowego prawdopodobnie jest input_image:0.

Można wymienić podpisanie zapisanego modelu dzwoniąc:

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

To powinno listy oczekiwanych tensory wejścia/wyjścia.

+0

'input_image: 0' nie działa, a obiekt' 'Estimator' nie ma atrybutu 'signature_def''. Używam TF 1.1.0. – HadiM

-1

Pracuję z tf.contrib.learn.Estimator. Jak widzę, sygnatury składni i metody są prawie takie same, więc uważam, że różnice są związane z kilkoma wersjami Tensorflow. dzięki czemu można tworzyć prognozy jak zwykle z czymś

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 
     ) 
    ) 

Potem robisz pociągu jak estimator.fit(input_fn=input_function, steps=100)

a następnie można wykonać prognozy wzywającą

estimator .predict(prediction) 

Mote, istnieje podstęp, związany z Tensorflowem known issue.Wywołanie predict nie została właściwie zainicjowana prognozy, więc trzeba zadzwonić

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

przed wywołaniem predict.

Hope, to pomaga.

+3

Moje pytanie dotyczyło przewidywania z wcześniej zapisanego modelu na dysku. – HadiM

+0

Po utworzeniu estymatora zawierającego "katalog_modelowy", wyszkolony model jest ładowany z dysku (katalog udostępniony w tym parametrze). Możesz więc dokonać prognozy. –

+0

Przepraszamy za to, że nie jest jasne, ale moim pomysłem było załadowanie "dowolnego" modelu z dysku bez kodu źródłowego "model_fn". Nie wydaje się to możliwe w ten sposób. – HadiM

0

Co do TypeError, rozwiązuję go w ten sposób.

pierwsze, nazwa zastępczy:

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

Wtedy można go używać tak:

feed_dict={"input_image:0": input_data} 

Nadzieję, że może komuś pomóc.

Powiązane problemy