前言
學歷與定位
近日在某論壇,有網(wǎng)友提問道:搞機器學習是不是要博士或是碩士學歷搀玖,是不是要求很高余境,頂會論文?本科生或者更低學歷的灌诅,是不是就沒有機會了芳来?從最近公司的招聘來看,算法工程師的 bar 確實有在提高猜拾。但在某些事業(yè)部即舌,仍需要很大的人力來做落地場景。每個人都要找準自己的定位挎袜,公司也有它的部門定位顽聂。如果是發(fā)論文肥惭、要在學術界站穩(wěn)腳跟,給投資人“我們很重視最新技術”的信心紊搪,那博士確實很重要蜜葱。另一個角度,從實用角度來說耀石,研究生和本科生可能性價比更高牵囤。當然,作為一個小本就工作的人娶牌,沒有較為豐富的實戰(zhàn)經(jīng)驗奔浅,有機會的話,還是拿到碩士及更高學歷比較好诗良。這里的實戰(zhàn)經(jīng)驗就比如:搭建一個完整的汹桦、涉及算法模型、后端及前端的系統(tǒng)鉴裹。
模型算法的實用主義
機器學習的實用主義舞骆,不是在論文多少,而是用正確的方法去解決正確的問題径荔。而作為背后的工程師督禽,除了調(diào)參、除了寫 sql总处,做調(diào)包俠狈惫、做 sql boy、報表 boy 以外鹦马,在之前的文章也提到過胧谈,要學會做正確的展示,做全套的工程化實施荸频。畢竟菱肖,等排期很難受;有些情況前后端資源不夠旭从,或者優(yōu)先級很低稳强,那就需要自己動手了。以下以上面的垃圾郵件分類為例子和悦,說明該如何搭建一個前后端完整的機器學習系統(tǒng)退疫。
關注微信公眾號:谷粒先生,下載權重文件并第一時間獲取更新鸽素。
這里將本次的任務拆解蹄咖,分為三個部分來講。后端 flask付鹿、前端 Vue澜汤、ML 模型采用 flair,項目地址 kuhung/flask_vue_ML
后端 flask
相關依賴的安裝
pip install -r requirements.txt
核心函數(shù)
- 導入函數(shù)包
from flask import Flask, jsonify, request
from flask_cors import CORS # 做跨域的準備
from flask import session # 追蹤客戶端會話
from flair.models import TextClassifier # 模型導入舵匾,采用前不久開源的 flair 做文本分類
from flair.data import Sentence
- 準備工作
app = Flask(__name__) # 聲明準備
app.secret_key = "super_secret_key"
CORS(app)
classifier = TextClassifier.load_from_file('models/best-model.pt') # 模型加載
- 配置 flask 的路由
# 根路由配置
@app.route('/', methods=['GET'])
def index():
return jsonify("welcome to Kuhung API")
# GET 方法俊抵,這里 session 的作用是追蹤客戶端會話,防止重復請求模型
@app.route('/api/tasks', methods=['GET'])
def get_result():
result = []
try:
data_result = session['my_result']
result.append ({'title': data_result['title'], 'tag': data_result['tag'] })
except:
result.append ({'title': 'The txt you input', 'tag': 'spam or ham' })
return jsonify(result)
# POST 方法
@app.route('/api/task', methods=['POST'])
def input_predict_text():
title = request.get_json()['title'] # 解析請求
sentence = Sentence(title) # 對請求做數(shù)據(jù)預處理
classifier.predict(sentence) # 調(diào)用模型坐梯,做預測徽诲,返回帶標簽的數(shù)據(jù)
text = sentence.to_plain_string() # 解析出原始數(shù)據(jù)
label = sentence.labels[0] # 解析出標簽
result = {'title' : text, 'tag' : label.value} # 拼接成字典格式
session['my_result'] = result # 存入 session ,以減少重復請求對模型的壓力
return jsonify(result) # 返回 json 格式的數(shù)據(jù)
if __name__ == '__main__':
app.run(debug=True) # 開發(fā)過程中開啟 debug 調(diào)試模式
啟動服務
python app.py
前端 vue
前端采用 Vue 框架吵血,與后端分離谎替。使用 Webpack 進行資源管理與打包。
相關依賴的安裝
npm install -g vue-cli
npm install
自定義組件
通過 vue init webpack flask_vue_ML
后蹋辅,進入項目文件夾钱贯,增加自定義內(nèi)容。
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>exposemodel</title>
</head>
<body>
<div id="app"></div>
<!-- 其它文件會自動注入這里 -->
</body>
</html>
src 文件夾
- components
- Home.vue // 自定義組件侦另,增加
- router
- index.js // 路由秩命,修改
- App.vue // 主組件,修改
- main.js // 入口文件褒傅,修改
Home.vue
這里定義頁面的基本樣式弃锐,以及獲取數(shù)據(jù)的邏輯。
<template>
<div id="todo-list-example" class="container">
<!-- 我是進度條殿托,最上方的 -->
<vue-progress-bar></vue-progress-bar>
<div class="row">
<div class="col-md-6 mx-auto">
<h1 class="text-center">Natural Language Processing (NLP)</h1>
<form v-on:submit.prevent="addNewTask">
<label for="tasknameinput">Spam Classification</label>
<input v-model="taskname" type="text" id="tasknameinput" class="form-control" placeholder="Enter Sentence">
<button type="submit" class="btn btn-success btn-block mt-3">
Submit
</button>
</form>
<!-- 省略表格定義內(nèi)容 -->
<script>
// 這里解決跨域請求問題霹菊,向后端發(fā)起請求
import axios from 'axios'
export default {
data () {
return {
textClassify: [],
id: '',
taskname: '',
isEdit: false
}
},
mounted () {
this.getTasks()
},
// 省略進度條內(nèi)容
// 請求任務相關操作
getTasks () {
axios({ method: 'GET', url: '/api/tasks' }).then(
result => {
console.log(result.data)
this.textClassify = result.data
},
error => {
console.error(error)
}
)
},
</script>
?```
index.js
定義路由,設定訪問路徑支竹,并將路徑和組件關聯(lián)
import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/components/Home'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'Home',
component: Home
}
]
})
App.vue
主組件
<template>
<div id="app">
<router-view/>
<!-- 植入一波廣告:微信搜索:谷粒先生旋廷,關注我的公眾號 -->
<img src="./assets/wechat.jpg">
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
main.js
初始化實例并加載必要插件
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import VueProgressBar from 'vue-progressbar'
require('../node_modules/bootstrap/dist/css/bootstrap.css')
Vue.config.productionTip = false
// 這是進度條
Vue.use(VueProgressBar, {
color: 'rgb(143, 255, 199)',
failedColor: 'red',
height: '10px'
})
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
啟動服務
npm run dev
模型 flair
模型這里采用 fair 框架,該框架在 2018 年底發(fā)布唾戚,易用性和效果都較前方案有了較大提升柳洋。這里直接采用官方樣例訓練好的垃圾郵件分類模型的權重,也就是在上文后端所讀取的文件叹坦。關注我的公眾號:谷粒先生熊镣,回復權重,即可獲得權重文件??鏈接募书。
模型調(diào)用
from flair.models import TextClassifier # 模型導入绪囱,采用前不久開源的 flair 做文本分類
from flair.data import Sentence
classifier = TextClassifier.load_from_file('models/best-model.pt') # 模型加載
sentence = Sentence(title) # 對請求做數(shù)據(jù)預處理
classifier.predict(sentence) # 調(diào)用模型,做預測莹捡,返回帶標簽的數(shù)據(jù)
效果展示
本教程針對文本分類這個場景鬼吵,構建了一套前后端分離的“完整”框架,能夠給到一個最直觀的感受篮赢。當然齿椅,這里還有很多優(yōu)化空間琉挖,還有后續(xù)部署等事宜沒有詳細展開,有心的同學可以自行檢索學習涣脚。通過這套流程示辈,可以在測試服搭建一套實用主義哲學的算法模型。給到領導做展示或是公司內(nèi)部使用遣蚀,已經(jīng)足夠矾麻。項目地址 kuhung/flask_vue_ML
終端端網(wǎng)站訪問
關注微信公眾號:谷粒先生,下載權重文件并第一時間獲取更新芭梯。
喜歡我的朋友险耀,別忘了點贊 ??、喜歡 ? +關注 ??哦玖喘,你的鼓勵是對我最大的支持~??