主要思路是用flask构建一个可以实时调用pytorch模型的地址,然后再将其部署到docker里,如果可以的话,再加上内网映射。
首先准备文件目录如下:
其中:
'''
此代码借鉴自参考链接1博主大大的,稍作修改
'''
PAGE = '''
Chinese Text Detector
Chinese Text Detector
'''
from flask import Flask,request,jsonify
import cv2
import numpy as np
from mnist1d import detection,load_model #这是后续导入自己模型的文件
app = Flask('Detector')
@app.route('/', methods=['GET', 'POST'])
# def index():
# print("GO GO GO!!!")
# return redirect(url_for('detector'))
@app.route('/detector', methods=['GET', 'POST'])
def detector():
print("GO GO!!")
if request.method !='POST':
return PAGE
img = request.files['file']
data = img.read()
arr = np.frombuffer(data, dtype=np.uint8)
img = cv2.imdecode(arr, cv2.IMREAD_COLOR)
net = load_model()
result = int(detection(net=net,img=img))
# print('inference time: ', time.time()-tic)
return jsonify(msg='success', data={'result': result})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000,debug=True) #这个5000有用的,debug关掉也可以
FROM pytorch/pytorch:1.2-cuda10.0-cudnn7-devel
ENV LISTEN_PORT 5000
EXPOSE 5000
COPY ./mnist1d.py /app/
COPY ./mnist1d_detection_notzip.pkl /app/
COPY ./detectFlask.py /app/
WORKDIR /app
RUN pip install flask
RUN pip install opencv-python
CMD ["python", "detectFlask.py"]
#这是上面那个dockerfile的注释
FROM pytorch/pytorch:1.2-cuda10.0-cudnn7-devel #1.2这里有坑,注意避雷用自己版本的Torch
ENV LISTEN_PORT 5000
EXPOSE 5000 #和detectflask文件选择的5000保持一致
COPY ./mnist1d.py /app/ #注意mnist1d.py需要与文件同目录
COPY ./mnist1d_detection_notzip.pkl /app/ #权重
COPY ./detectFlask.py /app/ #flask文件
WORKDIR /app #选择app作为工作目录
RUN pip install flask #如果可以的话找个不用安装的镜像
RUN pip install opencv-python
CMD ["python", "detectFlask.py"] #运行
import torch
import torch.nn as nn
class d1Net(nn.Module): #自己搭的1维卷积神经网络检测mnist数字,效果一般,主要是用来跑通用一下
def __init__(self):
super(d1Net, self).__init__()
self.conv = nn.Sequential(
nn.Conv1d(in_channels=1, out_channels=10, kernel_size=3, stride=2), #in:784*1*b, out:392*10*b
nn.MaxPool1d(kernel_size=3, stride=2), #in:392*10*b, out:196*10*b
nn.ReLU(),
nn.Conv1d(10, 20, 3, 2), #in:196*10*b, out:98*20*b
nn.MaxPool1d(kernel_size=3, stride=2), #in:98*20*b, out:49*20*b
nn.ReLU(),
nn.Conv1d(20, 40, 4) #input:49*20*b, 12*40*b
)
self.fc = nn.Sequential(
nn.Linear(1800, 120),
nn.Linear(120,84),
nn.Linear(84,10)
)
def forward(self,x):
x = x.view(-1,1,784)
#print(x.shape)
x = self.conv(x)
#print(x.shape)
x = x.view(-1,1800)
#print(x.shape)
x = self.fc(x)
#print(x.shape)
return x
def load_model(): #加载模型函数
net = d1Net()
# net.load_state_dict(torch.load(r'D:\py\textDectectionDocker\mnist1d_detection_notzip.pkl')) #绝对路径,用来docker前测试
net.load_state_dict(torch.load(r'mnist1d_detection_notzip.pkl'))
#torch.save(net.state_dict(), "mnist1d_detection_notzip.pkl",_use_new_zipfile_serialization=False) #保存不是zip的权重
return net
def detection(net,img): #测试函数
x = net(torch.from_numpy(img).float())
#print(x)
return torch.max(x,1).indices[0]
准备好文件后,可以开始制作镜像,因为此文件中需要安装依赖,所以时间较长
$cd xx/app
$docker build -t detector:v1.0 .
$docker run -p 3223:5000 -d --name detector detector:v1.0
这里的-d表示后台运行,在尝试时可以去掉以查看docker内响应情况
这里选用的花生壳的内网映射(毕竟之前搞小程序的时候买了个域名、http映射、https映射还没用上呢)
映射完成后就可以通过访问域名到达网站了,这波flask-pytorch-docker-内网映射的闹剧也就此拉下帷幕。
拉下帷幕……才怪,接下来介绍一下中间经历的部分弯弯绕绕吧,我内部标签可是有意识地被我迭代到了1.7,真的难受。
首先是我直接搬了博主大大的torch1.2版本出现的问题,因为我的环境是torch>1.6的,在1.6以后torch.save保存的模型是以zip格式保存的,1.2会报错。
解决办法:
在1.6的环境保存一个不是zip格式的,重新制作镜像(下载一个1.6的我觉得会花更多时间,放弃)
torch.save(net.state_dict(), "mnist1d_detection_notzip.pkl",_use_new_zipfile_serialization=False)
flask文件内host=0.0.0.0,我直接浏览器一摸黑直接输入0.0.0.0:3223或者0.0.0.0:3223/detector之类的网址,反正就是访问不出来
博主的flask文件里面还是有从/ 跳转到/detector 的url的代码的,虽然当时为了找是哪里的引用,逐个搜索去了,但是还是在某次中出现问题了
在mnist1d.py文件里有导入权重这个语句,而本来是同目录的但是硬是导入不成功,说没有这个文件
一看第五部分,怎么就这点坑,就算不算前面没有迭代标签,那起码也有6个坑才对,怎么就这?就这点东西不是三俩下就搞完了
(还用问,还不是你菜,这个华华就是训啦)
emmm,上面部分叙述由于本人真的很菜(不是甩锅句嗷)、同样最近也被各种事情逼着走,所以没时间了解之所以然,可能会给各位看官造成一些困扰,在此致歉!另外参考的博主写的比在下真的详细很多,可以直接看参考的链接,但是如果我的文章能给看官们一点点帮助,那就更好了。
总的来说,这波联动起码是达到我想要的结果了,记录一下,之后回来看也方便些,下一波联动:微信云托管。
1.如何将pytorch模型通过docker部署到服务器 - 知乎 (zhihu.com)
2.Docker搞一个flask的image, 然后通过端口映射让别人可以访问 - rookiehbboy - 博客园 (cnblogs.com)