相关文章推荐
孤独的饼干  ·  关于 ...·  3 周前    · 
孤独的饼干  ·  c语言 ...·  6 月前    · 
孤独的饼干  ·  Eclipse Community ...·  10 月前    · 
孤独的饼干  ·  HAProxy SSL handshake ...·  1 年前    · 
孤独的饼干  ·  gitlab-runner 9.0.0 ...·  1 年前    · 
孤独的饼干  ·  Minikube dashboard is ...·  1 年前    · 
聪明伶俐的课本  ·  SpringBoot ...·  15 分钟前    · 
爱看球的牙膏  ·  IDEA ...·  16 分钟前    · 
帅气的红茶  ·  清华大学出版社·  2 小时前    · 

通过Web服务调用Python写的手写数字识别算法模型,得到手写数字识别结果。

项目场景:

项目需求:将客户端的请求经由Web服务器转发给Flask程序实例。
示例:通过Web服务调用Python写的手写数字识别算法模型,得到手写数字识别结果。

环境准备:

  1. Python环境不多说了
  2. 安装 flask
    pip install flask
  3. 安装 waitress
    pip install waitress

main.py

from flask import Flask
from predictNumber import predict
app=Flask(__name__)
@app.route('/predictNumber/', methods=['POST'])
def predict_number():
	image = request.form["image"] # 非必须,本案例使用
	result = predict(image)
    return {
		"result": result
if __name__=='__main__':
    app.debug=True
    app.run(host='127.0.0.1',port=5000)

其中,手写数字识别的代码 predictNumber.py 赠送如下:

from __future__ import print_function
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.optim.lr_scheduler import StepLR
from PIL import Image
import numpy as np
import base64
from io import BytesIO
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, 32, 3, 1)
        self.conv2 = nn.Conv2d(32, 64, 3, 1)
        self.dropout1 = nn.Dropout(0.25)
        self.dropout2 = nn.Dropout(0.5)
        self.fc1 = nn.Linear(9216, 128)
        self.fc2 = nn.Linear(128, 10)
    def forward(self, x):
        x = self.conv1(x)
        x = F.relu(x)
        x = self.conv2(x)
        x = F.relu(x)
        x = F.max_pool2d(x, 2)
        x = self.dropout1(x)
        x = torch.flatten(x, 1)
        x = self.fc1(x)
        x = F.relu(x)
        x = self.dropout2(x)
        x = self.fc2(x)
        output = F.log_softmax(x, dim=1)
        return output
def predict(image):
    # load model
    model = Net()
    model.load_state_dict(torch.load("demo/model/mnist_cnn.pt"))
    model.eval()
    # load test data
    img = Image.open(image).convert('L') 
    img = img.resize((28, 28)) # 更改图片大小
    npimg1 = np.array(img) # 转为numpy矩阵
    flatten_img = npimg1.reshape(1, 1, 28, 28) # 转为mnist1, 1, 28, 28二维张量
    # 以下意思是把白色背景转为黑色背景,因为训练的都是黑色背景
    new_flatten_img = (255-flatten_img)/255.0
    new_flatten_img = new_flatten_img.reshape(1, 1, 28, 28) #      --------  该数据可直接被模型识别
    test_kwargs = {'batch_size': 1}
    test_loader = torch.utils.data.DataLoader(new_flatten_img, **test_kwargs)
    for data in test_loader:
        data = data.to(torch.float32)
        output = model(data)
        pred = output.argmax(dim=1, keepdim=True)
        print(pred)   
        print(pred.item())
        return pred.item() 

启动该服务有两种方式

通过运行Python脚本启动服务,run.py 代码如下:

from waitress import serve
import main
serve(main.app, host='127.0.0.1',port=5000)

直接运行 run.py 即可

python run.py

验证我们可通过postman发送请求,得到如下结果:
run方式启动

通过 cmd 设置 mian.py 路径,我的 main.py 放在E:\pythonProject\下面,大家自行调整。

set  FLASK_APP=E:\pythonProject\main.py

再通过以下指令启动服务:

flask run

效果如下:
cmd启动效果
以上便是简单版的完整流程。下面加更一些补充说明~

Flask程序必须创建一个程序实例。参见上面第一个代码 main.pyapp = Flask(__name__) 即为实例。

Web服务器把接收到的所有客户端请求,转交给Web服务器网关接口对象处理。需要提供的参数只有一个,就是程序主模块或包的名字,一般就是Python的name变量。

客户端的请求经由Web服务器转发给Flask程序实例。程序实例需要URL到具体代码的映射关系。这个映射关系称为路由。
Flask中最简单的路由定义方式是app.route修饰器。

上面的路由定义,把根路径和predictNumber函数关联起来,如果部署程序的服务器域名是 http://127.0.0.1:5000/,那么浏览器中输入 http://127.0.0.1:5000/predictNumber/ 就会触发这个函数。

函数的返回值称为响应,是客户端接收到的内容。这样如果客户端是Web浏览器,响应就是给客户看的文档。

下面博文中有非常详细完整的介绍,以供参考。

一个简单的Flask Web服务器


实现多并发调用服务可参考:

Flask+gunicorn实现web服务并发调用Python程序,解决多线程/多进程问题

多并发调用Pytorch的坑:

Flask+gunicorn部署深度学习报错gunicorn: error: argument -b: invalid int value ‘0.0.0.0:8000‘

要使用Python Flask搭建Web服务器和客户端,可以使用以下代码:from flask import Flaskapp = Flask(name)@app.route('/') def index(): return 'Hello, world!'if name == 'main': app.run()客户端代码:import requestsresp = requests...
代码已上传github 首先声明,在HTML中调用本地Python程序是十分不推荐的,一是因为网页调用本地程序的权限正在被取消,二是因为真不如JS写直接,三是只能在自己本地调用。 但如果你要用,像我一样,需要在课堂上进行一个Python代码的展示,并且想要一个好看的UI界面的话,可以这样来做,做起来还是很容易的,但这样的展示仅限于需要弹框的,比如我的人脸检测是弹窗式,如果需要内嵌在网页内...
启动Docker容器报错docker: Error response from daemon: driver failed programming external connectivity on.. 13345 安装Pytorch报错Error: No matching distribution found for typing-extensions (from torch==1.9.0) 小白白程序员: 解决了,包少可以,多了还是要考虑版本问题 RuntimeError: unexpected EOF, expected 73963 more bytes. The file might be corrupted.解决方案 小白白程序员: yeah!
 
推荐文章