Heroku 是一个平台即服务(platform as a service, PaaS),可以让开发者方便得在云端编译、部署自己的应用程序。本片教程展示了如何在 Heroku 上安装运行自己的 PyTorch 模型,并且提供给别人使用。
部署前的准备
在开始部署到 Heroku 之前,我们要做以下几项准备工作:
- Git
- Flask
- 网页端应用需要的 HTML,CSS,JavaScript
- Heroku 账户
我们分开每一步来讲解。
Git
在本地环境安装好 Git 的开发环境,参考链接:https://git-scm.com/downloads。
Flask
用下列命令安装 Flask:
1 | pip install Flask |
下面是我们将要用到的 Flask 应用目录结构:
1 2 3 4 5 6 7 8 9 10 | /web-app |--templates |----index.html |--static |----css |------style.css |----js |------script.js |--model.pt |--application.py |
其中 templates
包含了会用到的 HTML 文件。文件夹 static
用于存储静态文件,比如 css 或 javascript。文件 model.pt
是我们训练好的 PyTorch 模型。文件 application.py
是我们应用程序的主要逻辑文件。
下面是 application.py
文件的主要结构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | from flask import Flask,request,jsonify,render_template import os app = Flask(__name__, static_url_path='/static') @app.route('/') def render_page(): return render_template('index.html') @app.route('/predict',methods=['POST']) def predict(): #应用处理逻辑写在这里 if __name__ == '__main__': app.run(debug=False,port=os.getenv('PORT',5000)) |
下面的代码是一个接收用户上传图像,然后返回预测结果的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | @app.route('/uploadajax',methods=['POST']) def upload_file(): """ retrieve the image uploaded and make sure it is an image file """ file = request.files['file'] image_extensions=['ras', 'xwd', 'bmp', 'jpe', 'jpg', 'jpeg', 'xpm', 'ief', 'pbm', 'tif', 'gif', 'ppm', 'xbm', 'tiff', 'rgb', 'pgm', 'png', 'pnm'] if file.filename.split('.')[1] not in image_extensions: return jsonify('Please upload an appropriate image file') """ Load the trained densenet model """ model_transfer = models.densenet121(pretrained=False) model_transfer.classifier=nn.Sequential(nn.Linear(1024,512), nn.ReLU(), nn.Dropout(0.2), nn.Linear(512,133)) model_transfer.load_state_dict(torch.load('model_transfer.pt',map_location='cpu')) """ Load variables needed to detect human face/dog pil image for dog detection and breed prediction and numpy for face detection """ image_bytes = file.read() pil_image = Image.open(io.BytesIO(image_bytes)) nparr = np.frombuffer(image_bytes, np.uint8) img_np = cv2.imdecode(nparr, cv2.IMREAD_COLOR) if (dog_detector(pil_image)): dog_breed = predict_breed_transfer(pil_image,model_transfer) return jsonify ('This a dog picture of breed:{}'.format(dog_breed)) elif (face_detector(img_np)): dog_breed = predict_breed_transfer(pil_image,model_transfer) return jsonify('Hello Human You resemble dog breed of {}'.format(dog_breed)) else: return jsonify('This pic doesn\'t have a human face or a dog') |
网页端应用需要的 HTML, CSS, JavaScript
如果需要用到 CSS 文件,可以这样引入:
1 | <link rel=”stylesheet” href=”{{ url_for(‘static’, filename=’css/style.css’) }}”> |
同理,JavaScript 可以这样引入:
1 | <script src=”{{ url_for(‘static’, filename=’js/script.js’) }}”></script> |
Heroku 账户
如果你还没有 Heroku 账户,可以到官网注册一个,然后下载并安装 Heroku CLI。
接下来我们安装 gunicorn:
1 | pip install gunicorn |
然后在我们刚才的 Flask 项目 web-app 下创建三个文件:runtime.txt
,Procfile
和 requirements.txt
,新的目录结构如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 | /web-app |--templates |----index.html |--static |----css |------style.css |----js |------script.js |--model.pt |--application.py |--runtime.txt |--Procfile |--requirements.txt |
我们刚才创建的三个文件分别如下:
Runtime.txt
1 | python-3.7.0 |
Procfile
1 | web: gunicorn application:app --log-level debug |
这个命令里 application
是你的 .py
文件的文件名。
requirements.txt
这个文件里是 Python 需要的依赖包,可以用下面的命令获取:
1 | pip freeze > requirements.txt |
好,现在可以开始准备部署到 Heroku 了。
部署到 Heroku
首先在 Heroku CLI 里登陆并创建一个新的应用(也可以在网页端完成):
1 2 | heroku login heroku create |
然后用下列命令部署:
1 2 3 4 | git init git add . git commit -m 'initial commit' git push heroku master |
然后就可以用 Heroku 给的应用链接打开自己的应用了。
参考资料
Flask 文档:http://flask.pocoo.org/docs/0.12/
本文由 PyTorch中文网 编译整理自 Medium。
本站微信群、QQ群(三群号 726282629):
