如何部署TensorFlow Serving
发表于:2025-02-02 作者:千家信息网编辑
千家信息网最后更新 2025年02月02日,这篇文章主要介绍"如何部署TensorFlow Serving",在日常操作中,相信很多人在如何部署TensorFlow Serving问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希
千家信息网最后更新 2025年02月02日如何部署TensorFlow Serving
这篇文章主要介绍"如何部署TensorFlow Serving",在日常操作中,相信很多人在如何部署TensorFlow Serving问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"如何部署TensorFlow Serving"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
准备环境
准备好 TensorFlow 环境,导入依赖:
import sys# Confirm that we're using Python 3assert sys.version_info.major == 3, 'Oops, not running Python 3. Use Runtime > Change runtime type'
import tensorflow as tffrom tensorflow import keras# Helper librariesimport numpy as npimport matplotlib.pyplot as pltimport osimport subprocessprint(f'TensorFlow version: {tf.__version__}')print(f'TensorFlow GPU support: {tf.test.is_built_with_gpu_support()}')physical_gpus = tf.config.list_physical_devices('GPU')print(physical_gpus)for gpu in physical_gpus: # memory growth must be set before GPUs have been initialized tf.config.experimental.set_memory_growth(gpu, True)logical_gpus = tf.config.experimental.list_logical_devices('GPU')print(len(physical_gpus), "Physical GPUs,", len(logical_gpus), "Logical GPUs")
TensorFlow version: 2.4.1TensorFlow GPU support: True[PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')]1 Physical GPUs, 1 Logical GPUs
创建模型
载入 Fashion MNIST 数据集:
fashion_mnist = keras.datasets.fashion_mnist(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()# scale the values to 0.0 to 1.0train_images = train_images / 255.0test_images = test_images / 255.0# reshape for feeding into the modeltrain_images = train_images.reshape(train_images.shape[0], 28, 28, 1)test_images = test_images.reshape(test_images.shape[0], 28, 28, 1)class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']print('\ntrain_images.shape: {}, of {}'.format(train_images.shape, train_images.dtype))print('test_images.shape: {}, of {}'.format(test_images.shape, test_images.dtype))
train_images.shape: (60000, 28, 28, 1), of float64test_images.shape: (10000, 28, 28, 1), of float64
用最简单的 CNN 训练模型,
model = keras.Sequential([ keras.layers.Conv2D(input_shape=(28,28,1), filters=8, kernel_size=3, strides=2, activation='relu', name='Conv1'), keras.layers.Flatten(), keras.layers.Dense(10, name='Dense')])model.summary()testing = Falseepochs = 5model.compile(optimizer='adam', loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), metrics=[keras.metrics.SparseCategoricalAccuracy()])model.fit(train_images, train_labels, epochs=epochs)test_loss, test_acc = model.evaluate(test_images, test_labels)print('\nTest accuracy: {}'.format(test_acc))
Model: "sequential"_________________________________________________________________Layer (type) Output Shape Param #=================================================================Conv1 (Conv2D) (None, 13, 13, 8) 80_________________________________________________________________flatten (Flatten) (None, 1352) 0_________________________________________________________________Dense (Dense) (None, 10) 13530=================================================================Total params: 13,610Trainable params: 13,610Non-trainable params: 0_________________________________________________________________Epoch 1/51875/1875 [==============================] - 3s 722us/step - loss: 0.7387 - sparse_categorical_accuracy: 0.7449Epoch 2/51875/1875 [==============================] - 1s 793us/step - loss: 0.4561 - sparse_categorical_accuracy: 0.8408Epoch 3/51875/1875 [==============================] - 1s 720us/step - loss: 0.4097 - sparse_categorical_accuracy: 0.8566Epoch 4/51875/1875 [==============================] - 1s 718us/step - loss: 0.3899 - sparse_categorical_accuracy: 0.8636Epoch 5/51875/1875 [==============================] - 1s 719us/step - loss: 0.3673 - sparse_categorical_accuracy: 0.8701313/313 [==============================] - 0s 782us/step - loss: 0.3937 - sparse_categorical_accuracy: 0.8630Test accuracy: 0.8629999756813049
保存模型
将模型保存成 SavedModel 格式,路径里加上版本号,以便 TensorFlow Serving 时可选择模型版本。
# Fetch the Keras session and save the model# The signature definition is defined by the input and output tensors,# and stored with the default serving keyimport tempfileMODEL_DIR = os.path.join(tempfile.gettempdir(), 'tfx')version = 1export_path = os.path.join(MODEL_DIR, str(version))print('export_path = {}\n'.format(export_path))tf.keras.models.save_model( model, export_path, overwrite=True, include_optimizer=True, save_format=None, signatures=None, options=None)print('\nSaved model:')!ls -l {export_path}
export_path = /tmp/tfx/1INFO:tensorflow:Assets written to: /tmp/tfx/1/assetsSaved model:total 88drwxr-xr-x 2 john john 4096 Apr 13 15:10 assets-rw-rw-r-- 1 john john 78169 Apr 13 15:12 saved_model.pbdrwxr-xr-x 2 john john 4096 Apr 13 15:12 variables
查看模型
使用 saved_model_cli
工具查看模型的 MetaGraphDefs (the models) 和 SignatureDefs (the methods you can call),了解信息。
!saved_model_cli show --dir '/tmp/tfx/1' --all
2021-04-13 15:12:29.433576: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcudart.so.11.0MetaGraphDef 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_INVALID shape: unknown_rank name: NoOp Method name is:signature_def['serving_default']: The given SavedModel SignatureDef contains the following input(s): inputs['Conv1_input'] tensor_info: dtype: DT_FLOAT shape: (-1, 28, 28, 1) name: serving_default_Conv1_input:0 The given SavedModel SignatureDef contains the following output(s): outputs['Dense'] tensor_info: dtype: DT_FLOAT shape: (-1, 10) name: StatefulPartitionedCall:0 Method name is: tensorflow/serving/predictDefined Functions: Function Name: '__call__' Option #1 Callable with: Argument #1 Conv1_input: TensorSpec(shape=(None, 28, 28, 1), dtype=tf.float32, name='Conv1_input') Argument #2 DType: bool Value: False Argument #3 DType: NoneType Value: None Option #2 Callable with: Argument #1 inputs: TensorSpec(shape=(None, 28, 28, 1), dtype=tf.float32, name='inputs') Argument #2 DType: bool Value: False Argument #3 DType: NoneType Value: None Option #3 Callable with: Argument #1 inputs: TensorSpec(shape=(None, 28, 28, 1), dtype=tf.float32, name='inputs') Argument #2 DType: bool Value: True Argument #3 DType: NoneType Value: None Option #4 Callable with: Argument #1 Conv1_input: TensorSpec(shape=(None, 28, 28, 1), dtype=tf.float32, name='Conv1_input') Argument #2 DType: bool Value: True Argument #3 DType: NoneType Value: None ...
部署模型
安装 Serving
echo "deb [arch=amd64] http://storage.googleapis.com/tensorflow-serving-apt stable tensorflow-model-server tensorflow-model-server-universal" | sudo tee /etc/apt/sources.list.d/tensorflow-serving.list && \curl https://storage.googleapis.com/tensorflow-serving-apt/tensorflow-serving.release.pub.gpg | sudo apt-key add -sudo apt updatesudo apt install tensorflow-model-server
开启 Serving
开启 TensorFlow Serving ,提供 REST API :
rest_api_port: REST 请求端口。
model_name: REST 请求 URL ,自定义的名称。
model_base_path: 模型所在目录。
nohup tensorflow_model_server \ --rest_api_port=8501 \ --model_name=fashion_model \ --model_base_path="/tmp/tfx" >server.log 2>&1 &
$ tail server.logTo enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.2021-04-13 15:12:10.706648: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:206] Restoring SavedModel bundle.2021-04-13 15:12:10.726722: I external/org_tensorflow/tensorflow/core/platform/profile_utils/cpu_utils.cc:112] CPU Frequency: 2599990000 Hz2021-04-13 15:12:10.756506: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:190] Running initialization op on SavedModel bundle at path: /tmp/tfx/12021-04-13 15:12:10.759935: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:277] SavedModel load for tags { serve }; Status: success: OK. Took 110653 microseconds.2021-04-13 15:12:10.760277: I tensorflow_serving/servables/tensorflow/saved_model_warmup_util.cc:59] No warmup data file found at /tmp/tfx/1/assets.extra/tf_serving_warmup_requests2021-04-13 15:12:10.760486: I tensorflow_serving/core/loader_harness.cc:87] Successfully loaded servable version {name: fashion_model version: 1}2021-04-13 15:12:10.763938: I tensorflow_serving/model_servers/server.cc:371] Running gRPC ModelServer at 0.0.0.0:8500 ...[evhttp_server.cc : 238] NET_LOG: Entering the event loop ...2021-04-13 15:12:10.765308: I tensorflow_serving/model_servers/server.cc:391] Exporting HTTP/REST API at:localhost:8501 ...
访问服务
随机显示一张测试图:
def show(idx, title): plt.figure() plt.imshow(test_images[idx].reshape(28,28)) plt.axis('off') plt.title('\n\n{}'.format(title), fontdict={'size': 16})import randomrando = random.randint(0,len(test_images)-1)show(rando, 'An Example Image: {}'.format(class_names[test_labels[rando]]))
创建 JSON 对象,给到三张要预测的图:
import jsondata = json.dumps({"signature_name": "serving_default", "instances": test_images[0:3].tolist()})print('Data: {} ... {}'.format(data[:50], data[len(data)-52:]))
Data: {"signature_name": "serving_default", "instances": ... [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0]]]]}
REST 请求
最新模型版本进行预测:
!pip install -q requestsimport requestsheaders = {"content-type": "application/json"}json_response = requests.post('http://localhost:8501/v1/models/fashion_model:predict', data=data, headers=headers)predictions = json.loads(json_response.text)['predictions']show(0, 'The model thought this was a {} (class {}), and it was actually a {} (class {})'.format( class_names[np.argmax(predictions[0])], np.argmax(predictions[0]), class_names[test_labels[0]], test_labels[0]))
指定模型版本进行预测:
headers = {"content-type": "application/json"}json_response = requests.post('http://localhost:8501/v1/models/fashion_model/versions/1:predict', data=data, headers=headers)predictions = json.loads(json_response.text)['predictions']for i in range(0,3): show(i, 'The model thought this was a {} (class {}), and it was actually a {} (class {})'.format( class_names[np.argmax(predictions[i])], np.argmax(predictions[i]), class_names[test_labels[i]], test_labels[i]))
到此,关于"如何部署TensorFlow Serving"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!
模型
版本
学习
更多
环境
准备
帮助
实用
接下来
信息
名称
对象
工具
所在
数据
文章
方法
格式
理论
目录
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
软件开发公司可以做培训
宜章电脑软件开发工资多少
数据库文本框怎么删除
比特彗星 服务器
最近出现的一系列网络技术
网络安全工资
软件开发要穿正装面试吗
招聘小视频的软件开发
江苏企业软件开发代理价格
怎么做个软件开发公司
政府网络安全预算
真三国无双ol服务器
赫兹服务器
象山手机软件开发外包
地下城那个图是数据库
万德导出数据库
树莓派服务器系统
软件开发详细设计书百度文库
中央企业网络安全预防大赛
数据库热备视频教程
e地通主服务器地址
平谷区信息化软件开发
数据库连接失败999
sql 连接数据库查询值
计算机网络技术没用
网络安全 数字签名
计算机网络技术基础子网
网络服务器怎么设置
ide计算机软件开发领域
词语网络技术有限公司