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