Xamarin.iOS CoreML和Vision簡介

寫在前面:

在2017年的WWDC大會(huì)上,隨著iOS 11的發(fā)布,隨之而來的還有一系列新的特性和功能,同樣也帶來了獨(dú)特的布局適配問題。在這次大會(huì)中,蘋果推出了CoreML框架,能夠?qū)C(jī)器學(xué)習(xí)應(yīng)用在移動(dòng)端上,這等于在一些online的基礎(chǔ)上提供了offline方式,可以說在實(shí)際的開發(fā)過程中,能在一些特定的業(yè)務(wù)需求上能提供極大的幫助。

什么是機(jī)器學(xué)習(xí)?

機(jī)器學(xué)習(xí),也就是目前被大家經(jīng)常提起的Machine Learning,也可以說是現(xiàn)在很火的一個(gè)技術(shù),它也是人工智能最核心的內(nèi)容。比如說橫掃世界棋壇大名鼎鼎的阿爾法狗(AlphaGo),或者已經(jīng)深入大家生活場景的圖片識別、語言翻譯、云歌曲推薦等等,這其實(shí)都是機(jī)器學(xué)習(xí)的具體實(shí)際應(yīng)用的結(jié)果。

機(jī)器學(xué)習(xí)就是一種能讓計(jì)算機(jī)不需要進(jìn)行不斷人工手動(dòng)編程添加功能,而能自己學(xué)習(xí)的人工智能技術(shù)。它不是通過具體的編碼算法,而是在大量的模型數(shù)據(jù)中找到一個(gè)合適的模式從而讓計(jì)算機(jī)能夠不斷的發(fā)展和完善自身算法。

這個(gè)技術(shù)所要模擬的就是一個(gè)龐大而復(fù)雜的‘神經(jīng)網(wǎng)絡(luò)’,這個(gè)'神經(jīng)網(wǎng)絡(luò)'就需要大量的訓(xùn)練好的模型(model)來提供數(shù)據(jù),使得這個(gè)'神經(jīng)網(wǎng)絡(luò)'能對各種輸入(inputs)產(chǎn)生出一個(gè)對應(yīng)的輸出結(jié)果(outputs),并且還能通過不斷的訓(xùn)練數(shù)據(jù)來提高自己的算法準(zhǔn)確性。

這里的核心其實(shí)就是訓(xùn)練各種模型(model)來處理各種不同的情況和需求。比如說有了一個(gè)專門識別人臉的模型,給一個(gè)輸入圖片他就能把人臉位置輸出出來等等等等,最后如果將無限多的訓(xùn)練好的模型都結(jié)合起來,那這個(gè)計(jì)算機(jī)可能就能像人一樣應(yīng)對各種情況還能不斷地自我完善。下圖是機(jī)器學(xué)習(xí)的一些應(yīng)用場景:

CoreML是什么

Core ML根據(jù)官方文檔里的這張圖就可以看出,其實(shí)它的作用就是將一個(gè)訓(xùn)練好的ML模型,轉(zhuǎn)換成我們的app工程可以直接使用的對象。利用該模型可以基于新的輸入數(shù)據(jù)而進(jìn)行預(yù)測,也就是利用了機(jī)器學(xué)習(xí)的結(jié)果。比如,如果一個(gè)模型在一個(gè)地區(qū)的歷史房價(jià)數(shù)據(jù)上進(jìn)行了訓(xùn)練,那么它就可能能夠根據(jù)房子的臥室或客廳數(shù)量來預(yù)測房價(jià)。

Core ML 為設(shè)備性能進(jìn)行了優(yōu)化,從而減少了內(nèi)存占用和功耗。嚴(yán)格在設(shè)備上運(yùn)行能夠確保用戶數(shù)據(jù)的隱私,并且能保證你的應(yīng)用在沒有網(wǎng)絡(luò)連接時(shí)也能夠工作和響應(yīng)。構(gòu)建完成的Core ML又作為其他更高級框架的基礎(chǔ),比如支持用于圖像分析的 Vision 框架,用于自然語言處理的 Foundation類,以及用于評估已經(jīng)學(xué)習(xí)到的決策樹的 GameplayKit。如下圖:

  • vision:高性能的圖像分析和圖像識別。這部分應(yīng)用于人臉追蹤,人臉識別,文本識別,區(qū)域識別,二維碼識別,物體追蹤,圖像識別等。
  • Nattural Language processing:自然語言處理。用于語言識別,分詞,詞性還原,詞性判定等。
  • GamePlayKit:游戲制作,構(gòu)建游戲。用于常見的游戲行為如隨機(jī)數(shù)生成、人工智能、尋路、和代理行為。

Vision是什么

Vision是一個(gè)高性能的圖片分析庫,他能識別在圖片和視頻中的人臉、特征、場景分類等。你如果打開Vision的官方文檔看,官方對他包含的所有類做了分類,比如有Face Detection and Recognition(人臉檢測識別)、Machine Learning Image Analysis(機(jī)器學(xué)習(xí)圖片分析)、Barcode Detection(條形碼檢測)、Text Detection(文本檢測)等等。

大概可以這樣去理解:Vision庫里就已經(jīng)自帶了很多訓(xùn)練好的模型,這些模型是針對上面提到的人臉識別、條形碼檢測等等功能,如果你要實(shí)現(xiàn)的功能剛好是Vision庫本身就能實(shí)現(xiàn)的,那么你直接使用Vision庫自帶的一些類和方法就行。

而當(dāng)你要使用一個(gè)你在網(wǎng)上找的訓(xùn)練好的模型或者你自己訓(xùn)練好的模型的時(shí)候,才需要CoreML來將這個(gè)相當(dāng)于‘第三方’模型轉(zhuǎn)換成app認(rèn)得的類,之后才能使用這個(gè)模型,同時(shí)也結(jié)合上面提到的Vision的Machine Learning Image Analysis(機(jī)器學(xué)習(xí)圖片分析)分類下的類和方法來使用這個(gè)模型進(jìn)行圖形分析或者Vision其它的一些模型進(jìn)行一系列分析操作。

CoreML Samples

下面給大家介紹官網(wǎng)給出的一個(gè)Mars Habitat Pricer sample,用以預(yù)測火星上的殖民地價(jià)值

1.給項(xiàng)目中添加model

將已經(jīng)編譯好的一個(gè)以.modelc為后綴的model添加到Resources項(xiàng)目文件夾中,然后設(shè)置這個(gè)文件夾下所有文件的build actionBundleResource

2.加載model

在我們使用model之前,我們需要使用MLModel.Create這個(gè)靜態(tài)方法去加載model

var bundle = NSBundle.MainBundle;
var assetPath = bundle.GetUrlForResource("MarsHabitatPricer", "mlmodelc");
NSError mlErroe;
model = MLModel.Create(assetPath, out mlErroe);
3.設(shè)置參數(shù)

當(dāng)我們開始使用這個(gè)模型之前,我們需要用Xcode打開我們的model,查看需要相應(yīng)的inputs和outputs分別是什么,同時(shí)傳入模型參數(shù)以及獲取結(jié)果時(shí)都需要使用一個(gè)繼承IMLFeatureProvider的容器類,這個(gè)類相當(dāng)于一個(gè)字典,其中包含string的key,以及與之相對應(yīng)的MLFeatureValues,每個(gè)feature value可以是string,number,array,data或者image buffer。

public class MarsHabitatPricerInput : NSObject, IMLFeatureProvider
{
    public double SolarPanels { get; set; }
    public double Greenhouses { get; set; }
    public double Size { get; set; }

    public NSSet<NSString> FeatureNames => new NSSet<NSString>(new NSString("solarPanels"), new NSString("greenhouses"), new NSString("size"));

    public MLFeatureValue GetFeatureValue(string featureName)
    {
        switch (featureName)
        {
            case "solarPanels":
                return MLFeatureValue.Create(SolarPanels);
            case "greenhouses":
                return MLFeatureValue.Create(Greenhouses);
            case "size":
                return MLFeatureValue.Create(Size);
            default:
                return MLFeatureValue.Create(0);
        }
    }
}

通過以上這種方式,我們的輸入?yún)?shù)就可以被CoreML所識別,其中public NSSet<NSString> FeatureNames => new NSSet<NSString>(new NSString("solarPanels"), new NSString("greenhouses"), new NSString("size"));中的FeatureNames NSSet必須跟model所要求的輸入保持相同。

4.使用model

使用model需要實(shí)例化我們自定義的繼承了IMLFeatureProvider的容器類,將pickerview中三列的值傳入MarsHabitatPricerInput,然后調(diào)用GetPrediction方法,然后通過調(diào)用GetFeatureValue方法,獲取到相應(yīng)的輸出

void updatePredictedPrice()
{
    var pricerInput = new MarsHabitatPricerInput()
    {
        SolarPanels = datasource.GetValue(pickerView.SelectedRowInComponent(0), Feature.SolarPanels),
        Greenhouses = datasource.GetValue(pickerView.SelectedRowInComponent(1), Feature.Greenhouses),
        Size = datasource.GetValue(pickerView.SelectedRowInComponent(2), Feature.Size)
    };

    // Use the ML model
    NSError prErr;
    var outFeatures = model.GetPrediction(pricerInput, out prErr);
    var result = outFeatures.GetFeatureValue("price").DoubleValue;
    priceLabel.Text = "Predicted Price (millions) " + priceFormatter.StringFor(new NSNumber(result));
            
    Console.WriteLine(prErr == null ? $"result was {result}" : "Unexpected runtime error " + prErr.Description);
}

CoreML With Vision Framework Samples

CoreML也可以與Vision框架結(jié)合使用對圖像進(jìn)行操作,例如形狀識別,人臉識別等其它操作。下面這個(gè)CoreML With Vision Samples中采用了CoreML和Vision 。該示例將Vision框架中的rectangles recognitionMNINSTClassifier.mlmodelc相結(jié)合,以識別照片中的手寫數(shù)字。

1.創(chuàng)建一個(gè)Vision CoreML model

使用CoreML加載MNISTClassifier模型后,將其包裝在一個(gè)VNCoreMLModel 模型中,使得該模型可用于圖片處理。以下代碼還創(chuàng)建了兩個(gè)Vision請求:首先用于在圖像中查找矩形,然后用CoreML模型處理矩形獲取其中的數(shù)字:

// Load the ML model
var bundle = NSBundle.MainBundle;
var assetPath = bundle.GetUrlForResource("MNISTClassifier", "mlmodelc");
NSError mlErr, vnErr;
var mlModel = MLModel.Create(assetPath, out mlErr);
var model = VNCoreMLModel.FromMLModel(mlModel, out vnErr);

// Initialize
RectangleRequest = new VNDetectRectanglesRequest(HandleRectangles);
ClassificationRequest = new VNCoreMLRequest(model, HandleClassification);
2.開始Vision處理
// Run the rectangle detector, which upon completion runs the ML classifier.
var handler = new VNImageRequestHandler(ciImage, uiImage.Orientation.ToCGImagePropertyOrientation(), new VNImageOptions());
DispatchQueue.DefaultGlobalQueue.DispatchAsync(()=>{
        NSError error;
        handler.Perform(new VNRequest[] {RectangleRequest}, out error);
});
});

通過傳入一個(gè)CIImage對象給Vision Framework,之后根據(jù)第一步創(chuàng)建的VNDetectRectanglesRequest請求,當(dāng)矩形識別完畢后會(huì)執(zhí)行相應(yīng)的HandleRectangles回調(diào)函數(shù)。

3.處理Vision操作的結(jié)果

當(dāng)開始執(zhí)行HandleRectangles回調(diào)函數(shù)之后,裁剪圖像以提取第一個(gè)矩形,將矩形圖像轉(zhuǎn)換為灰度,并將其傳遞給CoreML模型。

void HandleRectangles(VNRequest request, NSError error) {
var observations = request.GetResults<VNRectangleObservation>();
// ... omitted error handling ...
var detectedRectangle = observations[0]; // first rectangle
// ... omitted cropping and greyscale conversion ...
// Run the Core ML MNIST classifier -- results in handleClassification method
var handler = new VNImageRequestHandler(correctedImage, new VNImageOptions());
DispatchQueue.DefaultGlobalQueue.DispatchAsync(() => {
    handler.Perform(new VNRequest[] { ClassificationRequest }, out NSError err);
 });
}
4.使用CoreML

通過傳入處理完成之后的CIImage對象給MNISTClassifier后,根據(jù)第一步創(chuàng)建的VNCoreMLRequest請求,當(dāng)數(shù)字識別完畢后會(huì)執(zhí)行相應(yīng)的HandleClassification回調(diào)函數(shù)。

void HandleClassification(VNRequest request, NSError error){
var observations = request.GetResults<VNClassificationObservation>();
... omitted error handling ...
var best = observations[0]; // first/best classification result
// render in UI
DispatchQueue.MainQueue.DispatchAsync(()=>{
    ClassificationLabel.Text = $"Classification: {best.Identifier} Confidence: {best.Confidence * 100f:#.00}%";
});
}

傳入的request參數(shù)中包含CoreML Request的詳細(xì)信息,通過調(diào)用GetResults<VNClassificationObservation>()方法返回可能的結(jié)果結(jié)合。

寫在最后:
到此在Xamarin.iOS中使用CoreML和Vision的案例介紹就完成了,之后也會(huì)給大家?guī)?strong>CoreML with Azure Custom Vision Service的介紹,包括使用工具轉(zhuǎn)化第三方Model的介紹。可以看出對于集成CoreML來說,其實(shí)不是特別復(fù)雜,但是其中的算法可以說是非常高深的,我也會(huì)繼續(xù)保持對CoreML的關(guān)注,分享更多的相關(guān)內(nèi)容給大家。

到這里Xamarin.iOS CoreML和Vision的介紹就完成了,希望能對您有所幫助。


——End 有問題可以加我微信,大家一起討論,加好友前請備注您的簡稱,謝謝!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容