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

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

 

說是狗狗的機器學習速成課程(Machine Learning Crash Course)如今能夠免費學習啦,由於一開始年初的時候是內部使用的,後來開放給大衆了。你們有誰對不做惡家的機器學習感興趣的話,能夠點擊鏈接去看看。ios

可是以上不是我說的重點。git

 

說狗狗的緣由,是爲了引出我大微軟的機器學習。github

 

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

ML means machine learning, not make love. Understand???dom

 

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

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

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

 

看看你看,這麼牛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

相關文章
相關標籤/搜索