ML.NET 示例:对象检测
| v1.4 | 動態API | 最新 | 控制臺應用程序 | 圖像文件 | 對象檢測 | 深度學習 | Tiny Yolo2 ONNX 模型 |
有關如何構建此應用程序的詳細說明,請參閱Microsoft Docs網站上附帶的教程。
問題
對象檢測是計算機視覺中的一個經典問題:識別給定圖像中的目標以及它們在圖像中的位置。對于這些情況,您可以使用預先訓練的模型,也可以訓練自己的模型來對特定于自定義域的圖像進行分類。
數據集
數據集包含位于assets文件夾中的圖像。這些圖片來自wikimedia commons網站。轉到[wikimediacomon.md](./ObjectDetectionConsoleApp/assets/images/wikimedia.md)查看圖像URL及其許可證。
預訓練模型
有多個預先訓練的模型來識別圖像中的多個對象。這里我們使用的是預訓練模型,Tiny Yolo2,格式為ONNX。該模型是一個用于對象檢測的實時神經網絡,可以檢測20個不同的類別。它由9個卷積層和6個最大池層組成,是更復雜的full[YOLOv2]的較小版本(https://pjreddie.com/darknet/yolov2/)網絡。
開放式神經網絡交換即ONNX是一種表示深度學習模型的開放格式。使用ONNX,開發人員可以在最先進的工具之間移動模型,并選擇最適合他們的組合。ONNX是由一個合作伙伴社區開發和支持的。
模型從ONNX Model Zoo 下載,這是一個預訓練的,最先進的模型在ONNX格式的集合。
Tiny YOLO2模型是在Pascal VOC數據集上訓練的(http://host.robots.ox.ac.uk/pascal/VOC/)。以下是模型的先決條件。
模型輸入和輸出
輸入
輸入圖像的大小 (3x416x416)
輸出
輸出是一個(1x125x13x13)數組
預處理步驟
將輸入圖像調整為float32類型的(3x416x416)數組。
后處理步驟
輸出是一個(125x13x13)張量,其中13x13是圖像被分割成的網格單元數。每個網格單元對應125個通道,由網格單元預測的5個邊界框和描述每個邊界框的25個數據元素(5x25=125)組成。有關如何導出最終邊界框及其相應的置信度分數的更多信息,請參閱文章。
解決方案
控制臺應用程序項目ObjectDetection可用于識別基于Tiny Yolo2 ONNX模型的示例圖像中的對象。
同樣,請注意,此示例僅使用/使用帶有ML.NET API的預先訓練的ONNX模型。因此,它不訓練任何ML.NET模型。目前,ML.NET僅支持對現有ONNX訓練模型進行評分/檢測。
為了執行分類測試,您需要執行以下步驟:
**設置VS默認啟動項目:**在Visual Studio中將ObjectDetection設置為啟動項目。
**運行training model控制臺應用程序:**在Visual Studio中按F5。在執行結束時,輸出將類似于此屏幕截圖:
代碼演練
解決方案中有一個名為ObjectDetection的項目,負責以 Tiny Yolo2 ONNX格式加載模型,然后檢測圖像中的對象。
ML.NET:模型評分
定義類中的數據架構,并在使用TextLoader加載數據時引用該類型。這里的類是ImageNetData。
public?class?ImageNetData {[LoadColumn(0)]public?string?ImagePath;[LoadColumn(1)]public?string?Label;public?static?IEnumerable<ImageNetData>?ReadFromFile(string?imageFolder){return?Directory.GetFiles(imageFolder).Where(filePath?=>?Path.GetExtension(filePath)?!=?".md").Select(filePath?=>?new?ImageNetData?{?ImagePath?=?filePath,?Label?=?Path.GetFileName(filePath)?});} }ML.NET:配置模型
第一步是創建一個空的數據視圖,因為我們在配置模型時只需要數據模式。
var?data?=?mlContext.Data.LoadFromTextFile<ImageNetData>(imagesLocation,?hasHeader:?true);用于加載圖像的圖像文件有兩列:第一列定義為ImagePath,第二列定義為與圖像對應的Label。
需要強調的是,在使用Tiny Yolo2 Onnx模型進行評分時,ImageNetData類中的Label并沒有真正使用。僅在控制臺上打印標簽時使用。
第二步是定義評估器管道。通常,在處理深度神經網絡時,必須使圖像適應網絡所期望的格式。這就是圖像調整大小然后變換的原因(主要是在所有R、G、B通道中對像素值進行歸一化)。
var?pipeline?=?mlContext.Transforms.LoadImages(outputColumnName:?"image",?imageFolder:?"",?inputColumnName:?nameof(ImageNetData.ImagePath)).Append(mlContext.Transforms.ResizeImages(outputColumnName:?"image",?imageWidth:?ImageNetSettings.imageWidth,?imageHeight:?ImageNetSettings.imageHeight,?inputColumnName:?"image")).Append(mlContext.Transforms.ExtractPixels(outputColumnName:?"image")).Append(mlContext.Transforms.ApplyOnnxModel(modelFile:?modelLocation,?outputColumnNames:?new[]?{?TinyYoloModelSettings.ModelOutput?},?inputColumnNames:?new[]?{?TinyYoloModelSettings.ModelInput?}));您還需要檢查神經網絡,并檢查輸入/輸出節點的名稱。為了檢查模型,您可以使用Netron之類的工具,它與Visual Studio Tools for AI一起自動安裝。這些名稱稍后將在評估管道的定義中使用:在初始網絡的情況下,輸入張量命名為“image”,輸出命名為“grid”。
定義模型的輸入和輸出參數。
public?struct?TinyYoloModelSettings {//?for?checking?TIny?yolo2?Model?input?and??output??parameter?names,//you?can?use?tools?like?Netron,?//?which?is?installed?by?Visual?Studio?AI?Tools//?input?tensor?namepublic?const?string?ModelInput?=?"image";//?output?tensor?namepublic?const?string?ModelOutput?=?"grid"; }最后,我們在擬合評估器管道之后返回訓練模型。
??var?model?=?pipeline.Fit(data);return?model;檢測圖像中的對象:
在模型配置完成后,我們需要將圖像傳遞給模型來檢測對象。獲取預測時,我們在屬性PredictedLabels中獲得一個浮點數組。該數組是一個浮點數組,大小為21125。如前所述,這是125x13x13的輸出。此輸出由“YoloOutputParser”類解釋,并為每個圖像返回多個邊界框。再次過濾這些框,以便我們僅檢索5個邊界框,這些邊界框對于圖像的每個對象具有更好的可信度(一個框包含obejct的確定程度如何)。
IEnumerable<float[]>?probabilities?=?modelScorer.Score(imageDataView);YoloOutputParser?parser?=?new?YoloOutputParser();var?boundingBoxes?=probabilities.Select(probability?=>?parser.ParseOutputs(probability)).Select(boxes?=>?parser.FilterBoundingBoxes(boxes,?5,?.5F));注意與完整的Yolo2模型相比,Tiny Yolo2模型沒有太多的精確度。由于這是一個示例程序,我們使用的是微型版本的Yolo模型,即Tiny_Yolo2
總結
以上是生活随笔為你收集整理的ML.NET 示例:对象检测的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: gRPC在C#中的未来属于grpc-do
- 下一篇: 开源推荐:Asp.Net Core入门学