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

来源:https://www.cnblogs.com/hupo376787/archive/2018/06/06/9145714.html
-Advertisement-
Play Games

今天看到一篇文章 Google’s Image Classification Model is now Free to Learn 說是狗狗的機器學習速成課程(Machine Learning Crash Course)現在可以免費學習啦,因為一開始年初的時候是內部使用的,後來開放給大眾了。大家有誰 ...


今天看到一篇文章  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


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 首先下載wireshark並安裝 這是一個免費軟體。我也不懂 隨便就在百度里下載了個 ,版本是Version 2.4.3 。 然後是要在首選項里勾選dicom協議選項。 關於使用,這個我也是一臉懵逼,隨便給兩個網上的教程吧,http://openmaniak.com/cn/wireshark_fil ...
  • 最近在做項目過程中,經常會遇到生成訂單流水號唯一性的應用,也有不少同事也請教我對唯一性的 "流水號"的問題,根據個人所見,一般生成的規則都是根據日期來進行操作,我目前在做的一個項目:”報告卡“上的編碼就是根據 ”yyyyMMdd+四位數字(累加)“的格式生成,一般對這一類的操作最好是在存儲過程中生成 ...
  • 因公司ELK監控分析日誌的需要,需要區分進程運行狀態日誌以及錯誤日誌,以便能夠根據日誌級別(level)進行不同策略的預警,而現有的Nlog、Log4Net都沒有Process這樣的level,故針對這兩個日誌框架做了一些擴展,實現了自定義PROCESS LEVEL,因代碼不多,故直接貼代碼,有疑問 ...
  • 第一種 split()方法將一個字元串對象的每個字元拆出來,並且將每個字元串當成數組的每個元素reverse()方法用來改變數組,將數組中的元素倒個序排列,第一個數組元素成為最後一個,最後一個變成第一個join()方法將數組中的所有元素邊接成一個字元串 第二種 for迴圈給原字元串做一個遞減遍歷,然 ...
  • 這兩天試了下Stylet框架,這個框架雖然很小,但是功能齊全,簡化了很多MVVM的代碼,比如Command,對Dialog,MessageBox都有很好的支持。 開源地址 https://github.com/canton7/Stylet 新建一個WPF項目,添加NuGet引用 安裝完成後會自動添加 ...
  • 使用兩個c#的特性: 加在類上的:[DataContract] 加在欄位上的:[DataMember(Name = "ResultCode",EmitDefaultValue = true,IsRequired = true, Order = 1)] 這個order就是控制順序的。C#就是辣麽強大。 ...
  • 這篇文章只是簡單展示一個基於HTTP請求如何抓取數據的文章,如覺得簡單的朋友,後續我們再慢慢深入研究探討。 圖1: 如圖1,我們工作過程中,無論平臺網站還是企業官網,總少不了新聞展示。如某天產品經理跟我們說,推廣人員想要抓取百度新聞中熱點要聞版塊提高站點百度排名。要抓取百度的熱點要聞版本,首先我們先 ...
  • 我們知道,基於DevExpress的開發Winform的項目界面的時候,GridControl控制項是經常用來綁定數據的,一般以常規的字元內容為主,有時候也會有圖片的顯示需要,那麼如果顯示圖片,我們應該如何實現呢?本篇隨筆介紹基於原生GridControl控制項的圖片綁定顯示操作和基於我封裝的分頁控制項(... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...