在深度學(xué)習(xí)更講究實(shí)用和落地的今天,構(gòu)建一個(gè)簡(jiǎn)單的,可以利用瀏覽器和后端交互的演示性 Demo 可以說(shuō)非常重要且實(shí)用了。本文我們將簡(jiǎn)單的介紹如何用幾十行核心代碼構(gòu)建一個(gè)好用的、前后端分離的Demo。2020年,可以說(shuō)真的是流年不利。對(duì)于人工智能行業(yè)來(lái)說(shuō),本來(lái)就面臨著落地考驗(yàn),再加上疫情打擊,很多 AI 企業(yè)甚至面臨現(xiàn)金流壓力。今天元峰得知,“CV四小龍”中兩家,竟然以疫情和集中入職為借口,阻止4月份畢業(yè)的碩士應(yīng)屆生入職,讓他們推遲到6月份入職,變相讓應(yīng)屆生主動(dòng)毀約?;蛟S,他們真的是面臨很大現(xiàn)金流壓力了。 唇亡齒寒,整個(gè)行業(yè)不好,瞬間讓筆者也打了個(gè)冷戰(zhàn)。作為 AI 領(lǐng)域的一個(gè)小小創(chuàng)業(yè)者,衷心希望中國(guó)所有的人工智能公司都能走過(guò)黎明前的黑暗,走向產(chǎn)品大規(guī)模落地的美好明天。 我們這篇文章還是要介紹技術(shù)的,我們開始言歸正傳吧。 1. 為什么要做前后端分離的演示Demo話說(shuō),在2020年,深度學(xué)習(xí)必須要非常講究落地了。在 AIZOO 成立后這段時(shí)間,也有不少客戶聯(lián)系我們合作事宜,其中一個(gè)重要的環(huán)節(jié)就是效果演示。在各種演示方式中,最便捷的就是讓用戶在瀏覽器訪問(wèn)一個(gè)網(wǎng)頁(yè),用戶可以自如上的上傳圖片,服務(wù)器返回結(jié)果,這是最簡(jiǎn)單的。 這里再插播一些題外話,我們?cè)?nbsp;http://AIZOO.com 部署了一些利用TensorFlow.js 庫(kù)(以下簡(jiǎn)稱 TF.js )做的 Demo,但是使用 TF.js 部署,需要把模型下載到用戶的瀏覽器里面運(yùn)算,對(duì)于一些可能要保密的模型,這種方法就無(wú)法使用了。我們?cè)陂_源口罩的 基于TF.js 演示頁(yè)面后,筆者在網(wǎng)站后臺(tái)看到很多網(wǎng)友把我們的網(wǎng)站扒的一絲不掛,甚至不少開發(fā)者去掉我們的 Logo,部署到了他們的網(wǎng)站上。 對(duì)于將模型部署到服務(wù)端,一個(gè)最簡(jiǎn)單的例子就是使用 Flask 框架。Flask 是一個(gè)極其簡(jiǎn)單的,使用 Python編寫的輕量級(jí) Web 框架, 該框架的使用方法極為簡(jiǎn)單,這點(diǎn),對(duì)于后端開發(fā)不太熟悉的算法工程師,可以說(shuō)是非常友好了。 這里有一個(gè)圖像分類的簡(jiǎn)單例子,大家可以感受一下 Flask 后端接受一張圖片請(qǐng)求,然后返回結(jié)果的方法有多么簡(jiǎn)單。
可以說(shuō)這樣一個(gè)處理邏輯,一目了然,與我們寫的 Python 前傳的代碼差異很小,學(xué)習(xí)起來(lái)很容易。 當(dāng)然,這只是一個(gè)純后端的簡(jiǎn)單 Demo,為了方便演示,我們需要有一個(gè)前端的頁(yè)面。筆者在 Github 上發(fā)現(xiàn)了很多基于 Flask的深度學(xué)習(xí)演示 Demo,不管是用PyTorch、TF、MXNet還是什么推理框架,他們有一個(gè)共同點(diǎn),那就是基本都是用的Flask的模板頁(yè)面做的。 關(guān)于模板頁(yè)面這種方法,也就是比較典型的前后端不分離的方法,在后端渲染好前端的 HTML 頁(yè)面,把結(jié)果作為參數(shù)傳給模板的占位符,大家可以感受一下,下面的代碼,就是將分類的額 class_id 和 class_name 傳給 HTML 頁(yè)面,渲染一個(gè)新的頁(yè)面。
筆者基本不怎么會(huì)前端開發(fā),但是總感覺這種方式非常不優(yōu)雅,主要是前后端是綁定的。雖然這種方法很簡(jiǎn)單,我們 AIZOO 的合伙人,大概五分鐘就做出來(lái)了一個(gè)使用這種模板的目標(biāo)檢測(cè)演示 Demo。(關(guān)于這位大佬有多牛,大家可以感受一下,http://AIZOO.com 是他一個(gè)人利用28天的下班空閑時(shí)間開發(fā)出來(lái)的,前端、后端、管理端三端一個(gè)人搞定, 等我們后面成功了,可以介紹一下元峰的這位朋友,也是我們的合伙人,有多硬核?。?/p> 這種前后端綁定的樣子,筆者不太喜歡,所以筆者就自己學(xué)習(xí)了一下前后端交互,才發(fā)現(xiàn)其實(shí)挺簡(jiǎn)單的,幾十行搞定。 下面,我們介紹一下如何做到前后端分離的一個(gè)簡(jiǎn)單 Demo, 真的非常簡(jiǎn)單。 2. 后端代碼 這里的后端還是使用 Flask 框架, 后端的邏輯非常簡(jiǎn)單,與剛才的例子基本無(wú)異,只需要將前端發(fā)過(guò)來(lái)的 base64 編碼的圖片解碼,轉(zhuǎn)成 PIL 的圖像對(duì)象,再使用 numpy 轉(zhuǎn)為矩陣,進(jìn)行目標(biāo)檢測(cè)的前傳,可以說(shuō)是非常簡(jiǎn)單了。核心代碼如下:
其中inference() 函數(shù)就是進(jìn)行目標(biāo)檢測(cè)的一個(gè)函數(shù),我們使用TensorFlow進(jìn)行推理,您可以將其替換為PyTorch、MXNet等任意你喜歡的框架。限于篇幅,目標(biāo)檢測(cè)代碼就不展示了,我們將其開源在 Github 上,大家可以去下載查看。 這里,返回給前端的是一個(gè) JSON 字典,如下所示,前端只需在接收這個(gè)以后,將 Bounding Box 畫在網(wǎng)頁(yè)的 Canvas 控件即可。
3. 前端怎么做? 對(duì)于網(wǎng)頁(yè)的前端,只需要設(shè)置一個(gè) Button 按鈕控件,用戶點(diǎn)擊上傳圖片以后,將其發(fā)送到后端,等接收到結(jié)果以后,將結(jié)果畫到 Canvas 上即可。 對(duì)于前后端交互,我們使用了 jQuery 中的 ajax 技術(shù)。ajax 是一種簡(jiǎn)單的進(jìn)行前后端交互式技術(shù),而 jQuery 庫(kù)封裝了很多常用的 JavaScript 方法, 使用起來(lái)非常簡(jiǎn)單。大家不要被這兩個(gè)術(shù)語(yǔ)嚇住了,我們的代碼中,用到他們的地方也就十幾行,請(qǐng)看下面代碼:
我們只需要將接收到的 base64 編碼的圖片,使用 ajax發(fā)送到 指定的 URL, 這里是本地的 5000 端口。然后在done函數(shù)中添加回調(diào),也即是處理返回結(jié)果的函數(shù),這里的drawResult()函數(shù),也就是將返回的 JSON 結(jié)果,畫到canvas控件上。其實(shí),整個(gè)前端的核心代碼,也就是前后端交互的核心,就在這 11 行代碼中。 關(guān)于怎么畫結(jié)果,以及 HTML 如何寫,也都是十幾行代碼搞定的事情。這里就不展示了。大家可以去Github上下載我們的代碼,簡(jiǎn)單查看一下就可以了。真的代碼很少、很簡(jiǎn)單。 4. 如何運(yùn)行 大家將代碼從 Github 下載后,在本地只需要運(yùn)行后端和前端就可以了。 app.py是后端的代碼入口,大家只需要python app.py就可以運(yùn)行起來(lái)了。注意這里大家要先裝好 Flask 和 TensorFlow 1.x版本(1.8 ~1.15應(yīng)該都可以),沒(méi)有的話,只需要用 pip 安裝一下就可以了。
對(duì)于前端部分,index.html 是入口文件,運(yùn)行也很簡(jiǎn)單,如果你使用Python,只需要如下操作:
如果你使用 node.js ,只要如下操作:
然后在瀏覽器打開終端顯示的 ip:port 就可以了。頁(yè)面長(zhǎng)這個(gè)樣子: 你可以點(diǎn)擊按鈕上傳,也可以將圖片直接拖到頁(yè)面,下面是一個(gè)簡(jiǎn)單的小動(dòng)畫。 ![]() |
|
來(lái)自: python_lover > 《待分類》