Core ML、Swift、およびNeuralEngineを使用したiOSデバイスでの機械学習の実装

こんにちはhabr!上級コース「iOSDeveloper」の開始を見越して、私たちは伝統的にあなたのために役立つ資料の翻訳を用意してきました。










前書き



Core MLは、WWDC 2017でAppleによってリリースされた機械学習ライブラリです



。iOS開発者は、Neural Engineを使用した高度なローカル機械学習モデルを使用して、アプリケーションにリアルタイムのパーソナライズされたエクスペリエンスを追加できます。



A11バイオニックチップレビュー





A11バイオニックチップフィリング

トランジスタ:43億

コア:6つのARMコア(64ビット)-2つの高周波(2.4 GHz)-4つの低電力

GPU:3つの

ニューラルエンジン-1秒あたり600の基本操作


2017年9月12日、AppleはNeuralEngineを搭載したA11Bionicチップを世界に紹介しました。このニューラルネットワークハードウェアは、最大600の基本操作/秒(BOPS)を実行でき、FaceID、Animoji、およびその他のマシン学習タスクに使用されます。開発者は、Core MLAPIを使用してニューラルエンジンを使用できます。



Core MLは、CPU、GPU、およびNeural Engineリソースを利用してデバイス上のパフォーマンスを最適化し、メモリと電力消費を最小限に抑えます。



モデルをユーザーのデバイスでローカルに実行すると、ネットワーク接続が不要になり、ユーザーデータをプライベートに保ち、アプリケーションの応答性を向上させることができます。


Core MLは、このドメインのフレームワークと機能の基盤です。Core MLは、画像分析用のVision、単語処理用のNatural Language、音声からテキストへの音声、および音声内の音声を識別するための音声分析をサポートしています。





Core ML API

Playgroundを使用したモデルのトレーニングとテスト、結果のモデルファイルのiOSプロジェクトへの統合など、機械学習モデルの構築タスクを簡単に自動化できます。



初心者向けのヒント:分類タスクの個別のラベルを強調表示します。






コアMLの一般的なブロック図



はい。何を作成しますか?



このチュートリアルでは、オレンジとストロベリーの画像を分類できるCore MLを使用して画像分類モデルを構築し、このモデルをiOSアプリケーションに追加する方法を示します。





画像分類モデル。



初心者向けのヒント:画像分類とは、ラベル付きデータを使用する監視対象の学習問題を指します(この場合、ラベルは画像の名前です)。








最低限必要なもの:



  • Swift言語の知識
  • IOS開発の基本
  • オブジェクト指向のプログラミング概念を理解する




アプリケーションプログラム:



  • Xコード10以降
  • iOS SDK 11.0+
  • macOS 10.13+




データ収集







画像分類のためにデータを収集するときは、Appleのガイドラインに従ってください。



  • 10 — , .
  • , .
  • , Create ML UI’s Augmentation: Crop, Rotate, Blur, Expose, Noise Flip.
  • : , . , .
  • , , .
  • , , -.




データセットを収集したら、それをトレーニングセットとテストセットに分割し、適切なフォルダーに配置します。







重要な注意:テストフォルダ内の適切なフォルダに画像を配布してください。フォルダー名が画像のラベルとして機能するためです。






この場合、2つのフォルダーがあり、それぞれに対応する画像が含まれています。



モデルの作成







パニックにならない! Appleは、マイルストーンを自動化することにより、これをはるかに簡単にしました。



Core MLを使用すると、すでにトレーニング済みのモデルを使用して入力データを分類したり、独自のモデルを作成したりできます。 VisionフレームワークはすでにCoreMLと連携して、分類モデルを画像に適用し、それらの画像を前処理し、機械学習タスクをより単純で堅牢にします。



次の手順に従ってください。



ステップ1:Xコードを開きます。

ステップ2:クリーンなSwiftPlaygroundを作成します。

ステップ3:デフォルトで生成されたコードを削除し、次のプログラムを追加して実行しplaygroundます。



   import CreateMLUI //  
  
   let builder = MLImageClassifierBuilder() 
//  MLImageClassifierBuilder
 
   builder.showInLiveView() 
//   Xcode Model builder




説明:

ここでは、Xcodeが提供するデフォルトのモデルビルダーのインターフェイスを開きます。



ステップ4:トレーニングサンプルフォルダをトレーニングエリアにドラッグします。



点線で示されたトレーニング領域にトレーニングサンプルフォルダを配置します。



初心者向けのヒント:チュートリアル領域の下矢印をクリックして、モデルに任意の名前を付けることもできます。




ステップ5:Xcodeは自動的に画像を処理し、学習プロセスを開始します。デフォルトでは、Macの特性とデータセットのサイズに応じて、モデルのトレーニングに10回の反復が必要です。 Playgroundターミナルウィンドウでトレーニングの進行状況を確認できます。





モデルのトレーニング中は待っています。



ステップ6:トレーニングが終了したら、Testフォルダーをテスト領域にドラッグアンドドロップしてモデルをテストできます。 Xcodeはモデルを自動的にテストし、結果を表示します。





ご覧のとおり、モデルは画像を正確に分類しています。



ステップ7:モデルを保存します。









iOSアプリケーションへの統合:



ステップ1:Xコードを開きます。

ステップ2:単一ページのiOSアプリを作成します。

ステップ3:プロジェクトナビゲーターを開きます。

ステップ4:トレーニング済みモデルをプロジェクトナビゲーターにドラッグします。





モデルをプロジェクトナビゲーターに配置します。



ステップ5:Main.storyboard以下に示すように、単純なインターフェイスを開いて作成し、それぞれのビューにIBOutletsとIBActionsを追加します。





UIImageView、UIButtons、およびUILabelsを追加します。



ステップ6:ファイルViewController.swift開き、次のコードを拡張子として追加します。



  extension ViewController: UINavigationControllerDelegate, UIImagePickerControllerDelegate { 
 
 
       func getimage() { 
 
           let imagePicker = UIImagePickerController()
//  UIImagePickerController()
 
           imagePicker.delegate = self //  
 
           imagePicker.sourceType = .photoLibrary  //       
 
           imagePicker.allowsEditing = true  //   
 
           present(imagePicker, animated: true)  //  UIPickerView
 
       } 
 
       func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo : [UIImagePickerController.InfoKey: Any]) { 
 
           let fimage = info[.editedImage] as!UIImage 
//      .editedImage   info 
 
           //    UIImage
 
           fruitImageView.image = fimage  
//    UIImageView
 
           dismiss(animated: true, completion: nil)  //   ,    
 
       } 
 
       func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { 
 
           dismiss(animated: true, completion: nil)  
//     ,     
 
       } 
 
   } 




説明:ここでは、ViewControllerクラスの拡張機能を作成し、UINavigationControllerDelegateとUIImagePickerControllerDelegateを実装して、ユーザーがPickImageUIButtonをクリックしたときにUIImagePickerViewを表示します。デリゲートコンテキストを設定してください。







iOSアプリケーションでCoreMLモデルにアクセスするための手順







ステップ1:次のライブラリをインポートしたことを確認します。



import CoreML 
 import Vision




ステップ2:Model CoreMLクラスのインスタンスを作成します。



let modelobj = ImageClassifier()




ステップ3:Core MLに分類を強制するには、最初にタイプVNCoreMLRequestのリクエストを作成する必要があります(VNはVisionの略です)



var myrequest: VNCoreMLRequest? 
//  VNCoreMLRequest
 
myrequest = VNCoreMLRequest(model: fruitmodel, completionHandler: { (request, error) in    
//    
 
               //  ,     Core ML
 
               self.handleResult(request: request, error: error)
//  
 
                                                     })




ステップ4:CoreMLモデルと互換性があるように画像をトリミングしてください。 ステップ5:リクエストオブジェクトを返すカスタム関数に上記のコードを配置します。



myrequest!.imageCropAndScaleOption = .centerCrop







 func mlrequest() - > VNCoreMLRequest { 
        var myrequest: VNCoreMLRequest ? 
            let modelobj = ImageClassifier() 
        do { 
            let fruitmodel = 
                try VNCoreMLModel( 
                    for: modelobj.model) 
 
           myrequest = VNCoreMLRequest(model: fruitmodel, completionHandler: {   
                (request, error) in self.handleResult(request: request, error: error) 
          
           }) 
 
       } catch { 
           print("Unable to create a request") 
 
       } 
 
       myrequest!.imageCropAndScaleOption = .centerCrop 
        return myrequest! 
    } 




ステップ6:UIImageをCIImage(CI:CoreImage)に変換して、CoreMLモデルへの入力として使用できるようにする必要があります。これは、コンストラクターでUIImageを渡してCIImageをインスタンス化することで簡単に実行できます。



guard  let ciImage = CIImage(image: image)  else { 
       return 
    } 




ステップ7VNCoreMLRequestリクエストハンドラーを作成してを渡すことで、処理できるようになりましたciImage



let handler = VNImageRequestHandler(ciImage: ciImage)




ステップ8:メソッドperform()呼び出してパラメーターとして渡すことにより、要求を実行できますVNCoreMLRequest



DispatchQueue.global(qos: .userInitiated).async { 
       let handler = VNImageRequestHandler(ciImage: ciImage) 
       do { 
           try handler.perform([self.mlrequest()]) 
       } catch {  
           print("Failed to get the description")  
       }  
   } 




説明:DispatchQueueは、アプリケーションのメイン(またはバックグラウンド)スレッドでタスクの実行を順次(または同時に)管理するオブジェクトです。



ステップ10:以下に示すように、上記のコードをカスタム関数に配置します。



func excecuteRequest(image: UIImage) { 
 
            guard 
            let ciImage = CIImage(image: image) 
            else { 
                return 
            } 
            DispatchQueue.global(qos: .userInitiated).async { 
                let handler = VNImageRequestHandler(ciImage: ciImage) 
                do { 
                    try handler.perform([self.mlrequest()]) 
                } catch { 
                    print("Failed to get the description") 
                } 
            } 




ステップ11エラーhandleResult()オブジェクトVNRequestとエラーオブジェクトをパラメーターとして受け取る名前付きカスタム関数作成します。この関数は、完了時に呼び出されますVNCoreMLRequest



func handleResult(request: VNRequest, error: Error ? ) { 
 
       if let classificationresult = request.results as ? [VNClassificationObservation] {//      VNClassificationObservation
 
           DispatchQueue.main.async { 
               self.fruitnamelbl.text = classificationresult.first!.identifier// UILabel          prperty
                print(classificationresult.first!.identifier)
            } 
        } 
        else { 
            print("Unable to get the results") 
        } 
    }  




DispatchQueue.main.asyncすべての分類タスクはバックグラウンドスレッドで実行されるため、これはUIスレッドまたはメインスレッドを使用してUIKitオブジェクト(この場合はUILabel)を更新するために使用されます。








リスト ViewController.Swift





import UIKit 
    import CoreML 
    import Vision 
    class ViewController: UIViewController { 
        var name: String = "" 
        @IBOutlet weak 
        var fruitnamelbl: UILabel!@IBOutlet weak 
        var fruitImageView: UIImageView!override func viewDidLoad() { 
            super.viewDidLoad() 
            //       .  
        } 
        @IBAction func classifybtnclicked(_ sender: Any) { 
            excecuteRequest(image: fruitImageView.image!) 
        } 
        @IBAction func piclimage(_ sender: Any) { 
            getimage() 
        } 
        func mlrequest() - > VNCoreMLRequest { 
            var myrequest: VNCoreMLRequest ? 
                let modelobj = ImageClassifier() 
           do { 
                let fruitmodel = 
                    try VNCoreMLModel( 
                        for: modelobj.model) 
                myrequest = VNCoreMLRequest(model: fruitmodel, completionHandler: { 
                    (request, error) in self.handleResult(request: request, error: error) 
                }) 
            } catch { 
                print("Unable to create a request") 
            } 
            myrequest!.imageCropAndScaleOption = .centerCrop 
            return myrequest! 
        } 
        func excecuteRequest(image: UIImage) { 
            guard 
            let ciImage = CIImage(image: image) 
            else { 
                return 
            } 
            DispatchQueue.global(qos: .userInitiated).async { 
                let handler = VNImageRequestHandler(ciImage: ciImage) 
                do { 
                    try handler.perform([self.mlrequest()]) 
                } catch { 
                    print("Failed to get the description") 
                } 
            } 
        } 
        func handleResult(request: VNRequest, error: Error ? ) { 
            if let classificationresult = request.results as ? [VNClassificationObservation] { 
                DispatchQueue.main.async { 
                    self.fruitnamelbl.text = classificationresult.first!.identifier 
                    print(classificationresult.first!.identifier) 
                } 
            } 
            else { 
                print("Unable to get the results") 
            } 
        } 
    } 
    extension ViewController: UINavigationControllerDelegate, UIImagePickerControllerDelegate { 
        func getimage() { 
            let imagePicker = UIImagePickerController() 
            imagePicker.delegate = self 
            imagePicker.sourceType = .photoLibrary 
            imagePicker.allowsEditing = true 
            present(imagePicker, animated: true) 
        } 
        func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) { 
            let fimage = info[.editedImage] as!UIImage 
            fruitImageView.image = fimage 
            dismiss(animated: true, completion: nil) 
        } 
        func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { 
            dismiss(animated: true, completion: nil) 
        } 
    }




すべての準備ができました!







次に、シミュレータを起動して、アプリケーションをテストします。



:シミュレーターのフォトライブラリにオレンジとイチゴの写真があることを確認してください。






[画像を





選択]ボタンをクリックします任意の画像





選択します[分類]ボタン





をクリックします別の画像を選択して[分類]をクリックします



やったー:



CoreMLを使用して最初のiOSアプリケーションを作成しました。



まだ:






All Articles