AI应用开发实战系列之四 - 定制化视觉服务的使用
AI應(yīng)用開發(fā)實(shí)戰(zhàn) - 定制化視覺服務(wù)的使用
本篇教程的目標(biāo)是學(xué)會使用定制化視覺服務(wù),并能在UWP應(yīng)用中集成定制化視覺服務(wù)模型。
前一篇:AI應(yīng)用開發(fā)實(shí)戰(zhàn) - 手寫識別應(yīng)用入門
建議和反饋,請發(fā)送到
https://github.com/Microsoft/vs-tools-for-ai/issues
聯(lián)系我們
OpenmindChina@microsoft.com
零、定制化視覺服務(wù)簡介
有的時(shí)候,在構(gòu)建應(yīng)用的過程中,在缺少強(qiáng)大計(jì)算資源與高性能算法的情況下,我們不一定需要自己從零開始訓(xùn)練模型。我們需要用的一些輪子,已經(jīng)有人給我們造好了。
就比如:
微軟提供的定制化視覺服務(wù)。
在機(jī)器學(xué)習(xí)應(yīng)用中,任何情況下都需要一個(gè)或大或小的模型。而怎么得到這個(gè)模型是其中最復(fù)雜的部分。定制化視覺服務(wù)相當(dāng)于在云端提供了一個(gè)生成模型的方法,把模型相關(guān)的復(fù)雜的算法都簡化了。同時(shí),它不僅能夠讓用戶自己管理訓(xùn)練數(shù)據(jù),定義自己的分類問題,而且支持一鍵訓(xùn)練,一鍵導(dǎo)出模型;不僅能導(dǎo)出適配所有主流框架的模型,而且可以生成REST接口,讓程序通過接口獲取圖片分類的結(jié)果。這樣給用戶提供了多種集成模型的方法和選擇,盡可能滿足用戶的各種需求,這也正是定制化視覺服務(wù)的強(qiáng)大之處。同時(shí),通過定制化服務(wù)來生成模型,需要的數(shù)據(jù)量可以非常少,訓(xùn)練過程相對來說也很快。使用上也是非常的方便。
本篇教程,就教大家如何使用定制化視覺服務(wù)。
定制化視覺服務(wù)官方地址 :https://customvision.ai/
一、準(zhǔn)備微軟賬號
使用該服務(wù)需要準(zhǔn)備微軟賬號,可以直接在定制化視覺服務(wù)官方地址上創(chuàng)建。
二、創(chuàng)建定制化視覺服務(wù)
| 進(jìn)入官方網(wǎng)站,點(diǎn)擊SIGN IN,目前定制化視覺服務(wù)提供了免費(fèi)試用版,可以體驗(yàn)定制化視覺服務(wù)。 | |
| 登錄后,然后界面會提示要求同意一些條約。 條約的大致內(nèi)容就是,個(gè)人必須在微軟要求的規(guī)則下使用微軟提供的這項(xiàng)服務(wù)。請勾選agree | |
| 此時(shí),界面會提示注冊Azure,因?yàn)槎ㄖ苹曈X服務(wù)實(shí)際上是Azure提供的一項(xiàng)云服務(wù),正式使用這項(xiàng)服務(wù)需要有Azure訂閱。 不過我們現(xiàn)在只是免費(fèi)試用,所以選擇Continue With trial,如果在根據(jù)這篇博客流程做完了一個(gè)小應(yīng)用之后,你覺得確實(shí)需要使用這項(xiàng)服務(wù),那么你可以去注冊Azure賬號,獲取Azure訂閱。 |
三、創(chuàng)建定制化視覺服務(wù)項(xiàng)目
點(diǎn)擊New Project,填寫項(xiàng)目信息。
這里不妨以一個(gè)熊的分類模型作為例子來實(shí)踐吧。
填寫好Name和Description,這里Name不妨填寫為BearClassification。
隨后選擇Classification和General(compact),點(diǎn)擊Create
| 在Project Type一欄,定制化視覺服務(wù)提供了識別和分類兩種服務(wù),另外提供了多種識別場景,其中末尾帶有(compact),也即壓縮字樣的三種。 壓縮模型,顧名思義,模型占用的空間更少,運(yùn)行更快,甚至可以放到手機(jī)這種移動設(shè)備里。 當(dāng)然,會有一個(gè)小問題就是精確度會受影響。導(dǎo)出模型后,模型文件的使用是沒有任何限制的,而其余的幾種場景只能通過調(diào)用API來進(jìn)行預(yù)測,由于當(dāng)前屬于免費(fèi)試用,因此這種方式有10000次調(diào)用上限。 | |
| 由于分類服務(wù)需要準(zhǔn)備用來訓(xùn)練的數(shù)據(jù)集,請自行準(zhǔn)備幾種不同的熊的照片,將同種的熊放在以這種熊的名字命名的文件夾里,最后再將這些文件夾放在一個(gè)data文件夾中。然后點(diǎn)擊Add images | |
| 選擇一種熊的全部照片,然后創(chuàng)建對應(yīng)的標(biāo)簽,點(diǎn)擊Up load xxx files | |
| 在添加了所有的數(shù)據(jù)集和標(biāo)簽之后,點(diǎn)擊網(wǎng)頁上方的Train,開始訓(xùn)練模型。 | |
| 一小會之后,點(diǎn)擊網(wǎng)頁上方的performance,就可以看到這次訓(xùn)練的結(jié)果了。 這里簡單解釋一下Precision和Recall,這是兩個(gè)評估模型好壞的主要指標(biāo)。 簡單來說,兩個(gè)數(shù)都是越大越好。在這個(gè)項(xiàng)目中,以Brown Bear為例: Precision就是識別出來的結(jié)果的準(zhǔn)確率,即在所有被識別為棕熊的圖片中真正有棕熊的圖片所占的比例;而Recall則是測試結(jié)果中正確識別為棕熊的圖片占測試集中所有棕熊圖片的比例。 | |
| 這時(shí)再點(diǎn)擊界面右上角的齒輪,可以看到免費(fèi)用戶每個(gè)項(xiàng)目能夠使用的服務(wù)額度: 一共可以上傳5000張圖片,創(chuàng)建50個(gè)不同標(biāo)簽,保存10次迭代的結(jié)果。 這十次迭代有什么用呢?當(dāng)需要增刪標(biāo)簽、給標(biāo)簽添加或刪除訓(xùn)練圖片時(shí),這次再訓(xùn)練,就會花費(fèi)掉一次迭代。 這些都是當(dāng)前項(xiàng)目的總數(shù)而不是累計(jì)值。對于一般的免費(fèi)用戶,這基本上就相當(dāng)于你可以隨意使用這項(xiàng)服務(wù)了,如果有大量的訓(xùn)練數(shù)據(jù),那么建議您還是訂閱Azure云服務(wù),Azure秉持著使用多少,收費(fèi)多少的原則,即使收費(fèi),也仍然良心。 | |
| 然后選擇剛剛訓(xùn)練好的這次迭代,點(diǎn)擊Export。 視覺認(rèn)知服務(wù)一共提供了適用于四種平臺的模型導(dǎo)出,對三大操作系統(tǒng)都能支持。 選擇ONNX,這個(gè)格式由微軟、臉書、亞馬遜等大廠鼎力支持,點(diǎn)擊Export,等待服務(wù)器把模型導(dǎo)出,然后點(diǎn)擊Download,即可下載模型。最后得到了一個(gè).onnx文件,然后就可以使用它來構(gòu)建應(yīng)用了。 |
如果需要上傳大量的圖片數(shù)據(jù),那么點(diǎn)擊鼠標(biāo)的方式肯定不夠方便,微軟同時(shí)提供了代碼的支持,詳見官方文檔:
https://docs.microsoft.com/en-us/azure/cognitive-services/custom-vision-service/home
四、使用Windows ML構(gòu)建應(yīng)用
這次不寫Winform程序,而是搭建一個(gè)識別熊的UWP的AI應(yīng)用,通過這個(gè)應(yīng)用來教大家如何使用Windows ML導(dǎo)入模型。
這部分的代碼已經(jīng)完成了,請使用git克隆samples-for-ai到本地,UWP項(xiàng)目的代碼在/samples-for-ai/projects/BearClassificationUWPDemo中。
在運(yùn)行代碼之前,請先安裝開發(fā)UWP所需的工作負(fù)載,流程如下:
另外,請將您的操作系統(tǒng)更新到1803版本,否則本程序?qū)⒉荒馨惭b。
如果您將進(jìn)行類似的開發(fā),請將UWP項(xiàng)目設(shè)置成最低運(yùn)行目標(biāo)版本為17134,否則對于版本低于17134的用戶,在運(yùn)行時(shí)會出現(xiàn):
“Requested Windows Runtime type ‘Windows.AI.MachineLearning.Preview.LearningModelPreview’ is not registered.”
詳見:https://github.com/MicrosoftDocs/windows-uwp/issues/575
安裝需要的時(shí)間比較長,可以先看看UWP的視頻教程,做一做頭腦預(yù)熱: https://www.bilibili.com/video/av7997007
Visual Studio 和 Windows 更新完畢后,我們打開CustomVisionApp.sln,運(yùn)行這個(gè)程序。
你可以從必應(yīng)上查找一些熊的圖片,復(fù)制圖片的URL,粘貼到輸入框內(nèi),然后點(diǎn)擊識別按鈕;或者,點(diǎn)擊瀏覽按鈕,選擇一張本地圖片,點(diǎn)擊確定,你就可以看到識別結(jié)果了:
現(xiàn)在來看看這個(gè)程序是怎么實(shí)現(xiàn)的。
我們來梳理一下這個(gè)應(yīng)用的邏輯,這個(gè)應(yīng)用的邏輯與上一篇博客中的手寫數(shù)字識別大體上是一樣的:
1. 文件結(jié)構(gòu):
文件結(jié)構(gòu)見下圖:
- Assets文件夾存放了這個(gè)項(xiàng)目的資產(chǎn)文件,比如程序圖標(biāo)等等,在本示例程序中,.onnx文件也存放在其中。
- Strings文件夾存放了用于本地化與全球化資源文件,這樣可以支持不同的語言。
- ViewModel文件夾中則存放了本項(xiàng)目的關(guān)鍵代碼,整個(gè)程序運(yùn)行的邏輯都在ResultViewModel.cs中
- BearClassification.cs則是系統(tǒng)自動生成的模型包裝文件
- MainPage.xaml是程序的UI布局文件
2. 核心代碼一:BearClassification.cs
這部分的代碼是自動生成的,教程詳見鏈接:https://docs.microsoft.com/zh-cn/windows/uwp/machine-learning/
生成的文件共有三個(gè)類:
- BearClassificationModelInput:定義了該模型的輸入格式是VideoFrame
- BearClassificationModelOutput:定義了該模型的輸出為一個(gè)list和一個(gè)dict,list存儲了所有標(biāo)簽按照probability降序排列,dict則存儲了標(biāo)簽與概率的鍵值對
- BearClassificationModel:定義了該模型的初始化函數(shù)與推理函數(shù)
3. 核心代碼二:ResultViewModel.cs
通過之前的運(yùn)行可以發(fā)現(xiàn):每次識別圖片,UI中的內(nèi)容需要進(jìn)行頻繁地更新,為了簡化更新控件內(nèi)容的代碼邏輯,這個(gè)程序使用UWP開發(fā)中常用的MVVM(model-view-viewmodel)這一組合模式開發(fā),使用“綁定”的方式,將UI控件與數(shù)據(jù)綁定起來,讓數(shù)據(jù)與界面自動地同步更新,簡化了代碼邏輯,保證了ResultViewModel職責(zé)單一。
| string BearUrl | TextBox InputUriBox |
| ObservableCollection Results | ListView ResultArea |
| BitmapImage BearImage | Image DisplayArea |
| string Description | TextBox DescribeArea |
| ICommand RecognizeCommand | Button RecognizeButton |
| ICommand BrowseCommand | Button BrowseButton |
綁定好之后,程序還需要一系列邏輯才能運(yùn)行,這里就包括:
導(dǎo)入與初始化模型:
在程序一開始,需要調(diào)用LoadModel進(jìn)行模型初始化工作。
private async void LoadModel() {//導(dǎo)入模型文件,實(shí)例化模型對象StorageFile modelFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/BearClassification.onnx"));model = await BearClassificationModel.CreateBearClassificationModel(modelFile); }圖片推理:
本程序提供了兩種方式訪問圖片資源:
五、使用其他方法構(gòu)建應(yīng)用
同樣,用之前使用Visual Studio Tools for AI提供的推理類庫生成器也能夠構(gòu)建相似的應(yīng)用。想看視頻教程的請移步:
【教程】普通程序員一小時(shí)入門AI應(yīng)用——看圖識熊(不含公式,包會)
該教程講解了如何使用模型瀏覽工具Netron
想看圖文教程請繼續(xù)往下看:
1. 界面設(shè)計(jì)
創(chuàng)建Windows窗體應(yīng)用(.NET Framework)項(xiàng)目,這里給項(xiàng)目起名ClassifyBear。
注意,項(xiàng)目路徑不要包含中文。
在解決方案資源管理器中找到Form1.cs,雙擊,打開界面設(shè)計(jì)器。從工具箱中向Form中依次拖入控件并調(diào)整,最終效果如下圖所示:
左側(cè)從上下到依次是:
- Label控件,將內(nèi)容改為“輸入要識別的圖片地址:”
- TextBox控件,可以將控件拉長一些,方便輸入U(xiǎn)RL
- Button控件,將內(nèi)容改為“識別”
- Lable控件,將label的內(nèi)容清空,用來顯示識別后的結(jié)果。因?yàn)閘abel也沒有邊框,所以在界面看不出來。可以將此控件的字體調(diào)大一些,能更清楚的顯示推理結(jié)果。
右側(cè)的控件是一個(gè)PictureBox,用來預(yù)覽輸入的圖片,同時(shí),我們也從這個(gè)控件中取出對應(yīng)的圖片數(shù)據(jù),傳給我們的模型推理類庫去推理。建議將控件屬性的SizeMode更改為StretchImage,并將控件長和寬設(shè)置為同樣的值,保持一個(gè)正方形的形狀,這樣可以方便我們直觀的了解模型的輸入,因?yàn)樵谇懊娌榭茨P托畔⒌臅r(shí)候也看到了,該模型的輸入圖片應(yīng)是正方形。
2. 查看模型信息
在將模型集成到應(yīng)用之前,我們先來看一看模型的基本信息,比如模型需要什么樣的輸入和輸出。打開Visual Studio中的AI工具菜單,選擇模型工具下的查看模型,會啟動Netron模型查看工具。該工具默認(rèn)不隨Tools for AI擴(kuò)展一起安裝,第一次使用時(shí)可以按照提示去下載并安裝。
Netron打開后,點(diǎn)擊Open model選擇打開之前下載的BearModel.onnx文件。然后點(diǎn)擊左上角的漢堡菜單顯示模型的輸入輸出。
上圖中可以看到該模型需要的輸入data是一個(gè)float數(shù)組,數(shù)組中要求依次放置227*227圖片的所有藍(lán)色分量、綠色分量和紅色分量,后面程序中調(diào)用時(shí)要對輸入圖片做相應(yīng)的處理。
上圖中還可以看到輸出有兩個(gè)值,第一個(gè)值loss包含所有分類的得分,第二個(gè)值classLabel是確定的分類的標(biāo)簽,這里只需用到第二個(gè)輸出即可。
3. 封裝模型推理類庫
由于目前模型推理用到的庫只支持x64,所以這里需要將解決方案平臺設(shè)置為x64。打開解決方案資源管理器,在解決方案上點(diǎn)右鍵,選擇配置管理器。
在配置管理器對話框中,點(diǎn)開活動解決方案平臺下拉框,選擇新建
在新建解決方案平臺對話框中,輸入新平臺名x64,點(diǎn)擊確定即可
下面添加模型推理類庫,再次打開解決方案資源管理器,在解決方案上點(diǎn)右鍵,選擇添加,然后選擇新建項(xiàng)目。
添加新項(xiàng)目對話框中,將左側(cè)目錄樹切換到AI Tools下的Inference,右側(cè)選擇模型推理類庫,下方填入項(xiàng)目名稱,這里用Model作為名稱。
確定以后會出現(xiàn)檢查環(huán)境的進(jìn)度條,耐心等待一會就可以出現(xiàn)模型推理類庫創(chuàng)建向?qū)υ捒颉?/p>
點(diǎn)擊模型路徑后面的瀏覽按鈕,選擇前面下載的BearModel.onnx模型文件。
注意,這里會出現(xiàn)幾處錯(cuò)誤提示,我們需要手動修復(fù)一下。首先會看到“發(fā)現(xiàn)不支持的張量的數(shù)據(jù)類型”提示,可以直接點(diǎn)確定。
確定后如果彈出“正在創(chuàng)建項(xiàng)目…”的進(jìn)度條,一直不消失,這里只需要在類名后面的輸入框內(nèi)點(diǎn)一下,切換下焦點(diǎn)即可。
然后,我們來手動配置一下模型的相關(guān)信息。類名輸入框中填入模型推理類的名字,這里用Bear。然后點(diǎn)擊推理接口右側(cè)的添加按鈕,在彈出的編輯接口對話框中,隨便起個(gè)方法名,這里用Infer。輸入節(jié)點(diǎn)的變量名和張量名填入data,輸出節(jié)點(diǎn)的變量名和張量名填入classLabel,字母拼寫要和之前查看模型時(shí)看到的拼寫一模一樣。然后一路確定,再耐心等待一會,就可以在解決方案資源管理器看到新建的模型推理類庫了。
還有一處錯(cuò)誤需要手動修復(fù)一下,切換到解決方案資源管理器,在Model項(xiàng)目的Bear目錄下找到Bear.cs雙擊打開,將函數(shù)Infer的最后一行
return r0;替換為
List<List<string>> results = new List<List<string>>(); results.Add(r0); return results;至此,模型推理類庫封裝完成。相信Tools for AI將來的版本中會修復(fù)這些問題,直接選擇模型文件創(chuàng)建模型推理類庫就可以了。
4. 使用模型推理類庫
首先添加對模型推理類庫的引用,切換到解決方案資源管理器,在ClassifyBear項(xiàng)目的引用上點(diǎn)右鍵,選擇添加引用。
在彈出的引用管理器對話框中,選擇項(xiàng)目、解決方案,右側(cè)可以看到剛剛創(chuàng)建的模型推理類庫,勾選該項(xiàng)目,點(diǎn)擊確定即可。
在Form1.cs上點(diǎn)右鍵,選擇查看代碼,打開Form1.cs的代碼編輯窗口。
添加兩個(gè)成員變量
// 使用Netron查看模型,得到模型的輸入應(yīng)為227*227大小的圖片 private const int imageSize = 227;// 模型推理類 private Model.Bear model;回到Form1的設(shè)計(jì)界面,雙擊Form的標(biāo)題欄,會自動跳轉(zhuǎn)到代碼頁面并添加了Form1_Load方法,在其中初始化模型推理對象
private void Form1_Load(object sender, EventArgs e) {// 初始化模型推理對象model = new Model.Bear(); }回到Form1的設(shè)計(jì)界面,雙擊識別按鈕,會自動跳轉(zhuǎn)到代碼頁面并添加了button1_Click方法,在其中添加以下代碼:
首先,每次點(diǎn)擊識別按鈕時(shí)都先將界面上顯示的上一次的結(jié)果清除
// 識別之前先重置界面顯示的內(nèi)容 label1.Text = string.Empty; pictureBox1.Image = null; pictureBox1.Refresh();然后,讓圖片控件加載圖片
bool isSuccess = false; try {pictureBox1.Load(textBox1.Text);isSuccess = true; } catch (Exception ex) {MessageBox.Show($"讀取圖片時(shí)出現(xiàn)錯(cuò)誤:{ex.Message}");throw; }如果加載成功,將圖片數(shù)據(jù)傳給模型推理類庫來推理。
if (isSuccess) {// 圖片加載成功后,從圖片控件中取出227*227的位圖對象Bitmap bitmap = new Bitmap(pictureBox1.Image, imageSize, imageSize);float[] imageArray = new float[imageSize * imageSize * 3];// 按照先行后列的方式依次取出圖片的每個(gè)像素值for (int y = 0; y < imageSize; y++){for (int x = 0; x < imageSize; x++){var color = bitmap.GetPixel(x, y);// 使用Netron查看模型的輸入發(fā)現(xiàn)// 需要依次放置227 *227的藍(lán)色分量、227*227的綠色分量、227*227的紅色分量imageArray[y * imageSize + x] = color.B;imageArray[y * imageSize + x + 1* imageSize * imageSize] = color.G;imageArray[y * imageSize + x + 2* imageSize * imageSize] = color.R;}}// 模型推理類庫支持一次推理多張圖片,這里只使用一張圖片var inputImages = new List<float[]>();inputImages.Add(imageArray);// 推理結(jié)果的第一個(gè)First()是取第一張圖片的結(jié)果// 之前定義的輸出只有classLabel,所以第二個(gè)First()就是分類的名字label1.Text = model.Infer(inputImages).First().First(); }注意,這里的數(shù)據(jù)轉(zhuǎn)換一定要按照前面查看的模型的信息來轉(zhuǎn)換,圖片大小需要長寬都是227像素,并且要依次放置所有的藍(lán)色分量、所有的綠色分量、所有的紅色分量,如果順序不正確,不能達(dá)到最佳的推理結(jié)果。
5. 測試
編譯運(yùn)行,然后在網(wǎng)上找一張熊的鏈接填到輸入框內(nèi),然后點(diǎn)擊識別按鈕,就可以看到識別的結(jié)果了。注意,這個(gè)URL應(yīng)該是圖片的URL,而不是包含該圖片的網(wǎng)頁的URL。
六、下一步?
本篇博客我們學(xué)會了使用定制化視覺服務(wù)與在UWP應(yīng)用中集成定制化視覺服務(wù)模型。這里我提兩個(gè)課后習(xí)題:(想不到吧)
當(dāng)訓(xùn)練含有多個(gè)標(biāo)簽、大量圖片數(shù)據(jù)時(shí),如何做到一鍵上傳圖片并訓(xùn)練?
如何通過調(diào)用REST接口的方式完成對圖片的推理?
提示:請看看定制化視覺服務(wù)給我們提供的API,這一題肯定是要寫代碼做的
https://docs.microsoft.com/en-us/azure/cognitive-services/custom-vision-service/home
加油!
七、內(nèi)容預(yù)告
接下來我們將會陸續(xù)推出:
請?jiān)谙路搅粞?#xff0c;告知我們您最想閱讀哪個(gè)教程,我們將優(yōu)先考慮。
如果您有別的想要了解的內(nèi)容,也可以在評論區(qū)留言。
總結(jié)
以上是生活随笔為你收集整理的AI应用开发实战系列之四 - 定制化视觉服务的使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 结对和团队项目建议 - 黄金点游戏
- 下一篇: AI应用开发基础傻瓜书系列3-激活函数