项目代码:
https://pan.baidu.com/s/1-FdTk7XjryvUsZR9CW9T3g
提取码:6uo5
该项目上传至阿里云仓库:docker——构建自己的项目(阿里云仓库)| docker构建仓库镜像教程
开启模型服务
run_pytorch_server.py
import io
import json
import flask
import torch
import torch
import torch.nn.functional as F
from PIL import Image
from torch import nn
from torchvision import transforms as T
from torchvision.models import resnet50
from torch.autograd import Variable
# 初始化Flask app
app = flask.Flask(__name__)
model = None
use_gpu = False
# 返回结果用的
with open('imagenet_class.txt', 'r') as f:
idx2label = eval(f.read())
# 加载模型进来
def load_model():
"""Load the pre-trained model, you can use your model just as easily.
"""
global model
#这里我们直接加载官方工具包里提供的训练好的模型(代码会自动下载)括号内参数为是否下载模型对应的配置信息
model = resnet50(pretrained=True)
#将模型指定为测试格式
model.eval()
#是否使用gpu
if use_gpu:
model.cuda()
# 数据预处理
def prepare_image(image, target_size):
"""Do image preprocessing before prediction on any data.
:param image: original image
:param target_size: target image size
:return:
preprocessed image
"""
#针对不同模型,image的格式不同,但需要统一至RGB格式
if image.mode != 'RGB':
image = image.convert("RGB")
# Resize the input image and preprocess it.(按照所使用的模型将输入图片的尺寸修改,并转为tensor)
image = T.Resize(target_size)(image)
image = T.ToTensor()(image)
# Convert to Torch.Tensor and normalize. mean与std (RGB三通道)这里的参数和数据集中是对应的,训练过程中一致
image = T.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])(image)
# Add batch_size axis.增加一个维度,用于按batch测试 本次这里一次测试一张
image = image[None]
if use_gpu:
image = image.cuda()
return Variable(image, volatile=True) #不需要求导
# 开启服务 这里的predict只是一个名字,可自定义
@app.route("/predict", methods=["POST"])
def predict():
# Initialize the data dictionary that will be returned from the view.
#做一个标志,刚开始无图像传入时为false,传入图像时为true
data = {"success": False}
# Ensure an image was properly uploaded to our endpoint.
# 如果收到请求
if flask.request.method == 'POST':
#判断是否为图像
if flask.request.files.get("image"):
# Read the image in PIL format
# 将收到的图像进行读取
image = flask.request.files["image"].read()
image = Image.open(io.BytesIO(image)) #二进制数据
# Preprocess the image and prepare it for classification.
# 利用上面的预处理函数将读入的图像进行预处理
image = prepare_image(image, target_size=(224, 224))
# Classify the input image and then initialize the list of predictions to return to the client.
preds = F.softmax(model(image), dim=1)
results = torch.topk(preds.cpu().data, k=3, dim=1)
results = (results[0].cpu().numpy(), results[1].cpu().numpy())
#将data字典增加一个key,value,其中value为list格式
data['predictions'] = list()
# Loop over the results and add them to the list of returned predictions
for prob, label in zip(results[0][0], results[1][0]):
label_name = idx2label[label]
r = {"label": label_name, "probability": float(prob)}
#将预测结果添加至data字典
data['predictions'].append(r)
# Indicate that the request was a success.
data["success"] = True
# Return the data dictionary as a JSON response.
# 将最终结果以json格式文件传出
return flask.jsonify(data)
if __name__ == '__main__':
print("Loading PyTorch model and Flask starting server ...")
print("Please wait until server has fully started")
#先加载模型
load_model()
#再开启服务
app.run()
调用模型(响应)
simple_request.py
import requests
import argparse
# Initialize the PyTorch REST API endpoint URL.
PyTorch_REST_API_URL = 'http://127.0.0.1:5000/predict'
def predict_result(image_path):
# Initialize image path
image = open(image_path, 'rb').read()
payload = {'image': image}
# Submit the request.
r = requests.post(PyTorch_REST_API_URL, files=payload).json()
# Ensure the request was successful.
if r['success']:
# Loop over the predictions and display them.
for (i, result) in enumerate(r['predictions']):
print('{}. {}: {:.4f}'.format(i + 1, result['label'],
result['probability']))
# Otherwise, the request failed.
else:
print('Request failed')
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Classification demo')
parser.add_argument('--file',default='./dog.jpg', type=str, help='test image file')
args = parser.parse_args()
predict_result(args.file)