前言
學歷與定位
近日在某論壇,有網友提問道:搞機器學習是不是要博士或是碩士學歷,是不是要求很高,頂會論文?本科生或者更低學歷的,是不是就沒有機會了?從最近公司的招聘來看,演算法工程師的 bar 確實有在提高。但在某些事業部,仍需要很大的人力來做落地場景。每個人都要找準自己的定位,公司也有它的部門定位。如果是發論文、要在學術界站穩腳跟,給投資人“我們很重視最新技術”的信心,那博士確實很重要。另一個角度,從實用角度來說,研究生和本科生可能價效比更高。當然,作為一個小本就工作的人,沒有較為豐富的實戰經驗,有機會的話,還是拿到碩士及更高學歷比較好。這裡的實戰經驗就比如:搭建一個完整的、涉及演算法模型、後端及前端的系統。
模型演算法的實用主義
機器學習的實用主義,不是在論文多少,而是用正確的方法去解決正確的問題。而作為背後的工程師,除了調參、除了寫 sql,做調包俠、做 sql boy、報表 boy 以外,在之前的文章也提到過,要學會做正確的展示,做全套的工程化實施。畢竟,等排期很難受;有些情況前後端資源不夠,或者優先順序很低,那就需要自己動手了。以下以上面的垃圾郵件分類為例子,說明該如何搭建一個前後端完整的機器學習系統。
關注微信公眾號:穀粒先生,下載權重檔案並第一時間獲取更新。
這裡將本次的任務拆解,分為三個部分來講。後端 flask、前端 Vue、ML 模型採用 flair,專案地址 kuhung/flask_vue_ML
後端 flask
相關依賴的安裝
pip install -r requirements.txt
核心函式
- 匯入函式包
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) # 對請求做資料預處理
classifier.predict(sentence) # 呼叫模型,做預測,返回帶標籤的資料
text = sentence.to_plain_string() # 解析出原始資料
label = sentence.labels[0] # 解析出標籤
result = {'title' : text, 'tag' : label.value} # 拼接成字典格式
session['my_result'] = result # 存入 session ,以減少重複請求對模型的壓力
return jsonify(result) # 返回 json 格式的資料
if __name__ == '__main__':
app.run(debug=True) # 開發過程中開啟 debug 除錯模式
複製程式碼
啟動服務
python app.py
前端 vue
前端採用 Vue 框架,與後端分離。使用 Webpack 進行資源管理與打包。
相關依賴的安裝
npm install -g vue-cli
npm install
複製程式碼
自定義元件
通過 vue init webpack flask_vue_ML
後,進入專案資料夾,增加自定義內容。
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
這裡定義頁面的基本樣式,以及獲取資料的邏輯。
<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>
<!-- 省略表格定義內容 -->
<script>
// 這裡解決跨域請求問題,向後端發起請求
import axios from 'axios'
export default {
data () {
return {
textClassify: [],
id: '',
taskname: '',
isEdit: false
}
},
mounted () {
this.getTasks()
},
// 省略進度條內容
// 請求任務相關操作
getTasks () {
axios({ method: 'GET', url: '/api/tasks' }).then(
result => {
console.log(result.data)
this.textClassify = result.data
},
error => {
console.error(error)
}
)
},
</script>
```
複製程式碼
index.js
定義路由,設定訪問路徑,並將路徑和元件關聯
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 年底釋出,易用性和效果都較前方案有了較大提升。這裡直接採用官方樣例訓練好的垃圾郵件分類模型的權重,也就是在上文後端所讀取的檔案。關注我的公眾號:穀粒先生,回覆權重,即可獲得權重檔案?連結。
模型呼叫
from flair.models import TextClassifier # 模型匯入,採用前不久開源的 flair 做文字分類
from flair.data import Sentence
classifier = TextClassifier.load_from_file('models/best-model.pt') # 模型載入
sentence = Sentence(title) # 對請求做資料預處理
classifier.predict(sentence) # 呼叫模型,做預測,返回帶標籤的資料
複製程式碼
效果展示
本教程針對文字分類這個場景,構建了一套前後端分離的“完整”框架,能夠給到一個最直觀的感受。當然,這裡還有很多優化空間,還有後續部署等事宜沒有詳細展開,有心的同學可以自行檢索學習。通過這套流程,可以在測試服搭建一套實用主義哲學的演算法模型。給到領導做展示或是公司內部使用,已經足夠。專案地址 kuhung/flask_vue_ML
終端端網站訪問
關注微信公眾號:穀粒先生,下載權重檔案並第一時間獲取更新。
喜歡我的朋友,別忘了點贊 ?、喜歡 ❤ +關注 ?哦,你的鼓勵是對我最大的支援~?