简介
机器学习模型躺在IPy笔记本或分散的Python脚本里是不行的。为了改变生活并对世界产生影响,模型需要以普通大众而不仅仅是领域专家可用的方式进行部署。为此,模型需要被封装在某种API后面,其他应用程序可以用它来与模型通信。这涉及到相当多的网络开发,人们常常被它吓到。然而,这并不难。读完这篇文章,你就可以自己发现它了
这篇文章的目的是将一个机器学习模型作为一个通用的API部署在网络上,可以在各种平台上使用,例如:
- 网站
- 应用程序的机器人,如telegram、slack、discord和更多。
- 安卓/iOS应用
- Alexa技能
- 任何其他允许你通过HTTP/HTTPS发送基本GET/POST请求的平台
免费托管API*!
*除非你的模型使用需要nvidia GPU的CUDA,否则这种方法是免费的。如果你想使用CUDA或任何其他GPU密集型库,你需要购买一个带有nvidia GPU的服务器。如果你有一台服务器,我已经在这篇文章的末尾介绍了介绍性的指南。
前提条件
读者需要能够在python中创建机器学习模型,训练它们,然后用它们来预测结果。这篇文章的目的只是提供关于将机器学习模型部署到生产中进行小规模使用的见解。
以下是将会用到的几个库和资源。
- pickle。一个原生的python库,用于将python对象保存(序列化)和加载(去序列化)为磁盘上的文件。
- flask。一个基于python的易于使用的网络框架。这里有sentdex的文档和一系列好的视频教程
- pythonanywhere。一个免费使用的教育网站,允许托管python flask并提供一个完整的python开发环境。
环境设置
确保使用python 3+。
pip安装以下软件包:
- flask (我们的python-web框架)
- flask_cors:用于 CORS 头信息。
- jsonify:使用flask返回JSON文件
- 其他根据需要的学习库,如numpy、pandas、sklearn等
pip install flask flask\_cors jsonify numpy pandas
数据流
下面是需要做的事情的总结:
- 使用Jupyter笔记本训练模型
- 将训练好的模型对象保存为一个pickle文件(序列化)
- 创建一个flask环境,该环境将有一个API端点,该端点将封装我们训练好的模型,并使其能够通过HTTP/HTTPS的GET请求接收输入(特征),然后在对早期序列化的模型进行去序列化后返回输出。
- 将flask脚本和训练好的模型一起上传到pythonanywhere。
- 通过网站、机器人、安卓应用或任何其他能够发送HTTP/HTTPS请求的应用向托管的flask脚本发出请求
机器学习模型
这篇文章的目的是部署一个模型,而不是创建它。让我们假设我们有一个模型,它把日期作为输入并预测比特币的价格。这个模型已经通过历史价格数据进行了训练。
模型数据流
如果你有兴趣了解这个模型,你可以参考我的github资源库。虽然,请注意!比特币的价格永远无法用机器学习来预测,这只是一个失败的尝试(这也是一个非常愚蠢的尝试),只是为了巩固这一点。这个模型的有效性不是这篇博文所关注的,所以我们现在只处理这个模型。序列化和去序列化的模型
Pickle
一个叫做pickle的模块帮助在python中执行序列化和反序列化。
序列化
简单地说,序列化是一种在磁盘上写一个Python对象的方法,它可以被传输到任何地方,然后由一个Python脚本反序列化(读取)回来。
以下是它是如何完成的。
运行上述代码后,一个名为 "mlp_nn.pkl"的文件被创建,它是训练好的模型,可以被转移到任何地方,并在去序列化后使用,如下所示。
去序列化
Flask设置
让我们首先在本地主机上设置flask服务器,然后在pythonanywhere上免费部署。
在本地主机上设置flask-app。
确保已经安装了flask。 pip install flask
下面的脚本在localhost和默认端口(5000)上启动flask服务器,制作URL:http://127.0.0.1:5000/
只要在浏览器上粘贴http://127.0.0.1:5000/,然后按回车键就可以看到服务器在工作。
- 应用程序路线
app.route 装饰器用于在网络上指定flask应用的路由。
"/" 仅仅意味着首页是"http://127.0.0.1:5000/"
"/price/" 表示http://127.0.0.1:5000/price/
- 参数
参数可以通过这些路由传递,如下所示:
[http://127.0.0.1:5000/price/?date=12&month=3&year=2019]
这些参数在flask脚本中被解析如下:
- request.args.get('date') 将返回12
- request.args.get('month') 将返回3
- request.args.get('year') 将返回2019年。
当你在浏览器中输入URL时,它实际上通过HTTP/HTTPS向指定的URL发送了一个GET请求。
在我们的案例中,我们向flask服务器发送了一个GET请求,参数包括日期、月份和年份,以获得我们模型的预测结果。
- jsonify
flask.jsonify() 函数将返回一个JSON格式的python字典。JSON格式可以被认为是一个可以任意嵌套的python字典,并通过网络传递。这是一种在应用程序之间共享数据的伟大方式。在处理网络API时,我们总是建议使用JSON格式。
- CORS
flask_cors 包用于修复用于AJAX调用的CORS头, ,使跨源AJAX成为可能。
旅行你可以在这里阅读更多关于CORS的信息,或者直接使用它。你不能忽视它,因为如果没有正确的 CORS 头信息,我们的 API 将无法被其他几乎所有的外部应用程序使用。我个人对 CORS 错误纠结了很久,不得不阅读 flask 和一些 web 开发文档,才想出了这个简单的解决方案。如果你有更好的方法来使用flask处理CORS头,请在回复中告诉我。
预测函数
上面的代码在 my_bitcoin_predictor 类中有一个预测函数,需要解释一下
Predict函数可以接受输入特征并输出模型的预测结果。这是使用python flask在网络上实际部署的函数。现在不是在同一环境下通过python脚本或IPy笔记本接收输入特征,而是通过网络服务器如flask在网络上接收特征,并返回预测结果。
为了简单起见,我跳过了my_bitcoin_predictor类中的很多部分,只写了重要的部分。
文件结构
一个简单的文件结构看起来像这样:
Bitcoin predictor
我还没有涵盖模型被历史数据训练的部分
名为Bitcoin predictor的文件夹是需要上传到pythonanywhere的。
托管flask应用
托管在localhost上的flask应用不能与他人共享,因为它是 "本地 "的。通过几个简单的步骤将脚本托管到一个免费的python托管网站pythonanywhere。
第1步:注册一个新的账户。
现在,让我们坚持使用免费账户。你可以购买更好的主机计划,以满足更多不同和复杂的需求。(在这个网站上有一个针对新用户的很好的导览,它将帮助你)。
第二步:添加一个新的Web应用
选择flask和你想要的任何一个Python版本。为了本教程,我将使用最新的Python 3.7。创建网络应用后,你会得到一个指向你的flask端点的URL。默认情况下,它将显示一条信息:"来自Flask的你好!"。你的端点看起来像这样。[用户名].pythonanywhere.com
第3步:安装依赖项
你的ML模型必须使用各种外部库,如sklearn、numpy、pandas等。在你的pythonanywhere环境中安装所有这些库。为此,打开一个新的bash控制台,使用pip安装库。确保用 pip 安装库时使用 用户选项,因为我们没有超级用户的权限。Flask已经被安装了,不需要再安装。
pip install --user flask_cors numpy pandas
第四步。 上传文件
在默认文件夹--/mysite/内,你需要上传你的完整文件夹。你可以使用网站上的文件页面或者使用bash控制台使用wget命令下载你的文件来完成。
第5步。 重新加载网络应用程序
你的端点现在将作为一个API,以方便其他应用程序。
一个前端应用的例子
你需要了解基本的HTML、CSS和JavaScript。
据观察,很多机器学习爱好者不喜欢网络开发,这就是为什么我创建了一个简单的模板,可以用来通过HTML表单接收输入特征,并向API发出请求以获取结果。即使你不精通HTML-CSS-JavaScript,你也可以轻松编辑这个模板。
这里是GitHub的仓库。
对于讨论中的例子,编辑后的JavaScript模板是这样的:
在线托管这个网站,我们就完成了!任何地方的人都可以使用这个网站来提交特征,并从位于后端的各种数据层下的ML模型中获得预测结果。
在个人服务器上托管
pythonanywhere仅用于教育目的,缺乏GPU。对于严重依赖CUDA和基于GPU计算的复杂深度学习模型,需要一个更强大的服务器。Flask在一个新的服务器上从头开始,使用像gunicorn这样的WSGI服务器,在像nginx这样的Web服务器后面,实现功能。也可以使用像supervisor这样的过程控制系统。
所有这些都需要一些Web开发的知识,写这些东西会让这篇文章变得过于冗长。这个网页帮助我第一次在我的服务器上设置flask。它真的很简单,而且写得非常好。
你也可以参考我的图像分类模型,该模型使用CUDA,托管在本地主机上。它展示了你如何使用flask处理图像文件并将其传递给模型。我很快就会写一篇完整的文章专门介绍它。
总结
托管和分享机器学习模型真的很容易。依靠机器学习模型的后端创建安卓应用、聊天机器人和更多的应用,现在可以非常容易地创建。