python - Tensorflow,sess.run() 并不总是以相同的顺序返回输出
问题描述
我开发了一个 Python 网络服务器,它在启动时会加载两个 tensorflow 模型,然后将使用这些模型来生成预测。
我正在使用来自 tensorflow的预训练对象检测模型:mask_rcnn_inception_resnet_v2_atrous_coco_2018_01_28
和faster_rcnn_inception_resnet_v2_atrous_lowproposals_coco_2018_01_28
。
这是我的代码:
主要.py:
from Classifier import Classifier
from flask import Flask, Response
import json
classifier_mask = Classifier("path/to/mask_rcnn_inception_resnet_v2_atrous_coco_2018_01_28/saved_model")
classifier_nomask = Classifier("path/to/faster_rcnn_inception_resnet_v2_atrous_lowproposals_coco_2018_01_28/saved_model")
image = ...
app = Flask(__name__)
@app.route('/mask',methods=['POST'])
def do_detections_mask():
output = classifier_mask.detection(image)
return Response(response=json.dumps(output), status=200, mimetype="application/json")
@app.route('/nomask',methods=['POST'])
def do_detections_nomask():
output = classifier_nomask.detection(image)
return Response(response=json.dumps(output), status=200, mimetype="application/json")
app = Flask(__name__)
分类器.py:
import cv2
import tensorflow as tf
import numpy as np
class Classifier():
def __init__(self, model_folder):
self.sess = tf.compat.v1.Session()
model = tf.compat.v1.saved_model.load(
self.sess,
[tf.saved_model.SERVING],
model_folder
)
model_signature = model.signature_def["serving_default"]
self.input_tensor = model_signature.inputs['inputs'].name
self.output_tensor = [v.name for k, v in model_signature.outputs.items() if v.name]
# make a first prediction on some image to 'warm up' the classifier (aka, initializing cuda/memory resources)
# If we don't do that, the first prediction will take a lot more time than others
self.sess.run(self.output_tensor, feed_dict={self.input_tensor: [cv2.imread("path/to/some_image.jpg")]})
def detection(self, image):
outs = self.sess.run(self.output_tensor, feed_dict={self.input_tensor: [image]})
if (len(outs) == 4): # result of an object detection without masks
counts_objects = int(outs[2][0])
scores = outs[0][0][:counts_objects]
labels = outs[1][0].astype(int)[:counts_objects]
boxes = outs[3][0][:counts_objects]
masks = np.array([])
else: # result of an object detection with masks
counts_objects = int(outs[3][0])
scores = outs[0][0][:counts_objects]
labels= outs[1][0].astype(int)[:counts_objects]
masks = outs[2][0][:counts_objects]
boxes = outs[4][0][:counts_objects]
output_dict = {}
output_dict['scores'] = scores.tolist()
output_dict['labels'] = labels
output_dict['boxes'] = boxes.tolist()
output_dict['masks'] = masks.tolist()
return output_dict
当我在本地计算机(Windows 上的 PyCharm)上运行我的代码时,它运行良好。我得到了预期的行为。
该指令outs = self.sess.run(self.output_tensor, feed_dict={self.input_tensor: [image]})
返回一个数组,其中包含给定图像的模型输出以及结构。
outs[0] : the scores
outs[1] : the labels
outs[2] : the count of objects
outs[3] : the bounding boxes
对于faster_rcnn
模型和
outs[0] : the scores
outs[1] : the labels
outs[2] : the mask of objects
outs[3] : the count of objects
outs[4] : the bounding boxes
对于mask_rcnn
模型:
但是当我在 docker 映像中运行它时(python:3.6.10-slim-buster
添加了一些依赖项作为 python-pip、libglib1.0-0、...),我得到了一个非常奇怪的行为。该outs
数组的顺序与我在计算机上运行时的顺序不同。更糟糕的是,每次运行的顺序似乎都是随机变化的(这在我的电脑上没有发生)。很明显,当我检索这些输出并将它们放入字典时,我会得到运行时错误或错误的结果(如果幸运的话,有时会得到很好的结果)
有谁知道这里发生了什么?我能做些什么来解决(或绕过)这个问题?
我尝试过的所有 tensorflow 版本(1.12、1.15.2 和 2.1)都有问题,都在 CPU 上。
这是requirements.txt
我在两种情况下都使用的:
absl-py==0.9.0
astor==0.8.1
boto3==1.12.31
botocore==1.15.31
cachetools==4.0.0
certifi==2019.11.28
chardet==3.0.4
click==7.1.1
cycler==0.10.0
Cython==0.29.16
docutils==0.15.2
Flask==1.1.1
gast==0.2.2
google-auth==1.12.0
google-auth-oauthlib==0.4.1
google-pasta==0.2.0
grpcio==1.27.2
h5py==2.10.0
idna==2.9
itsdangerous==1.1.0
Jinja2==2.11.1
jmespath==0.9.5
Keras-Applications==1.0.8
Keras-Preprocessing==1.1.0
kiwisolver==1.1.0
Markdown==3.2.1
MarkupSafe==1.1.1
matplotlib==3.2.1
numpy==1.18.2
oauthlib==3.1.0
object-detection-0.1==0.1
opencv-python==4.2.0.32
opt-einsum==3.2.0
Pillow==7.0.0
protobuf==3.11.3
pyasn1==0.4.8
pyasn1-modules==0.2.8
pyparsing==2.4.6
python-dateutil==2.8.1
requests==2.23.0
requests-oauthlib==1.3.0
rsa==4.0
s3transfer==0.3.3
scipy==1.4.1
six==1.14.0
tensorboard==2.1.1
tensorflow==2.1.0
tensorflow-estimator==2.1.0
termcolor==1.1.0
urllib3==1.25.8
Werkzeug==1.0.0
wrapt==1.12.1
编辑:
- 如果我只初始化一个分类器,我会有同样的行为。
解决方案
推荐阅读
- mysql - 查询移动到单独的列
- python - azure webapp 中没有 pip 或 python 模块
- ruby-on-rails - 将长 SQL 查询转换为 ActiveRecord 表达式
- laravel - Laravel 和 CodeIgniter 是否具有相同的哈希函数?
- angular - Angular:无法绑定到“上传器”,但 FileUploadModule 已导入同一模块
- javascript - React Context:什么时候重新渲染孩子?
- excel - 为什么会出现此复选框问题?
- excel - 删除excel下拉列表中的重复项而不创建新表
- java - spring mvc项目不返回jsp页面HTTP状态404
- php - 如何使用 PHP 或 Laravel 函数从其他两个数组创建嵌套关联数组?