AI應用開發實戰系列之四 - 定製化視覺服務的使用

AI應用開發實戰 - 定製化視覺服務的使用

本篇教程的目標是學會使用定製化視覺服務,並能在UWP應用中集成定製化視覺服務模型。

前一篇:AI應用開發實戰 - 手寫識別應用入門

建議和反饋,請發送到
https://github.com/Microsoft/vs-tools-for-ai/issues

聯繫我們
[email protected]

零、定製化視覺服務簡介

有的時候,在構建應用的過程中,在缺少強大計算資源與高性能算法的情況下,我們不一定需要自己從零開始訓練模型。我們需要用的一些輪子,已經有人給我們造好了。

就比如:

微軟提供的定製化視覺服務。

在機器學習應用中,任何情況下都需要一個或大或小的模型。而怎麼得到這個模型是其中最複雜的部分。定製化視覺服務相當於在雲端提供了一個生成模型的方法,把模型相關的複雜的算法都簡化了。同時,它不僅能夠讓用戶自己管理訓練數據,定義自己的分類問題,而且支持一鍵訓練,一鍵導出模型;不僅能導出適配所有主流框架的模型,而且可以生成REST接口,讓程序通過接口獲取圖片分類的結果。這樣給用戶提供了多種集成模型的方法和選擇,儘可能滿足用戶的各種需求,這也正是定製化視覺服務的強大之處。同時,通過定製化服務來生成模型,需要的數據量可以非常少,訓練過程相對來說也很快。使用上也是非常的方便。

本篇教程,就教大家如何使用定製化視覺服務。

定製化視覺服務官方地址 :https://customvision.ai/

一、準備微軟賬號

使用該服務需要準備微軟賬號,可以直接在定製化視覺服務官方地址上創建。

二、創建定製化視覺服務

截圖 操作
進入官方網站,點擊SIGN IN,目前定製化視覺服務提供了免費試用版,可以體驗定製化視覺服務。
登錄後,然後界面會提示要求同意一些條約。
條約的大致內容就是,個人必須在微軟要求的規則下使用微軟提供的這項服務。請勾選agree
此時,界面會提示註冊Azure,因爲定製化視覺服務實際上是Azure提供的一項雲服務,正式使用這項服務需要有Azure訂閱。
不過我們現在只是免費試用,所以選擇Continue With trial,如果在根據這篇博客流程做完了一個小應用之後,你覺得確實需要使用這項服務,那麼你可以去註冊Azure賬號,獲取Azure訂閱。

三、創建定製化視覺服務項目

點擊New Project,填寫項目信息。

這裏不妨以一個熊的分類模型作爲例子來實踐吧。

填寫好NameDescription,這裏Name不妨填寫爲BearClassification

隨後選擇ClassificationGeneral(compact),點擊Create

截圖 操作
Project Type一欄,定製化視覺服務提供了識別和分類兩種服務,另外提供了多種識別場景,其中末尾帶有(compact),也即壓縮字樣的三種。
壓縮模型,顧名思義,模型佔用的空間更少,運行更快,甚至可以放到手機這種移動設備裏。
當然,會有一個小問題就是精確度會受影響。導出模型後,模型文件的使用是沒有任何限制的,而其餘的幾種場景只能通過調用API來進行預測,由於當前屬於免費試用,因此這種方式有10000次調用上限。
由於分類服務需要準備用來訓練的數據集,請自行準備幾種不同的熊的照片,將同種的熊放在以這種熊的名字命名的文件夾裏,最後再將這些文件夾放在一個data文件夾中。然後點擊Add images
選擇一種熊的全部照片,然後創建對應的標籤,點擊Up load xxx files
在添加了所有的數據集和標籤之後,點擊網頁上方的Train,開始訓練模型。
一小會之後,點擊網頁上方的performance,就可以看到這次訓練的結果了。
這裏簡單解釋一下Precision和Recall,這是兩個評估模型好壞的主要指標。
簡單來說,兩個數都是越大越好。在這個項目中,以Brown Bear爲例:
Precision就是識別出來的結果的準確率,即在所有被識別爲棕熊的圖片中真正有棕熊的圖片所佔的比例;而Recall則是測試結果中正確識別爲棕熊的圖片佔測試集中所有棕熊圖片的比例。
這時再點擊界面右上角的齒輪,可以看到免費用戶每個項目能夠使用的服務額度:
一共可以上傳5000張圖片,創建50個不同標籤,保存10次迭代的結果。
這十次迭代有什麼用呢?當需要增刪標籤、給標籤添加或刪除訓練圖片時,這次再訓練,就會花費掉一次迭代。
這些都是當前項目的總數而不是累計值。對於一般的免費用戶,這基本上就相當於你可以隨意使用這項服務了,如果有大量的訓練數據,那麼建議您還是訂閱Azure雲服務,Azure秉持着使用多少,收費多少的原則,即使收費,也仍然良心。
然後選擇剛剛訓練好的這次迭代,點擊Export
視覺認知服務一共提供了適用於四種平臺的模型導出,對三大操作系統都能支持。
選擇ONNX,這個格式由微軟、臉書、亞馬遜等大廠鼎力支持,點擊Export,等待服務器把模型導出,然後點擊Download,即可下載模型。最後得到了一個.onnx文件,然後就可以使用它來構建應用了。

如果需要上傳大量的圖片數據,那麼點擊鼠標的方式肯定不夠方便,微軟同時提供了代碼的支持,詳見官方文檔:

https://docs.microsoft.com/en-us/azure/cognitive-services/custom-vision-service/home

四、使用Windows ML構建應用

這次不寫Winform程序,而是搭建一個識別熊的UWP的AI應用,通過這個應用來教大家如何使用Windows ML導入模型。

這部分的代碼已經完成了,請使用git克隆samples-for-ai到本地,UWP項目的代碼在/samples-for-ai/projects/BearClassificationUWPDemo中。

在運行代碼之前,請先安裝開發UWP所需的工作負載,流程如下:

  1. 打開Visual Studio Installer
  2. 在工作負載中勾選Universal Windows Platform development
  3. 在單個組件一欄中下拉到最下方,確認Windows 10 SDK(10.0.17134.0)已被勾選上,這是使用Windows ML開發的核心組件



另外,請將您的操作系統更新到1803版本,否則本程序將不能安裝。

如果您將進行類似的開發,請將UWP項目設置成最低運行目標版本爲17134,否則對於版本低於17134的用戶,在運行時會出現:

“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,粘貼到輸入框內,然後點擊識別按鈕;或者,點擊瀏覽按鈕,選擇一張本地圖片,點擊確定,你就可以看到識別結果了:



現在來看看這個程序是怎麼實現的。

我們來梳理一下這個應用的邏輯,這個應用的邏輯與上一篇博客中的手寫數字識別大體上是一樣的:

  1. 導入模型
  2. 按下按鈕後,通過某種方式獲取要用來識別的圖片
  3. 將圖片交給模型識別
  4. 將圖片與識別結果展示在界面上

1. 文件結構:

文件結構見下圖:

  • Assets文件夾存放了這個項目的資產文件,比如程序圖標等等,在本示例程序中,.onnx文件也存放在其中。
  • Strings文件夾存放了用於本地化與全球化資源文件,這樣可以支持不同的語言。
  • ViewModel文件夾中則存放了本項目的關鍵代碼,整個程序運行的邏輯都在ResultViewModel.cs中
  • BearClassification.cs則是系統自動生成的模型包裝文件
  • MainPage.xaml是程序的UI佈局文件

2. 核心代碼一:BearClassification.cs

這部分的代碼是自動生成的,教程詳見鏈接:https://docs.microsoft.com/zh-cn/windows/uwp/machine-learning/

  1. 將.onnx文件添加到UWP項目的Assets文件夾中,隨後將自動生成一個對應的包裝.cs文件,在本例中爲BearClassification.cs
  2. 由於目前存在的一些BUG,生成的類名會有亂碼,需要將亂碼替換爲別的字符串。
  3. 修改BearClassification.onnx屬性->生成操作,將其改爲內容,確保在生成時,能夠調用到這個模型。

生成的文件共有三個類:
- BearClassificationModelInput:定義了該模型的輸入格式是VideoFrame
- BearClassificationModelOutput:定義了該模型的輸出爲一個list和一個dict,list存儲了所有標籤按照probability降序排列,dict則存儲了標籤與概率的鍵值對
- BearClassificationModel:定義了該模型的初始化函數與推理函數

// 模型的輸入格式爲VideoFrame
public sealed class BearClassificationModelInput
{
    public VideoFrame data { get; set; }
}

// 模型的輸出格式,其中包含了一個列表:classLabel和一個字典:loss
// 列表中包含每種熊的標籤,按照概率降序排列
// 字典中則包含了每種熊的標籤和其概率,按照用戶在創建模型時的添加順序排列
public sealed class BearClassificationModelOutput
{
    public IList<string> classLabel { get; set; }
    public IDictionary<string, float> loss { get; set; }
    public BearClassificationModelOutput()
    {
        this.classLabel = new List<string>();
        this.loss = new Dictionary<string, float>(){...}
    }
}

// 模型的包裝類,提供了兩個函數
// CreateBearClassificationModel:從.onnx文件中創建模型
// EvaluateAsync:對輸入對象進行評估,並返回結果
public sealed class BearClassificationModel
{
    private LearningModelPreview learningModel;
    public static async Task<BearClassificationModel> CreateBearClassificationModel(StorageFile file)
    {
        ...
    }

    public async Task<BearClassificationModelOutput> EvaluateAsync(BearClassificationModelInput input)
    {
        ...
    }
}

3. 核心代碼二:ResultViewModel.cs

通過之前的運行可以發現:每次識別圖片,UI中的內容需要進行頻繁地更新,爲了簡化更新控件內容的代碼邏輯,這個程序使用UWP開發中常用的MVVM(model-view-viewmodel)這一組合模式開發,使用“綁定”的方式,將UI控件與數據綁定起來,讓數據與界面自動地同步更新,簡化了代碼邏輯,保證了ResultViewModel職責單一。

綁定源(ResultViewMode.cs) 綁定目標(MainPage.xaml)
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);
}

圖片推理:

本程序提供了兩種方式訪問圖片資源:
1. 通過URL訪問網絡圖片
2. 通過文件選取器訪問本地圖片

private async void EvaluateNetPicAsync()
{
    try
    {
        ...
        //BearClassification要求的輸入格式爲VideoFrame
        //程序需要以stream的形式從URL中讀取數據,生成VideoFrame
        var response = await new HttpClient().GetAsync(BearUrl);
        var stream = await response.Content.ReadAsStreamAsync();
        BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream.AsRandomAccessStream());
        VideoFrame imageFrame = VideoFrame.CreateWithSoftwareBitmap(await decoder.GetSoftwareBitmapAsync());

        //將videoframe交給函數進行識別
        EvaluateAsync(imageFrame);
    }
    catch (Exception ex){ ... }
}


private async void EvaluateLocalPicAsync()
{
    try
    {
        ...
        // 從文件選取器中獲得文件
        StorageFile file = await openPicker.PickSingleFileAsync();
        var stream = await file.OpenReadAsync();
        ...
        // 生成videoframe
        BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);
        VideoFrame imageFrame = VideoFrame.CreateWithSoftwareBitmap(await decoder.GetSoftwareBitmapAsync());

        // 將videoframe交給函數進行識別
        EvaluateAsync(imageFrame);
    }
    catch (Exception ex){ ... }
}

private async void EvaluateAsync(VideoFrame imageFrame)
{
    //將VideoFrame包裝進BearClassificationModelInput中,交給模型識別
    //模型的輸出格式爲BearClassificationModelOutput
    //其中包含一個列表,存儲了每種熊的標籤名稱,按照probability降序排列
    //和一個字典,存儲了每種熊的標籤,和對應的probability
    //這裏取出輸出中的字典,並對其進行降序排列
    var result = await model.EvaluateAsync(new BearClassificationModelInput() { data = imageFrame });
    var resultDescend = result.loss.OrderByDescending(p => p.Value).ToDictionary(p => p.Key, o => o.Value).ToList();

    //根據結果生成圖片描述
    Description = DescribResult(resultDescend.First().Key, resultDescend.First().Value);

    Results.Clear();
    foreach (KeyValuePair<string, float> kvp in resultDescend)
    {
        Results.Add(resourceLoader.GetString(kvp.Key) + " : " + kvp.Value.ToString("0.000"));
    }
}

五、使用其他方法構建應用

同樣,用之前使用Visual Studio Tools for AI提供的推理類庫生成器也能夠構建相似的應用,請看:

【教程】普通程序員一小時入門AI應用——看圖識熊(不含公式,包會)

該教程講解了如何使用模型瀏覽工具Netron

根據模型瀏覽工具與推理類庫生成器來生成模型調用接口。

六、下一步?

本篇博客我們學會了使用定製化視覺服務與在UWP應用中集成定製化視覺服務模型。這裏我提兩個課後習題:(想不到吧)

  1. 當訓練含有多個標籤、大量圖片數據時,如何做到一鍵上傳圖片並訓練?

  2. 如何通過調用REST接口的方式完成對圖片的推理?

提示:請看看定製化視覺服務給我們提供的API,這一題肯定是要寫代碼做的
https://docs.microsoft.com/en-us/azure/cognitive-services/custom-vision-service/home

加油!

七、內容預告

接下來我們將會陸續推出:
1. 微軟認知服務使用教程
2. 模型訓練及推理的通常流程及原理
3. 模型轉換工具的使用
4. 開放AI平臺-大規模計算資源調度系統

請在下方留言,告知我們您最想閱讀哪個教程,我們將優先考慮。

如果您有別的想要了解的內容,也可以在評論區留言。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章