在tensorflow.rb上运行已保存的模型

Wiw*_*web 6 ruby tensorflow

我使用高级Estimator API(DNNClassifier)在Python中构建并保存了一个非常简单的模型.它需要2个浮点数并输出两个类别中的一个.我正在尝试使用tensorflow.rb gem在Ruby中加载它,并使用它进行预测.这应该与tensorflow.rb提供的CAPTCHA示例非常相似.

我用它保存了它export_saved_model.以下是训练模型的Python代码.它可以正确预测类.

将numpy导入为np import pandas as pd import tensorflow as tf

dataframe = pd.read_csv("remediations_import.csv", sep=",")
dataframe = dataframe.reindex(
    np.random.permutation(dataframe.index))

STEPS = 5000
BATCH_SIZE = 10
SAVED_MODEL_FOLDER = 'saved_model'
FEATURE_1 = 'Float_input_1'
FEATURE_2 = 'Float_input_2'
LABEL = "Human_label"

my_feature_data = dataframe[[FEATURE_1, FEATURE_2]]
targets = dataframe[LABEL]

feature_columns = [tf.feature_column.numeric_column(FEATURE_1),
                   tf.feature_column.numeric_column(FEATURE_2)]

features = {key: np.array(value) for key, value in dict(my_feature_data).items()}
training_input_fn = tf.estimator.inputs.numpy_input_fn(x=features,
                                                       y=targets.as_matrix(),
                                                       batch_size=BATCH_SIZE,
                                                       shuffle=True)

classifier = tf.estimator.DNNClassifier(
    feature_columns=feature_columns,
    hidden_units=[10, 10],
    n_classes=2,
    model_dir=SAVED_MODEL_FOLDER)

classifier.train(
    input_fn=training_input_fn,
    steps=STEPS
)

print("Model training finished.")

# Save the model under pb format
features = {'Float_input_1': tf.placeholder(tf.float32, shape=[1]),
            'Float_input_2': tf.placeholder(tf.float32, shape=[1])}
serving_input_receiver_fn = tf.estimator.export.build_raw_serving_input_receiver_fn(features,
                                                                                    default_batch_size=None)
classifier.export_savedmodel(SAVED_MODEL_FOLDER + '_pb', serving_input_receiver_fn, strip_default_attrs=True)

# Predict
new_features = pd.DataFrame({FEATURE_1: [0.97, 0.03], FEATURE_2: [1.00, -1.00]})
# Convert pandas data into a dict of numpy arrays.
features = {key: np.array(value) for key, value in dict(new_features).items()}
prediction_input_fn = tf.estimator.inputs.numpy_input_fn(x=features,
                                                         num_epochs=1,
                                                         shuffle=False)

predictions_results = classifier.predict(input_fn=prediction_input_fn)
predictions = np.array([item['class_ids'][0] for item in predictions_results])
print(predictions)
Run Code Online (Sandbox Code Playgroud)

使用以下方式查看我保存的模型saved_model_cli:

MetaGraphDef with tag-set: 'serve' contains the following SignatureDefs:

signature_def['predict']:
  The given SavedModel SignatureDef contains the following input(s):
    inputs['Float_input_1'] tensor_info:
        dtype: DT_FLOAT
        shape: (-1)
        name: Placeholder:0
    inputs['Float_input_2'] tensor_info:
        dtype: DT_FLOAT
        shape: (-1)
        name: Placeholder_1:0
  The given SavedModel SignatureDef contains the following output(s):
    outputs['class_ids'] tensor_info:
        dtype: DT_INT64
        shape: (-1, 1)
        name: dnn/head/predictions/ExpandDims:0
    outputs['classes'] tensor_info:
        dtype: DT_STRING
        shape: (-1, 1)
        name: dnn/head/predictions/str_classes:0
    outputs['logistic'] tensor_info:
        dtype: DT_FLOAT
        shape: (-1, 1)
        name: dnn/head/predictions/logistic:0
    outputs['logits'] tensor_info:
        dtype: DT_FLOAT
        shape: (-1, 1)
        name: dnn/logits/BiasAdd:0
    outputs['probabilities'] tensor_info:
        dtype: DT_FLOAT
        shape: (-1, 2)
        name: dnn/head/predictions/probabilities:0
  Method name is: tensorflow/serving/predict
Run Code Online (Sandbox Code Playgroud)

我的tensorflow.rb Ruby代码得到一个预测:

saved_model = Tensorflow::Savedmodel.new
saved_model.LoadSavedModel('saved_model_pb', ['serve'], nil)

input = [0.97, 1.00]
feature1_output = saved_model.graph.operation('Placeholder').output(0)
feature2_output = 
saved_model.graph.operation('Placeholder_1').output(0)
classes = saved_model.graph.operation('dnn/head/predictions/str_classes').output(0)
# probabilities = saved_model.graph.operation('dnn/head/predictions/probabilities').output(0)

feature1_tensor = Tensorflow::Tensor.new(input[0])
feature2_tensor = Tensorflow::Tensor.new(input[1])
feeds_tensor_to_output_hash = {feature1_output => feature1_tensor,
                               feature2_output => feature2_tensor}
out_tensor = saved_model.session.run(feeds_tensor_to_output_hash, [classes], [])

puts out_tensor
Run Code Online (Sandbox Code Playgroud)

这失败了ArgumentError没有错误消息:

2018-05-22 17:07:08.443115: I tensorflow/cc/saved_model/loader.cc:242] Loading SavedModel with tags: { serve }; from: saved_model_pb/saved_model
2018-05-22 17:07:08.447053: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: SSE4.2 AVX AVX2 FMA
2018-05-22 17:07:08.452575: I tensorflow/cc/saved_model/loader.cc:161] Restoring SavedModel bundle.
2018-05-22 17:07:08.453012: I tensorflow/cc/saved_model/loader.cc:171] The specified SavedModel has no variables; no checkpoints were restored.
2018-05-22 17:07:08.453024: I tensorflow/cc/saved_model/loader.cc:196] Running LegacyInitOp on SavedModel bundle.
2018-05-22 17:07:08.475575: I tensorflow/cc/saved_model/loader.cc:291] SavedModel load for tags { serve }; Status: success. Took 33095 microseconds.
rake aborted!
ArgumentError: 
.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/bundler/gems/tensorflow.rb-eb3f5bf4f0fd/lib/tensorflow/session.rb:57:in `Session_run'
.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/bundler/gems/tensorflow.rb-eb3f5bf4f0fd/lib/tensorflow/session.rb:57:in `run'
lib/tasks/ml.rake:380:in `block (2 levels) in <top (required)>'
Run Code Online (Sandbox Code Playgroud)

知道我做错了什么吗?CAPTCHA示例和模型工作正常.我的模型是否正确保存?这是我使用的保存模型.

Wiw*_*web 1

事实证明这是类型不匹配。我保存模型以接受 float32 变量。tensorflow.rb 从 Ruby 的 float 类型(即 float64)创建输入张量。

改变这个:

# Save the model under pb format
features = {'Float_input_1': tf.placeholder(tf.float32, shape=[1]),
            'Float_input_2': tf.placeholder(tf.float32, shape=[1])}
Run Code Online (Sandbox Code Playgroud)

对此:

# Save the model under pb format
features = {'Float_input_1': tf.placeholder(tf.float64, shape=[1]),
            'Float_input_2': tf.placeholder(tf.float64, shape=[1])}
Run Code Online (Sandbox Code Playgroud)

解决了这个问题。