在這裡,我們將設置您的示例應用程式,設置模型,弄清楚如何處理應用程式中的分類請求,並將轉換後的ResNet模型添加到項目中。
介紹
深度神經網絡在諸如圖像分類等任務上非常出色。擁有一半像樣的GPU的任何人現在都可以輕鬆獲得十年前耗資數百萬美元的結果以及整個研究團隊。但是,深度神經網絡有一個缺點。它們可能非常沉重且緩慢,因此它們並不總是在行動裝置上運行良好。幸運的是,Core ML提供了一個解決方案:它使您能夠創建在iOS設備上運行良好的苗條模型。
在本系列文章中,我們將向您展示如何以兩種方式使用Core ML。首先,您將學習如何將預先訓練的圖像分類器模型轉換為Core ML並在iOS應用中使用它。然後,您將訓練自己的機器學習(ML)模型並將其用於製作Not Hotdog應用程式-就像您在HBO的矽谷所見過的那樣。
在上一篇文章中將ResNet模型轉換為Core ML格式後,我們現在將在一個簡單的iOS應用程式中使用它。
設置示例應用程式
為了專注於手頭的主要任務-展示轉換後的ResNet模型的用法-我們將「借用」 Apple開發人員站點上可用的示例圖像分類應用程式。當您使用Xcode打開下載的應用程式項目時,將顯示簡短的「切題」說明:
看看-此說明可能會回答您的很多問題。要在iOS設備上運行示例應用程式,您需要執行設置團隊和唯一捆綁包標識符的常規步驟。我們建議您在真實設備上運行該應用程式,以便能夠使用該設備的相機。
該示例應用程式具有
ImageClassificationViewController
處理ML處理的三種主要方法。
設置模型
模型設置和分配給延遲初始化的classificationRequest變量:
lazy var classificationRequest: VNCoreMLRequest = { do { /* Use the Swift class `MobileNet` Core ML generates from the model. To use a different Core ML classifier model, add it to the project and replace `MobileNet` with that model's generated Swift class. */ let model = try VNCoreMLModel(for: MobileNet().model) let request = VNCoreMLRequest(model: model, completionHandler: { [weak self] request, error in self?.processClassifications(for: request, error: error) }) request.imageCropAndScaleOption = .centerCrop return request } catch { fatalError("Failed to load Vision ML model: \(error)") } }()
上面的代碼片段中最重要的一行是模型分配(let model = (…))。在許多情況下,這是切換到其他模型時唯一要更新的行。
注意VN類名稱中的前綴。這意味著這些類是Vision框架的一部分。該框架提供了高級API,旨在處理計算機視覺任務,例如面部和身體檢測,矩形檢測,身體和手姿勢檢測,文本檢測等。除了這些內部使用Apple創建的模型的高級API之外,Vision框架還公開了使用自定義Core ML模型進行ML圖像分析時非常方便的API。
雖然您可以直接使用Core ML,但是擁有Vision層可以減輕一些瑣碎的任務,例如圖像縮放和裁切,色彩空間和方向的轉換等。
在我們的示例應用程式中,一行代碼可以處理所有必需的任務:request.imageCropAndScaleOption = .centerCrop
每次模型分類完成時,processClassifications都會調用該方法來相應地更新UI。
在您的應用程式中處理分類請求
updateClassifications其他應用程式組件調用下一個方法,以啟動圖像分類:
func updateClassifications(for image: UIImage) { classificationLabel.text = "Classifying..." let orientation = CGImagePropertyOrientation(image.imageOrientation) guard let ciImage = CIImage(image: image) else { fatalError("Unable to create \(CIImage.self) from \(image).") } DispatchQueue.global(qos: .userInitiated).async { let handler = VNImageRequestHandler(ciImage: ciImage, orientation: orientation) do { try handler.perform([self.classificationRequest]) } catch { /* This handler catches general image processing errors. The `classificationRequest`'s completion handler `processClassifications(_:error:)` catches errors specific to processing that request. */ print("Failed to perform classification.\n\(error.localizedDescription)") } } }
此方法接受單個參數,image並classificationRequest以線程安全的方式在內部調用先前配置的參數。
顯示分類結果
最後一種「主要」方法負責使用分類結果更新UI:
func processClassifications(for request: VNRequest, error: Error?) { DispatchQueue.main.async { guard let results = request.results else { self.classificationLabel.text = "Unable to classify image.\n\(error!.localizedDescription)" return } // The `results` will always be `VNClassificationObservation`s, as specified by the Core ML model in this project. let classifications = results as! [VNClassificationObservation] if classifications.isEmpty { self.classificationLabel.text = "Nothing recognized." } else { // Display top classifications ranked by confidence in the UI. let topClassifications = classifications.prefix(2) let descriptions = topClassifications.map { classification in // Formats the classification for display; e.g. "(0.37) cliff, drop, drop-off". return String(format: " (%.2f) %@", classification.confidence, classification.identifier) } self.classificationLabel.text = "Classification:\n" + descriptions.joined(separator: "\n") } } }
此方法顯示模型可信度最高的前兩個預測標籤(let topClassifications =classifications.prefix(2))。
其餘方法處理相機和捕獲的圖片。它們不是特定於ML的。
Inspec MobileNet模型
如果單擊資源管理器中的MobileNet.mlmodel文件,則可以檢查模型詳細信息:
除了「輸入和輸出」定義外,此處還提供了大量的元數據:作者,詳細說明和許可證。
將模型添加到應用程式
現在是時候將我們轉換後的ResNet模型添加到項目中了。最簡單的方法是將其從Finder中拖放到Xcode的資源管理器中。請記住,這僅將模型連結到應用程式。該模型並未物理複製到項目文件夾中。如果要將新模型與應用程式的其餘部分保留在一起,則需要在連結之前手動將其複製到那裡。
完成此步驟後,您可以查看ResNet模型描述:
在我們的情況下,僅指定名稱,類型,大小,輸入和輸出。如果您考慮分發模型,則應考慮使用有意義的信息填充這些欄位。這可以使用coremltoolsPython庫完成。
使用轉換後的ResNet模型運行您的應用
要使用您拖放到Xcode項目中的轉換後的模型,我們需要在ImageClassificationViewController.swift文件中更改一行代碼:
因為在轉換過程中我們選擇「 13」作為最低iOS版本,所以您需要相應地更改目標平臺設置:
完成上述更改後,您可以使用ResNet模型立即運行預測:
MobileNet和ResNet模型之間的區別很明顯:MobileNet返回具有置信度概率的標籤(由於softmax層),而ResNet返回「原始」,未縮放的神經網絡輸出。如果需要,可以通過在ResNet模型中添加自定義層或通過對應用程式中返回的結果計算softmax來解決此問題。
摘要
現在,我們有一個示例應用程式,可以與轉換後的ResNet圖像分類模型一起正常運行。事實證明,iOS 13設備不僅能夠成功運行簡化的「移動」 ML模型,而且還能夠成功運行原始(大型)模型。
看起來我們可以在iOS應用中使用任何圖像分類模型(包括轉換後的模型)。為了達到本系列的目標,我們現在需要的是一個可以檢測熱狗的模型。MobileNet和ResNet模型都已經能夠檢測熱狗,但是這裡有趣的任務是了解它們如何實現。