链接:源代码
提取码:7gpf
给的是本地测试版的代码:需要修改Server.py文件中的app.run("0.0.0.0", port=5000)
深 度 分 类 模 型 部 署 − 远 程 测 试 版 深度分类模型部署-远程测试版 深度分类模型部署−远程测试版
- 安装:
pip install torch===1.2.0 torchvision===0.4.0 -f https://download.pytorch.org/whl/torch_stable.html
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple flask
- 工程目录
- 介绍
1.models: 存放模型参数的文件夹
2.net: 存放网络的文件夹
3.resources: 存放网络服务资源的文件夹,目前主要就是接受上传上来的图片
4.test: 没有用,是用来在本地测试用的,可以删除
5.Clinet: 没有用,是用来作为本地测试用的,可以删除
6.Server: 最重要的文件,是发送服务的文件
- 运行
python Server.py
远程接受请求结果:
本地请求显示结果:
最主要的服务文件:Server.py
# -*- coding: utf-8 -*-
#------------------------------------------------------0.引入库--------------------------------------------------------------
import torch
from net.lenet import LeNet
from PIL import Image
import os
import torchvision.transforms as transforms
import time
from flask import request, Flask
# 实例化Flask
app = Flask(__name__)
#------------------------------------------------------1.加载模型--------------------------------------------------------------
# 导入模型参数
path_model_state_dict = "./models/model.pth"
# 导入网络
net_loaded=LeNet(classes=2)
# 在网络中加载参数合成为模型
net_loaded.load_state_dict(torch.load(path_model_state_dict))
model_loaded = net_loaded
#------------------------------------------------------2.获取Inference数据--------------------------------------------------------------
def get_image(imageFilePath):
input_image = Image.open(imageFilePath).convert("RGB")
return input_image
#------------------------------------------------------3.定义数据预处理--------------------------------------------------------------
def process_image(input_image):
# 均值和方差
norm_mean = [0.485, 0.456, 0.406]
norm_std = [0.229, 0.224, 0.225]
# 预处理
preprocess = transforms.Compose([
transforms.Resize((32, 32)),
transforms.ToTensor(),
transforms.Normalize(norm_mean, norm_std), # 标准化
])
img_chw = preprocess(input_image)
return img_chw # chw:channel height width
#------------------------------------------------------4.模型预测--------------------------------------------------------------
def predict_image(model, imageFilePath):
model.eval() # 参数固化
input_image = get_image(imageFilePath) # 获取图片
img_chw = process_image(input_image) # 图片预处理
# unsqueeze:加一个维度。pytorch的输入数据要求是四维的, 即(3,32,32) =》 (1,3,32,32) 多出来的一维一般是用来表示图片的张数,我们这里就是1
img_chw=torch.unsqueeze(img_chw, dim=0)
with torch.no_grad(): # 不计算梯度
outputs = model(img_chw) # ***重要:模型预测***
_, predicted = torch.max(outputs.data, 1) # predicted : tensor([1])
rmb = 1 if predicted.numpy()[0] == 0 else 100 # predicted.numpy()[0] : 1
return rmb
#------------------------------------------------------5.服务返回--------------------------------------------------------------
# 定义回调函数,接收来自/的post请求,并返回预测结果
@app.route("/", methods=['POST'])
def return_result():
startTime = time.time()
received_file = request.files['file']
imageFileName = received_file.filename
print('----------')
print(request.files)
print('----------')
print(received_file)
print('----------')
if received_file:
received_dirPath = './resources/received_images'
if not os.path.isdir(received_dirPath):
os.makedirs(received_dirPath)
imageFilePath = os.path.join(received_dirPath, imageFileName)
received_file.save(imageFilePath)
print('图片文件保存到此路径:%s' % imageFilePath)
usedTime = time.time() - startTime
print('接收图片并保存,总共耗时%.2f秒' % usedTime)
startTime = time.time()
print(imageFilePath)
result = predict_image(model_loaded, imageFilePath)
#print(result)
usedTime = time.time() - startTime
print('完成对接收图片的检测,总共耗时%.2f秒' % usedTime)
print("testtest",result)
return str(result)
else:
return 'failed'
#------------------------------------------------------6.主函数--------------------------------------------------------------
if __name__ == "__main__":
# imageFilePath = "./test/0MEDOLBT.jpg"
# result = predict_image(model_loaded,imageFilePath)
# print("模型获得{}元".format(result))
app.run("0.0.0.0", port=5000)
lenet.py
# -*- coding: utf-8 -*-
import torch.nn as nn
import torch.nn.functional as F
class LeNet(nn.Module):
def __init__(self, classes):
super(LeNet, self).__init__()
self.conv1 = nn.Conv2d(3, 6, 5)
self.conv2 = nn.Conv2d(6, 16, 5)
self.fc1 = nn.Linear(16*5*5, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, classes)
def forward(self, x):
out = F.relu(self.conv1(x))
out = F.max_pool2d(out, 2)
out = F.relu(self.conv2(out))
out = F.max_pool2d(out, 2)
out = out.view(out.size(0), -1)
out = F.relu(self.fc1(out))
out = F.relu(self.fc2(out))
out = self.fc3(out)
return out
def initialize_weights(self):
for m in self.modules():
if isinstance(m, nn.Conv2d):
nn.init.xavier_normal_(m.weight.data)
if m.bias is not None:
m.bias.data.zero_()
elif isinstance(m, nn.BatchNorm2d):
m.weight.data.fill_(1)
m.bias.data.zero_()
elif isinstance(m, nn.Linear):
nn.init.normal_(m.weight.data, 0, 0.1)
m.bias.data.zero_()
class LeNet2(nn.Module):
def __init__(self, classes):
super(LeNet2, self).__init__()
self.features = nn.Sequential(
nn.Conv2d(3, 6, 5),
nn.ReLU(),
nn.MaxPool2d(2, 2),
nn.Conv2d(6, 16, 5),
nn.ReLU(),
nn.MaxPool2d(2, 2)
)
self.classifier = nn.Sequential(
nn.Linear(16*5*5, 120),
nn.ReLU(),
nn.Linear(120, 84),
nn.ReLU(),
nn.Linear(84, classes)
)
def forward(self, x):
x = self.features(x)
x = x.view(x.size()[0], -1)
x = self.classifier(x)
return x