手把手教程:Linux服务器-flask部署深度学习模型

Linux服务器-flask部署深度学习模型

1.首先本地构建DL模型

根据自己的实际业务场景构建ML、DL模型,训练模型,并保存自己需要的模型,这里就不用过多赘述了。

2.本地跑通mac-将题目分类模型转换为Web应用程序

在原本的项目文件夹中新增如下几个文件:

app.py

templates/

        home.html

        result.html

static/

        style.css

如图:


目录

子目录templates是Flask在Web浏览器中查找静态HTML文件的目录。

2.1 app.py代码

from flask import Flask,render_template,url_for,request

from lstm_clf import get_title_text_label

app = Flask(__name__)

@app.route('/')

def home():

    return render_template('home.html')

@app.route('/predict',methods=['POST'])

def predict():

    if request.method == 'POST':

        message = request.form['message']

        y_label = get_title_text_label(message)

    return render_template('result.html',prediction = y_label)

if __name__ == '__main__':

    app.run(host='0.0.0.0', port=5018,debug=True)

app.py文件包含将由Python解释器执行以运行Flask Web应用程序的主代码

1、我们将应用程序作为单个模块运行,因此我们使用参数初始化了一个新的Flask实例,__name__是为了让Flask知道它可以在templates所在的同一目录中找到HTML模板文件夹()。

2、接下来,我们使用route decorator(@app.route('/'))来指定可以触发home 函数执行的URL 。我们的home 函数只是呈现home.htmlHTML文件,该文件位于templates文件夹中。

3、在predict函数内部,封装了一个get_title_text_label(text)函数,这个函数是对之前保存模型的封装及使用,通过访问用户输入信息,传入get_title_text_label(message)函数,就会对输入的数学题目文本进行分类,返回预测的分类标签。

4、我们使用该POST方法将表单数据传输到服务器。最后,通过debug=True在app.run方法中设置参数,进一步激活Flask的调试器。

5、最后,使用run函数执行在服务器上的脚本文件,我们需要确保使用if语句 __name__ == '__main__'。

2.2 home.html

以下是home.html将呈现文本表单的文件的内容,用户可以在其中输入数学题目文本:

<!DOCTYPE html>

<html>

<head>

    <title>Home</title>

    <!--<link rel="stylesheet" type="text/css" href="../static/styles.css">-->

    <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/styles.css') }}">

</head>

<body>

    <header>

        <div class="container">

        <div id="brandname">

            <h2 style="color:black;text-align:center;">Mathematical Problem Classifier</h2>

        </div>

    </div>

    </header>

    <div class="ml-container" >

        <form action="{{ url_for('predict')}}" method="POST">

        <p style="color:blue;font-size:20px;text-align:center;">Enter Your Mathematical Problem Here</p>

        <div style="display: flex;justify-content:center;flex-direction: column">

            <textarea name="message" rows="10" cols="100" style="align-self: center;color:black;font-size:14px;text-align:left;" placeholder="e.g. '{'main': '直线\\{\\begin{matrix}x=-2+t\\\\ y=1-t\\end{matrix}(t为参数)被圆(x-3)^{2}+(y+1)^{2}=25所截得的弦长为(  )', 'options': [], 'subquestions': []}'" ></textarea>

        <br/>

        <input type="submit" class="btn-info" value="predict" style="margin: 0 auto;font-size:18px;text-align:center;">

    </div>

    </form>

    </div>

</body>

</html>

2.3 style.css

在home.html的head部分,我们将加载styles.css文件,CSS文件是用于确定HTML文档的外观和风格的。styles.css必须保存在一个名为的子目录中static,这是Flask查找静态文件(如CSS)的默认目录。

body{

    font:15px/1.5 Arial, Helvetica,sans-serif;

    padding: auto;

    background-color:#f4f3f3;

}

.container{

    width:100%;

    margin: 0 auto;

    overflow: hidden;

}

header{

    background:#03A9F4;

    border-bottom:#448AFF 3px solid;

    height:120px;

    width:100%;

    padding-top:30px;

}

.main-header{

            text-align:center;

            background-color: blue;

            height:100px;

            width:100%;

            margin:0 auto;

        }

#brandname{

    float:left;

    font-size: 100px;

    color: #fff;

    /*margin: 10px;*/

}

header h2{

    text-align:center;

    color:#fff;

}

.btn-info {background-color: #2196F3;

    height:40px;

    width:100px;} /* Blue */

.btn-info:hover {background: #0b7dda;}

.resultss{

    border-radius: 15px 50px;

    background: #345fe4;

    padding: 20px;

    width: 200px;

    height: 150px;

}

2.4 result.html

我们创建一个result.html文件,该文件将通过函数render_template('result.html', prediction=my_prediction)返回呈现predict,我们在app.py脚本中定义该文件以显示用户通过文本字段提交的文本。result.html文件包含以下内容:

<!DOCTYPE html>

<html>

<head>

    <title></title>

    <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/styles.css') }}">

</head>

<body>

    <header>

        <div class="container">

        <div id="brandname">

            <h2 style="color:black;text-align:center;">Mathematical Problem Classifier</h2>

        </div>

    </div>

    </header>

    <p style="color:blue;font-size:20px;text-align:center;"><b>math tag:</b></p>

    <div class="results">

    <h2 style="color:blue;text-align:center;">{{prediction}}</h2>

    </div>

</body>

</html>

从result.htm文件我们可以看到一些代码使用通常在HTML文件中找不到的语法例如{{prediction}},这是jinja语法,它用于访问从HTML文件中请求返回的预测。

2.5 本地运行app.py

完成上述所有操作后,可以直接在pycharm中运行app.py文件,也可以在mac 终端中切换至项目目录,然后

python app.py

结果显示:

pycharm app.py 运行结果

点击网址进入,显示以下页面:


predict之后页面显示:


到这里就已经本地跑通flask部署web应用了。

2.6 其他

深入了解其原理,可参见以下文章:

https://www.cnblogs.com/sebastiane-root/p/9365248.html

https://segmentfault.com/a/1190000018807684

3.最后实现linux服务器部署

Linux常用命令:https://www.cnblogs.com/gaojun/p/3359355.html

3.1首先下载secureCRT 登陆服务器

详细Mac下安装SecureCRT并激活教程链接:

https://blog.csdn.net/gengxiaoming7/article/details/79433940

安装激活之后登陆

3.2打包项目文件zip,上传至服务器并解压

把自己项目文件打包成zip文件

在服务器上新建自己的文件夹:mkdir filename

zip文件包上传至自己的文件夹,  secureCRT可以使用 rz 和 sz 命令完成文件的上传和下载,rz上传时,自动跳出文件目录进行选择,选择相应文件进行选择即可。对于需要变更默认上传以及下载文件目录的,可以进行设置

中文版目录设置:  点开 secureCRT 的菜单项中的【选项】 --> 会话选项 --> 打开会话选项对话框 -->点击分类中的的终端 --> X/Y/Zmodem

英文版目录设置: Options --> session options --> terminal --> X/Y/Zmodem

对上传的zip包解压:

解压zip文件到当前目录 unzip filename.zip

3.3使用nohup启动flask服务

上面已经完成了项目文件的上传,接下来启动flask服务:

在并发量不大,仅是开发环境试用时,可以试用nohup启动服务,nohup命令详解链接:https://www.cnblogs.com/zq-inlook/p/3577003.html,下面简单介绍:

nohup保证部署的服务在退出SSH客户端后程序能一直执行

nohup /usr/local/python3.6/bin/python3  app.py &

2.执行nohup命令的时候,经常会出现下面这种没有写入权限的错误。

nohup: ignoring input and appending output to `nohup.out'

解决方案:https://www.cnblogs.com/quchunhui/p/5582371.html

在使用nohup命令的时候,经常由于输出nohup.out的路径没有写入权限,而无法使用nohup。

这是可以使用Linux重定向的方法,将nohup.out重定向至一个有写入权限的路径,或者直接扔到/dev/null中。

nohup ./program >/dev/null 2>/dev/null &

或者

nohup ./program >/dev/null 2>&1 &

本次使用的是:

nohup /usr/local/python3.6/bin/python3  app.py >/dev/null 2>&1 &

3. 到此为止,就已经完成服务器的flask服务部署了

访问网址就可以体验数学题目分类标签预测服务了:

IP地址:服务器的对外地址

端口号:5018是自己程序中设置的,未被占用的端口号

3.4其他1--关于端口号被占用的解决方案


端口号被占用

如果端口号被占用本次使用的是:

查看进程

ps -ef | grep python3

杀掉进程

kill -9 XXXX

详细链接:https://blog.csdn.net/weixin_42109679/article/details/80578778

关于LINUX中如何查看某个端口是否被占用:https://blog.csdn.net/yyf960126/article/details/80908823

这样就可以在app.py中设置不被占用的端口号

#查看该端口号是否被占用

netstat  -anp  |grep   端口号

#该命令是查看当前所有已经使用的端口情况

netstat   -nultp

3.5 其他2--关于Python2与Python3出现冲突的问题

如果使用pip install jieba,在服务器上会默认安装至Python2,但是我们平时使用的是Python3,所以使用如下命令执行:

/usr/local/python3.6/bin/pip install --user jieba

为什么使用--user,也是为了解决 Permission denied这个问题,防止pip安装报错

对于Python执行程序时,也是使用:

/usr/local/python3.6/bin/python3 XX.py

3.6 其他3--对并发,进程,线程有要求时,可以使用uwsgi 启动flask 服务方式

添加 app.ini文件

代码如下:

[uwsgi]

master = true

http=0.0.0.0:5018

chdir =项目文件夹地址

wsgi-file=app.py

callable=app

processes=4

threads=2

buffer-size = 65536

socket-timeout = 240

uid = work

gid = work

protocol = uwsgi

详细解释,参考链接:https://www.runoob.com/python3/python-uwsgi.html

https://blog.csdn.net/u013421629/article/details/84103873

相关参数解释:

master = true

#启动主进程,来管理其他进程,其它的uwsgi进程都是这个master进程的子进程,如果kill这个master进程,相当于重启所有的uwsgi进程。

chdir = /web/www/mysite

#在app加载前切换到当前目录, 指定运行目录

socket = /test/myapp.sock

#指定socket文件,也可以指定为127.0.0.1:9000,这样就会监听到网络套接字

processes = 2 #启动2个工作进程,生成指定数目的worker/进程

buffer-size = 32768

#设置用于uwsgi包解析的内部缓存区大小为64k。默认是4k。

服务器中启动方式

/usr/local/python3.6/bin/uwsgi app.ini

停止:

-- 停止 uwsgi

pkill -f -9 uwsgi

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容