1. 程式人生 > >基於Windows 機器學習(Machine Learning)的圖像分類(Image classification)實現

基於Windows 機器學習(Machine Learning)的圖像分類(Image classification)實現

BYD pack format ret bmp async 配置 rev 技術分享

原文:基於Windows 機器學習(Machine Learning)的圖像分類(Image classification)實現

今天看到一篇文章 Google’s Image Classification Model is now Free to Learn

技術分享圖片

說是狗狗的機器學習速成課程(Machine Learning Crash Course)現在可以免費學習啦,因為一開始年初的時候是內部使用的,後來開放給大眾了。大家有誰對不作惡家的機器學習感興趣的話,可以點擊連接去看看。

但是以上不是我說的重點。

技術分享圖片

說狗狗的原因,是為了引出我大微軟的機器學習。

在2018年3月7日,在Windows開發者日活動中,微軟宣布推出Windows人工智能平臺Windows ML。

ML means machine learning, not make love. Understand???技術分享圖片

在Windows ML平臺下,開發人員能夠將不同的AI平臺導入現有的學習模型,並在安裝了Windows10系統的PC設備上使用預先培訓的ML模型,並利用CPU和GPU(AMD,Intel,NVIDIA、Qualcomm)硬件進行加速,而非雲端。從而加快對本地圖像及視頻數據的實時分析,甚至是後臺任務的改進。

此外該技術支持ONNX格式的ML模型行業標準,開發者能夠添加ONNX文件至UWP應用中,在並項目中生成模型界面。

目前微軟已將自家的AI技術融入進了Office 365、Windows 10 照片中,甚至還使用了Windows Hello面部識別技術,來替換傳統的開機密碼。

看看你看,這麽牛B的技術,我們怎麽不來嘗鮮呢。不過也不鮮了,已經過去仨月了。但是哪一家的技術不是先畫一個餅,過很久你才能看到樣品。哈哈。

現在學習ML還來得及。

在操作之前,先來說一下需要什麽配置吧。

1. Windows 10 1803 或者更高

2. Visual Studio 15.7.1或更高

3. Microsoft Visual Studio Tools for AI,在工具——擴展和更新 裏面搜索AI即可找到。

OK,大體說一下流程。

1. 創建和訓練機器學習的模型

要實現對某一張圖像的辨別,首先我們需要用一些數據來訓練機器,告訴它這個是啥。也就是加標簽tag.

比如,之前微軟的小冰識狗,那你得首先找很多狗的照片吧,你要是拿貓的照片來訓練機器,告訴它這是狗,也不是不可以。因為歷史上也有指鹿為馬的故事呢。當然在一個很大數據下,比如你拿了10萬張狗的圖片,裏面有那麽幾張是貓的,雞的圖片,這樣訓練出來也沒事。因為機器會在訓練之後給你一個數據讓你參考。在數據很大的前提下,允許小錯的。

2. 代碼實戰

用代碼來實現一下,並且隨機挑一張照片,叫機器辨別它是個啥。因為機器剛才學習了啊,如果他認識,那麽就會給出相應的可能性大小。

技術分享圖片

1. 創建和訓練機器學習的模型

用你的Microsoft賬號登陸 https://www.customvision.ai/projects, ,創建項目,類型就選擇圖像分類,Domains領域選擇了General(Compact),帶Compact是可以到處到Android和ios上用模型

技術分享圖片

接下來你會看到下圖,你可以先加標簽tag,在給標簽添加相應的圖像。也可以先加圖像,然後新加標簽的。

技術分享圖片

我先訓練一個川普出來試試,

技術分享圖片

你可以多加幾個標簽。我一共做了兩個。一個是川普,一個是一種花,一年蓬。

等把標簽和對應的圖像都上傳完畢後,點擊上面的【訓練】

技術分享圖片

然後訓練結果馬上就出來了。

第一個Precision,表示模型包含的標簽預測的精度,越大越好。

第一個Recall,模型標簽外的預測精度,也是越大越好。

當然,你也可以現在試驗一下。點擊右上方的Quick Test,即可測試。。

技術分享圖片

然後,點擊正上方的Export,導出模型。支持4種格式,Android,Ios,ONNX,DockFile。我們選擇WIndows標準的ONNX。好了。第一步基本結束。很簡單,都是點幾下就搞定。

如果你好奇ONNX裏面是啥樣子,那麽恭喜你,你很好學。去 https://github.com/lutzroeder/Netron 下載一個軟件,看看吧。

技術分享圖片

2. 代碼實戰

模型做好了,就該寫代碼了。代碼也不多,很簡單滴。

新建一個UWP 程序,在Assets資產文件夾裏面,添加剛才下載的ONNX文件(該文件可以隨意重命名,也最好Rename一下,不然文件名字太長了),設置它的生成操作為【Content 內容】。

這是你會發現,多了一個.cs類。

技術分享圖片

打開Vincent.cs看看啊,沒錯,又是有點亂。改一下咯技術分享圖片

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Windows.Media;
using Windows.Storage;
using Windows.AI.MachineLearning.Preview;

// e6c82f6e-c60f-422a-97b6-e0406cba82da_6ed0259c-001e-4895-be7a-4a930321a307

namespace VincentML
{
    public sealed class ModelInput
    {
        public VideoFrame data { get; set; }
    }

    public sealed class ModelOutput
    {
        public IList<string> classLabel { get; set; }
        public IDictionary<string, float> loss { get; set; }
        public ModelOutput()
        {
            this.classLabel = new List<string>();
            this.loss = new Dictionary<string, float>()
            {
                { "Donald Trump", float.NaN },
                { "Yinianpeng", float.NaN },
            };
        }
    }

    public sealed class Model
    {
        private LearningModelPreview learningModel;
        public static async Task<Model> CreateModel(StorageFile file)
        {
            LearningModelPreview learningModel = await LearningModelPreview.LoadModelFromStorageFileAsync(file);
            Model model = new Model();
            model.learningModel = learningModel;
            return model;
        }
        public async Task<ModelOutput> EvaluateAsync(ModelInput input) {
            ModelOutput output = new ModelOutput();
            LearningModelBindingPreview binding = new LearningModelBindingPreview(learningModel);
            binding.Bind("data", input.data);
            binding.Bind("classLabel", output.classLabel);
            binding.Bind("loss", output.loss);
            LearningModelEvaluationResultPreview evalResult = await learningModel.EvaluateAsync(binding, string.Empty);
            return output;
        }
    }
}

好,接下來寫一個簡單的界面,一個圖像Image和一個按鈕Button,一個文本TextBlock

    <Grid>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>

            <Image x:Name="image"/>
            <TextBlock Grid.Row="1" x:Name="tbResult" HorizontalAlignment="Center"/>
            <Button Grid.Row="2" Content="Choose a picture" HorizontalAlignment="Center" Click="ChooseImage"/>
        </Grid>
    </Grid>

主要看後臺代碼ChooseImage。

龍宮分四步:

1. 加載模型
2. 選擇一個圖片
3. 設置模型的輸入數據
4. 輸出結果
            //1. 加載模型
StorageFile modelDile = await StorageFile.GetFileFromApplicationUriAsync(new Uri($"ms-appx:///Assets/Vincent.onnx")); Model model = await Model.CreateModel(modelDile);
//2. 選擇一個圖片 FileOpenPicker picker
= new FileOpenPicker(); picker.FileTypeFilter.Add(".jpg"); picker.FileTypeFilter.Add(".jpeg"); picker.FileTypeFilter.Add(".png"); picker.FileTypeFilter.Add(".bmp"); picker.SuggestedStartLocation = PickerLocationId.PicturesLibrary; var file = await picker.PickSingleFileAsync(); if (file != null) {

BitmapImage src = new BitmapImage();
using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read))
{
await src.SetSourceAsync(stream);
stream.Dispose();
};
image.Source = src;

                //3. 設置模型的輸入數據
                ModelInput modelInput = new ModelInput();
                modelInput.data = await GetVideoFrame(file);

//4. 輸出結果 ModelOutput modelOutput
= await model.EvaluateAsync(modelInput); var topCategory = modelOutput.loss.OrderByDescending(kvp => kvp.Value).FirstOrDefault().Key; }

註意一下,ModelInput的輸如數據類型是VideoFrame,所以需要將圖片轉換一下。

        private async Task<VideoFrame> GetVideoFrame(StorageFile file)
        {
            SoftwareBitmap softwareBitmap;
            using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read))
            {
                // Create the decoder from the stream 
                BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);

                // Get the SoftwareBitmap representation of the file in BGRA8 format
                softwareBitmap = await decoder.GetSoftwareBitmapAsync();
                softwareBitmap = SoftwareBitmap.Convert(softwareBitmap, BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied);

                return VideoFrame.CreateWithSoftwareBitmap(softwareBitmap);
            }
        }

好了,看一下咋樣,運行一下。技術分享圖片

我還特地找了一張川總很酷的發型圖

技術分享圖片

如果你選擇了一個別的照片,比如狗,會得到這樣的。

但是你非要說這條狗就叫Donald Trump,那我無F*ck可說了。

技術分享圖片

最後,歡迎大家去全球最大的同性戀交友平臺Fork/Star我的項目:https://github.com/hupo376787/MachineLearningOnUWP

基於Windows 機器學習(Machine Learning)的圖像分類(Image classification)實現