人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新)
在部署模型时,我们的第一步往往是将训练好的整个模型完整导出为一系列标准格式的文件,然后即可在不同的平台上部署模型文件。这时,TensorFlow 为我们提供了 SavedModel 这一格式。
除了CheckPointTensorFlow还会有其他格式,这里做统一介绍:部署在线服务(Serving)时官方推荐使用 SavedModel 格式,而部署到手机等移动端的模型一般使用 FrozenGraphDef 格式(最近推出的 TensorFlow Lite 也有专门的轻量级模型格式 *.lite,和 FrozenGraphDef 十分类似)。这些格式之间关系密切,可以使用 TensorFlow 提供的 API 来互相转换。下面简单介绍几种格式:
2、*.pb
3、SavedModel
使用下面的代码即可将模型导出为 SavedModel:
tf.saved_model.save(model, "保存的目标文件夹名称")
在需要载入 SavedModel 文件时,使用即可
model = tf.saved_model.load("保存的目标文件夹名称")
1、将之前CIFAE100分类模型进行导出和导入,导出模型到 saved/mlp/1
文件夹中,mlp可以自己指定的一个模型名称,1为版本号,必须提供,后面开启服务需要有版本号
import tensorflow as tf
import os
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2"def main():num_epochs = 1batch_size = 32learning_rate = 0.001model = tf.keras.models.Sequential([tf.keras.layers.Flatten(),tf.keras.layers.Dense(120, activation=tf.nn.relu),tf.keras.layers.Dense(100),tf.keras.layers.Softmax()])(train, train_label), (test, test_label) = \tf.keras.datasets.cifar100.load_data()model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=learning_rate),loss=tf.keras.losses.sparse_categorical_crossentropy,metrics=[tf.keras.metrics.sparse_categorical_accuracy])model.fit(train, train_label, epochs=num_epochs, batch_size=batch_size)tf.saved_model.save(model, "./saved/mlp/1")
2、并且模型加载出来,测试性能就能够
def test():model = tf.saved_model.load("./saved/mlp/1")sparse_categorical_accuracy = tf.keras.metrics.SparseCategoricalAccuracy()(train, train_label), (test, test_label) = \tf.keras.datasets.cifar100.load_data()y_pred = model(test)sparse_categorical_accuracy.update_state(y_true=test_label,y_pred=y_pred)print("test accuracy: %f" % sparse_categorical_accuracy.result())
输出结果
test accuracy: 0.010000
3、自定义的keras模型使用:
使用继承 tf.keras.Model
类建立的 Keras 模型同样可以以相同方法导出,唯须注意 call
方法需要以 @tf.function
修饰,以转化为 SavedModel 支持的计算图,代码如下:
def __init__(self):super().__init__()self.flatten = tf.keras.layers.Flatten()self.dense1 = tf.keras.layers.Dense(units=100, activation=tf.nn.relu)self.dense2 = tf.keras.layers.Dense(units=10)@tf.functiondef call(self, inputs): # [batch_size, 28, 28, 1]x = self.flatten(inputs) # [batch_size, 784]x = self.dense1(x) # [batch_size, 100]x = self.dense2(x) # [batch_size, 10]output = tf.nn.softmax(x)return outputmodel = MLP()
TensorFlow Serving是一种灵活的高性能服务系统,适用于机器学习模型,专为生产环境而设计。TensorFlow Serving可以轻松部署新算法和实验,同时保持相同的服务器架构和API。TensorFlow Serving提供与TensorFlow模型的开箱即用集成,但可以轻松扩展以提供其他类型的模型和数据。
特点:TensorFlow Serving 支持热更新模型,其典型的模型文件夹结构如下:
/saved_model_files/1 # 版本号为1的模型文件/assets/variablessaved_model.pb.../N # 版本号为N的模型文件/assets/variablessaved_model.pb
上面 1~N 的子文件夹代表不同版本号的模型。当指定 --model_base_path
时,只需要指定根目录的 绝对地址 (不是相对地址)即可。例如,如果上述文件夹结构存放在 home/snowkylin
文件夹内,则 --model_base_path
应当设置为 home/snowkylin/saved_model_files
(不附带模型版本号)。TensorFlow Serving 会自动选择版本号最大的模型进行载入。
4.11.3.1 安装Tensorflow Serving
安装过程详细参考官网
https://www.tensorflow.org/serving/setup
TensorFlow Serving 可以使用 apt-get 或 Docker 安装。在生产环境中,推荐 使用 Docker 部署 TensorFlow Serving 。
4.11.3.2 TensorFlow Serving Docker 使用介绍
获取最新TF Serving docker镜像
docker pull tensorflow/serving
查看docker镜像
docker images
运行tf serving(即创建一个docker容器来运行)
docker run -p 8501:8501 -p 8500:8500 --mount type=bind,source=/home/ubuntu/detectedmodel/commodity,target=/models/commodity -e MODEL_NAME=commodity -t tensorflow/serving
说明:
-p 8501:8501
为端口映射,-p 主机端口:docker容器程序(tf serving)使用端口
,访问主机8501端口就相当于访问了tf serving程序的8501端口--mount type=bind,source=/home/ubuntu/detectedmodel/commodity,target=/models/commodity
为文件映射,将主机(source)的模型文件映射到docker容器程序(target)的位置,以便tf serving使用模型,target
参数为/models/我的模型
-e MODEL_NAME=commodity
设置了一个环境变量,名为MODEL_NAME
,此变量被tf serving读取,用来按名字寻找模型,与上面target参数中我的模型
对应-t
为tf serving创建一个伪终端,供程序运行tensorflow/serving
为镜像名常见docker命令:
docker ps:查看正在运行的容器
docker images:查看已下载的景象
docker stop 8779b492e4aa:停止正在运行的ID为8779b492e4aa的容器,IP可以通过docker ps查看
4.11.3.3 案例操作:commodity模型服务运行
docker run -p 8501:8501 -p 8500:8500 --mount type=bind,source=/root/cv_project/tf_example
/saved/mlp,target=/models/mlp -e MODEL_NAME=mlp -t tensorflow/serving &
itcast:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS POR
TS NAMES
1354f9aeab33 tensorflow/serving "/usr/bin/tf_serving…" 7 seconds ago Up 5 seconds 0.0
.0.0:8500-8501->8500-8501/tcp gifted_jackson
TensorFlow Serving 支持以 gRPC 和 RESTful API 调用以 TensorFlow Serving 部署的模型。RESTful API 以标准的 HTTP POST 方法进行交互,请求和回复均为 JSON 对象。为了调用服务器端的模型,我们在客户端向服务器发送以下格式的请求:服务器 URI: http://服务器地址:端口号/v1/models/模型名:predict
请求内容:
{"signature_name": "需要调用的函数签名(Sequential模式不需要)","instances": 输入数据
}
回复为:
{"predictions": 返回值
}
4.11.5.1 直接使用curl
运行下面命令
curl -d '{"instances": [image_data]}' \-X POST http://localhost:8501/v1/models/mlp:predict
4.11.5.2 编写客户端代码
示例使用Python 的 Requests 库(你可能需要使用 pip install requests
安装该库)向本机的 TensorFlow Serving 服务器发送20张图像并返回预测结果,同时与测试集的真实标签进行比较。
def client():import jsonimport numpy as npimport requests(_, _), (test, test_label) = \tf.keras.datasets.cifar100.load_data()data = json.dumps({"instances": test[0:20].tolist() # array转换成列表形式})headers = {"content-type": "application/json"}json_response = requests.post('http://localhost:8501/v1/models/mlp:predict',data=data, headers=headers)predictions = np.array(json.loads(json_response.text)['predictions'])print(np.argmax(predictions, axis=-1))print(test_label[0:20])if __name__ == '__main__':# main()# test()client()
输出:
[67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67]
[[49][33][72][51][71][92][15][14][23][ 0][71][75][81][69][40][43][92][97][70][53]]
因为模型并没有训练多久,只迭代一次,所以效果不好,主要是完成整个流程。
import tensorflow as tf
import os
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2"def main():num_epochs = 1batch_size = 32learning_rate = 0.001model = tf.keras.models.Sequential([tf.keras.layers.Flatten(),tf.keras.layers.Dense(120, activation=tf.nn.relu),tf.keras.layers.Dense(100),tf.keras.layers.Softmax()])(train, train_label), (test, test_label) = \tf.keras.datasets.cifar100.load_data()model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=learning_rate),loss=tf.keras.losses.sparse_categorical_crossentropy,metrics=[tf.keras.metrics.sparse_categorical_accuracy])model.fit(train, train_label, epochs=num_epochs, batch_size=batch_size)tf.saved_model.save(model, "./saved/mlp/2")def test():model = tf.saved_model.load("./saved/mlp/2")(_, _), (test, test_label) = \tf.keras.datasets.cifar100.load_data()y_predict = model(test)sparse_categorical_accuracy = tf.keras.metrics.SparseCategoricalAccuracy()sparse_categorical_accuracy.update_state(y_true=test_label, y_pred=y_predict)print("测试集的准确率为: %f" % sparse_categorical_accuracy.result())def client():import jsonimport numpy as npimport requests(_, _), (test, test_label) = \tf.keras.datasets.cifar100.load_data()# 1、构造好请求data = json.dumps({"instances": test[:10].tolist()})headers = {"content-type": "application/json"}json_response = requests.post('http://localhost:8501/v1/models/mlp:predict',data=data, headers=headers)predictions = np.array(json.loads(json_response.text)['predictions'])print(predictions)print(np.argmax(predictions, axis=-1))print(test_label[:10])if __name__ == '__main__':"""TensorFlow 模型导出"""main()test()"""TensorFlow Serving"""# client()
构建深度学习模型时,需要选择各种超参数,例如模型中的学习率,优化器,神经元个数等。这些决策会影响模型指标,例如准确性。因此,工作流程中的一个重要步骤是为您的问题确定最佳的超参数,这通常涉及实验。此过程称为“超参数优化”或“超参数调整”。TensorBoard中的HParams仪表板提供了多种工具,帮助确定最佳实验或最有希望的超参数集。
注:Note: The HParams summary APIs and dashboard UI are in a preview stage and will change over time.
使用导入
from tensorboard.plugins.hparams import api as hp
4.11.5.1 案例:CIFAR100分类模型添加参数进行调优
1、设置HParams 实验参数
HP_NUM_UNITS = hp.HParam('num_units', hp.Discrete([1024, 512]))
HP_DROPOUT = hp.HParam('dropout', hp.RealInterval(0.2, 0.3))
HP_OPTIMIZER = hp.HParam('optimizer', hp.Discrete(['adam', 'sgd']))
2、将试验参数添加到模型指定结构当中,或者编译训练的过程参数中
def train_test_model(self, hparams):"""训练验证模型:return:"""# 1、定义模型中加入了一个dropoutmodel = tf.keras.Sequential([tf.keras.layers.Conv2D(32, kernel_size=5, strides=1, padding='same', activation=tf.nn.relu),tf.keras.layers.MaxPool2D(pool_size=2, strides=2),tf.keras.layers.Conv2D(64, kernel_size=5, strides=1, padding='same', activation=tf.nn.relu),tf.keras.layers.MaxPool2D(pool_size=2, strides=2),tf.keras.layers.Flatten(),tf.keras.layers.Dense(hparams[HP_NUM_UNITS], activation=tf.nn.relu),tf.keras.layers.Dropout(hparams[HP_DROPOUT]),tf.keras.layers.Dense(100, activation=tf.nn.softmax)])# 2、模型设置以及训练model.compile(optimizer=hparams[HP_OPTIMIZER],loss=tf.keras.losses.sparse_categorical_crossentropy,metrics=['accuracy'])tensorboard = tf.keras.callbacks.TensorBoard(log_dir='./graph', histogram_freq=1,write_graph=True, write_images=True)# 添加记录hparams的回调hp.KerasCallback('./graph/', hparams)model.fit(self.train, self.train_label,epochs=1, batch_size=32,callbacks=[tensorboard, hp.KerasCallback('./logs/hparam_tuning/', hparams)],validation_data=(self.test, self.test_label))return None
3、使用超参数调优方法对不同的超参数集训练每个实验组合
使用网格搜索:尝试使用离散参数的所有组合或者连续型值参数的上限和下限。对于更复杂的场景,随机选择每个超参数值会更有效(随机搜索)。
def hyper_parameter(self):"""超参数调优:return:"""session_num = 0for num_units in HP_NUM_UNITS.domain.values:for dropout_rate in (HP_DROPOUT.domain.min_value, HP_DROPOUT.domain.max_value):for optimizer in HP_OPTIMIZER.domain.values:hparams = {HP_NUM_UNITS: num_units,HP_DROPOUT: dropout_rate,HP_OPTIMIZER: optimizer,}print('--- 开始 实验: %s' % session_num)print({h.name: hparams[h] for h in hparams})self.train_test_model(hparams)session_num += 1return None
注:其中如果对于连续的值比如说你的模型中learning_rate,假设设置0.0001~0.1,可以这样迭代使用
for lr_tate in tf.linspace(HP_LR.domain.min_value,HP_LR.domain.max_value,res):
最终打印效果为:
--- 开始 实验: 0
{'num_units': 512, 'dropout': 0.2, 'optimizer': 'adam'}
Train on 50000 samples, validate on 10000 samples
Epoch 1/232/50000 [..............................] - ETA: 21:58 - loss: 4.6257 - accuracy: 0.0000e+002020-03-22 05:02:24.239954: E
50000/50000 [==============================] - 61s 1ms/sample - loss: 3.6983 - accuracy: 0.1391 - val_loss: 3.1219 - val_accuracy: 0.2460
Epoch 2/2
50000/50000 [==============================] - 60s 1ms/sample - loss: 2.9337 - accuracy: 0.2777 - val_loss: 2.7689 - val_accuracy: 0.3094
--- 开始 实验: 1
{'num_units': 512, 'dropout': 0.2, 'optimizer': 'sgd'}
Train on 50000 samples, validate on 10000 samples
Epoch 1/232/50000 [..............................] - ETA: 9:12 - loss: 4.5919 - accuracy: 0.0000e+002020-03-22 05:04:26.409071: E
50000/50000 [==============================] - 55s 1ms/sample - loss: 4.3805 - accuracy: 0.0404 - val_loss: 4.1078 - val_accuracy: 0.0641
Epoch 2/2
50000/50000 [==============================] - 55s 1ms/sample - loss: 3.9086 - accuracy: 0.1072 - val_loss: 3.7098 - val_accuracy: 0.1479
--- 开始 实验: 2
{'num_units': 512, 'dropout': 0.3, 'optimizer': 'adam'}
Train on 50000 samples, validate on 10000 samples
Epoch 1/232/50000 [..............................] - ETA: 11:06 - loss: 4.6464 - accuracy: 0.03122020-03-22 05:06:18.355198: E
50000/50000 [==============================] - 61s 1ms/sample - loss: 3.7051 - accuracy: 0.1400 - val_loss: 3.1361 - val_accuracy: 0.2422
Epoch 2/2
50000/50000 [==============================] - 60s 1ms/sample - loss: 2.9754 - accuracy: 0.2687 - val_loss: 2.7621 - val_accuracy: 0.3118
--- 开始 实验: 3
{'num_units': 512, 'dropout': 0.3, 'optimizer': 'sgd'}
Train on 50000 samples, validate on 10000 samples
Epoch 1/232/50000 [..............................] - ETA: 9:03 - loss: 4.5909 - accuracy: 0.0000e+002020-03-22 05:08:20.864262: E
50000/50000 [==============================] - 55s 1ms/sample - loss: 4.3802 - accuracy: 0.0399 - val_loss: 4.0482 - val_accuracy: 0.0807
Epoch 2/2
50000/50000 [==============================] - 55s 1ms/sample - loss: 3.9227 - accuracy: 0.1036 - val_loss: 3.7022 - val_accuracy: 0.1423
--- 开始 实验: 4
{'num_units': 1024, 'dropout': 0.2, 'optimizer': 'adam'}
Train on 50000 samples, validate on 10000 samples
Epoch 1/232/50000 [..............................] - ETA: 11:28 - loss: 4.6099 - accuracy: 0.0000e+002020-03-22 05:10:12.802252: E
50000/50000 [==============================] - 78s 2ms/sample - loss: 3.5546 - accuracy: 0.1683 - val_loss: 3.0440 - val_accuracy: 0.2580
Epoch 2/2
50000/50000 [==============================] - 77s 2ms/sample - loss: 2.7925 - accuracy: 0.3048 - val_loss: 2.7049 - val_accuracy: 0.3255
--- 开始 实验: 5
{'num_units': 1024, 'dropout': 0.2, 'optimizer': 'sgd'}
Train on 50000 samples, validate on 10000 samples
Epoch 1/232/50000 [..............................] - ETA: 9:22 - loss: 4.5938 - accuracy: 0.0000e+002020-03-22 05:12:50.161457: E
50000/50000 [==============================] - 68s 1ms/sample - loss: 4.3278 - accuracy: 0.0477 - val_loss: 3.9872 - val_accuracy: 0.0849
Epoch 2/2
50000/50000 [==============================] - 67s 1ms/sample - loss: 3.8071 - accuracy: 0.1244 - val_loss: 3.6097 - val_accuracy: 0.1679
--- 开始 实验: 6
{'num_units': 1024, 'dropout': 0.3, 'optimizer': 'adam'}
Train on 50000 samples, validate on 10000 samples
Epoch 1/232/50000 [..............................] - ETA: 11:14 - loss: 4.6129 - accuracy: 0.0000e+002020-03-22 05:15:07.480836: E
50000/50000 [==============================] - 78s 2ms/sample - loss: 3.6139 - accuracy: 0.1548 - val_loss: 2.9943 - val_accuracy: 0.2691
Epoch 2/2
50000/50000 [==============================] - 77s 2ms/sample - loss: 2.8460 - accuracy: 0.2921 - val_loss: 2.7325 - val_accuracy: 0.3195
--- 开始 实验: 7
{'num_units': 1024, 'dropout': 0.3, 'optimizer': 'sgd'}
Train on 50000 samples, validate on 10000 samples
Epoch 1/232/50000 [..............................] - ETA: 9:22 - loss: 4.5689 - accuracy: 0.03122020-03-22 05:17:44.697445: E
50000/50000 [==============================] - 68s 1ms/sample - loss: 4.3251 - accuracy: 0.0469 - val_loss: 3.9708 - val_accuracy: 0.1038
Epoch 2/2
50000/50000 [==============================] - 67s 1ms/sample - loss: 3.8546 - accuracy: 0.1173 - val_loss: 3.6345 - val_accuracy: 0.1653
生成如下目录
4、最终可以通过Tensoboard开启读取对应目录的events文件看到对应结果
tensorboard --logdir './logs/hparam_tuning/'
可以在HPARAMS菜单中查看到下面的效果(官网截图)
并且其中有提供了两种主要的不同的查看方式:
TensorFlow训练好的模型以tensorflow原生方式保存成protobuf文件后可以用许多方式部署运行。
例如:通过 tensorflow-js 可以用javascrip脚本加载模型并在浏览器中运行模型。
通过 tensorflow-lite 可以在移动和嵌入式设备上加载并运行TensorFlow模型。
通过 tensorflow-serving 可以加载模型后提供网络接口API服务,通过任意编程语言发送网络请求都可以获取模型预测结果。
通过 tensorFlow for Java接口,可以在Java或者spark(scala)中调用tensorflow模型进行预测。
我们主要介绍tensorflow serving部署模型、使用spark(scala)调用tensorflow模型的方法。
使用 tensorflow serving 部署模型要完成以下步骤。
(1) 准备protobuf模型文件。
(2) 安装tensorflow serving。
(3) 启动tensorflow serving 服务。
(4) 向API服务发送请求,获取预测结果。
可通过以下colab链接测试效果《tf_serving》:https://colab.research.google.com/drive/1vS5LAYJTEn-H0GDb1irzIuyRB8E3eWc8
%tensorflow_version 2.x
import tensorflow as tf
print(tf.__version__)
from tensorflow.keras import *
我们使用tf.keras 训练一个简单的线性回归模型,并保存成protobuf文件。
import tensorflow as tf
from tensorflow.keras import models,layers,optimizers
## 样本数量
n = 800
## 生成测试用数据集
X = tf.random.uniform([n,2],minval=-10,maxval=10)
w0 = tf.constant([[2.0],[-1.0]])
b0 = tf.constant(3.0)
Y = X@w0 + b0 + tf.random.normal([n,1],mean = 0.0,stddev= 2.0) # @表示矩阵乘法,增加正态扰动
## 建立模型
tf.keras.backend.clear_session()
inputs = layers.Input(shape = (2,),name ="inputs") #设置输入名字为inputs
outputs = layers.Dense(1, name = "outputs")(inputs) #设置输出名字为outputs
linear = models.Model(inputs = inputs,outputs = outputs)
linear.summary()
## 使用fit方法进行训练
linear.compile(optimizer="rmsprop",loss="mse",metrics=["mae"])
linear.fit(X,Y,batch_size = 8,epochs = 100)
tf.print("w = ",linear.layers[1].kernel)
tf.print("b = ",linear.layers[1].bias)
## 将模型保存成pb格式文件
export_path = "./data/linear_model/"
version = "1" #后续可以通过版本号进行模型版本迭代与管理
linear.save(export_path+version, save_format="tf")
#查看保存的模型文件
!ls {export_path+version}
assets saved_model.pb variables
# 查看模型文件相关信息
!saved_model_cli show --dir {export_path+str(version)} --all
MetaGraphDef with tag-set: 'serve' contains the following SignatureDefs:
signature_def['__saved_model_init_op']:The given SavedModel SignatureDef contains the following input(s):The given SavedModel SignatureDef contains the following output(s):outputs['__saved_model_init_op'] tensor_info:dtype: DT_INVALIDshape: unknown_rankname: NoOpMethod name is:
signature_def['serving_default']:The given SavedModel SignatureDef contains the following input(s):inputs['inputs'] tensor_info:dtype: DT_FLOATshape: (-1, 2)name: serving_default_inputs:0The given SavedModel SignatureDef contains the following output(s):outputs['outputs'] tensor_info:dtype: DT_FLOATshape: (-1, 1)name: StatefulPartitionedCall:0Method name is: tensorflow/serving/predict
WARNING:tensorflow:From /tensorflow-2.1.0/python3.6/tensorflow_core/python/ops/resource_variable_ops.py:1786: calling BaseResourceVariable.__init__ (from tensorflow.python.ops.resource_variable_ops) with constraint is deprecated and will be removed in a future version.
Instructions for updating:
If using Keras pass *_constraint arguments to layers.
Defined Functions:Function Name: '__call__'Option #1Callable with:Argument #1inputs: TensorSpec(shape=(None, 2), dtype=tf.float32, name='inputs')Argument #2DType: boolValue: FalseArgument #3DType: NoneTypeValue: NoneOption #2Callable with:Argument #1inputs: TensorSpec(shape=(None, 2), dtype=tf.float32, name='inputs')Argument #2DType: boolValue: TrueArgument #3DType: NoneTypeValue: None
Function Name: '_default_save_signature'Option #1Callable with:Argument #1inputs: TensorSpec(shape=(None, 2), dtype=tf.float32, name='inputs')
Function Name: 'call_and_return_all_conditional_losses'Option #1Callable with:Argument #1inputs: TensorSpec(shape=(None, 2), dtype=tf.float32, name='inputs')Argument #2DType: boolValue: TrueArgument #3DType: NoneTypeValue: NoneOption #2Callable with:Argument #1inputs: TensorSpec(shape=(None, 2), dtype=tf.float32, name='inputs')Argument #2DType: boolValue: FalseArgument #3DType: NoneTypeValue: None
安装 tensorflow serving 有2种主要方法:通过Docker镜像安装,通过apt安装。
通过Docker镜像安装是最简单,最直接的方法,推荐采用。
Docker可以理解成一种容器,其上面可以给各种不同的程序提供独立的运行环境。
一般业务中用到tensorflow的企业都会有运维同学通过Docker 搭建 tensorflow serving.
无需算法工程师同学动手安装,以下安装过程仅供参考。
不同操作系统机器上安装Docker的方法可以参照以下链接。
Windows: https://www.runoob.com/docker/windows-docker-install.html
MacOs: https://www.runoob.com/docker/macos-docker-install.html
CentOS: https://www.runoob.com/docker/centos-docker-install.html
安装Docker成功后,使用如下命令加载 tensorflow/serving 镜像到Docker中
docker pull tensorflow/serving
!docker run -t --rm -p 8501:8501 \-v "/Users/.../data/linear_model/" \-e MODEL_NAME=linear_model \tensorflow/serving & >server.log 2>&1
可以使用任何编程语言的http功能发送请求,下面示范linux的 curl 命令发送请求,以及Python的requests库发送请求。
!curl -d '{"instances": [1.0, 2.0, 5.0]}' \-X POST http://localhost:8501/v1/models/linear_model:predict
{"predictions": [[3.06546211], [5.01313448]]
}
import json,requests
data = json.dumps({"signature_name": "serving_default", "instances": [[1.0, 2.0], [5.0,7.0]]})
headers = {"content-type": "application/json"}
json_response = requests.post('http://localhost:8501/v1/models/linear_model:predict', data=data, headers=headers)
predictions = json.loads(json_response.text)["predictions"]
print(predictions)
[[3.06546211], [6.02843142]]