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