EmptyWalker

黑夜给了我黑色的眼睛,我却用它寻找光明

欢迎来到空行者小站


「译」使用 Python 和 Turi Create 创建一个自定义的 Core ML 模型

本文是翻译于AppCoda社区,如有版权问题,请告知,会配合处理

原文地址

在过去的几年里,使用机器学习的方式去解决问题和执行复杂任务一直在增加。机器学习使我们可以使用大数据去解决复杂任务,比如:图片分类和语音识别。苹果最近宣布一个框架去简化把机器学习模型集成到 macOS, iOS, tvOS 和 watchOS 设备中的过程,这个框架叫做 Core ML 。苹果也提供了示例 Core ML 模型去测试框架。

Core ML 首次发布时,对开发者来说,去创建一个自己的 Core ML 模型是一个非常大的挑战,因为需要之前就有机器学习的经验。

然而,感谢 GraphLab 和 Apple ,现在我们有了 Turi Create , 一个使我们可以简单的创建 Core ML 模型的框架。 Turi Create 为了可以创建我们自己的机器学习模型,给我们提供了基本的机器学习算法,比如:K-近邻算法,和高级深度学习算法,比如: Residual Networks (ResNet) 。

在本教程中,我将会演示如何创建一个自定义的图片分类器 Core ML 模型,并把它集成到 iOS 应用程序中。为了完成目标,我们将会使用 Python 2.7Turi CreateSwift 4.0Core ML

在开始之前,你需要以下信息:

  • 一个有 64 位处理器的计算机( x86_64 架构)
  • Python , 2.7 版本:这里下载

开始!

为了开始,我们首先需要使用 Python 的包管理器 pip 去安装 Turi Create 。包管理器是你在机器上安装 Python 时附带的。

为了安装 Turi Create,打开终端,输入以下命令:

$ pip install turicreate

Python 包安装好了之后,我们将通过以下步骤去创建一个新的 Python 项目:

  1. 创建一个 MLClassifier 文件夹
  2. 打开 Xcode ,创建一个新文件

  1. 从其它组中选一个 Empty 文件

  1. 文件命名为 classifier.py
  2. 把它保存到 MLClassifier 文件夹中

创建一个数据集

在本例中,我们将创建一个机器学习模型,去分类一个图片是包含米还是汤。为了做到这个,我们将要创建一个包含所有种类图片的数据集。这个数据的设置是用于训练我们的模型。你可以下载我使用的数据集,并保存早 MLClassifier 文件夹中。或者你可以通过下面的步骤来创建自己的数据集:

  1. MLClassifier 文件夹中,创建一个新的 dataset 文件夹。
  2. dataset 里面,创建两个空的文件夹 ricesoup
  3. rice 里面,添加至少 100 张不同大米的图片。
  4. soup 里面,添加至少 100 张不同汤的图片。

dataset 文件夹中的内容应该像下面这样:

实现 Turi Create

Turi Create 简化了自定义机器模型的开发过程。你不需要成为一名机器学习的专家,就能为你的 app 添加推荐、对象识别、图片分类、图片相似性或活动分类。

—— Turi Create 官方文档

在这部分,我们将会在 Python 项目中实现 turicreate ,标记我们在前面创建的数据集中的每个图片。让我们来通过以下步骤实现和配置我们的框架。

  1. 打开 classifier.py 文件,通过下面一行代码导入 turicreate
import turicreate as turi
  1. 接下里,定义数据集的路径:
url = "dataset/"
  1. 然后添加下面的代码去寻找和加载数据集文件夹里的图片:
datad  = turi.image_analysis.load_images(url)
  1. 继续添加下面一行代码,我们基于它们的路径定义图片的类别:
data["foodType"] = data["path"].apply(lambda path: "Rice" if "rice" in path else "Soup")

-给定一张图片,图片分类器的目标就是从确定的标签库中分配一个给它。

  1. 最后,保存新标记的数据集为 rice_or_soup.sframe ,我们将会使用它去训练模型
    data.save("rice_or_soup.sframe")
    
  2. 在 Turi Create 中预览新标记的数据集
data.explore()

训练 & 导出机器学习模型

是时候去训练和导出机器学习模型用于生产! 为了实现这个,我们将使用 turicreate 提供的 SqueezeNet架构选项来训练我们的机器学习模型。我们使用SqueezeNet架构是因为它花费的训练时间更少;然而,为了更准确的结果推荐使用 ResNet-50 。接下来,我将使用两种架构来演示示例:

  1. classifier.py 文件中,我们首先加载前面保存的 rice_or_soup.sframe 文件。在文件中插入下面一行代码:
dataBuffer = turi.SFrame("rice_or_soup.sframe")
  1. 接下来,使用 dataBuffer 对象的 90% 创建训练数据,我们只用剩下的 10% 创建测试数据。
trainingBuffers, testingBuffers = dataBuffer.random_split(0.9)
  1. 继续插入下面的代码,使用训练数据和 SqueezeNet 架构去图片分类器。
model = turi.image_classifier.create(trainingBuffers, target="foodType", model="squeezenet_v1.1")

另外,你也可以使用 ResNet-50 得到一个更精确的结果。

model = turi.image_classifier.create(trainingBuffers, target="foodType", model="resnet-50")
  1. 接下来,我们将会评估测试数据来决定模型的准确度:
evaluations = model.evaluate(testingBuffers)
print evaluations["accuracy"]
  1. 最后,插入下面的代码保存模型,并将图片分类器模型导为 Core ML 模型:
model.save("rice_or_soup.model")
model.export_coreml("RiceSoupClassifier.mlmodel")

你的 classifier.py 文件应该看起来像这样:

现在,是时候运行我们的代码了!因此,来到 Terminal.app ,切换到 MLClassifier 文件夹下,然后执行下面的代码运行 classifier.py 文件:

python classifier.py

只要耐心等待一下,你就会看到下面的信息。

几分钟后 … 你将会有一个 Core ML 模型准备去实现在任何 iOS, macOS, tvOS, 或 watchOS 应用程序中。

把 Core ML 模型集成到一个 iOS app

现在我们准备将我们刚刚创建的自定义 Core ML 模型集成到一个 iOS app中。如果你之前已经读过我们 Core ML 的入门教程,那么你应该对如果集成一个 Core ML 模型到 iOS app 中有一些想法。因此,我将使这部分简短而甜蜜。

  1. 使用 Single Application 模板创建一个新的 iOS 项目,可以命名成任何你你喜欢的名字,但在本示例中要确保使用 Swift 。
  2. 为了使用我们刚刚创建的模型,把训练好的 Core ML 模型( RiceSoupClassifier.mlmodel 文件)拖到项目中。

  3. 在我们的项目中导入 CoreML 框架,然后在 ViewController.swift 文件中添加下面一行代码。
import CoreML
  1. 创建 CoreML 模型对象
let mlModel = RiceSoupClassifier()
  1. 创建应用程序的 UI
 var importButton:UIButton = {
    let btn = UIButton(type: .system)
    btn.setTitle("Import", for: .normal)
    btn.setTitleColor(.white, for: .normal)
    btn.backgroundColor = .black
    btn.frame = CGRect(x: 0, y: 0, width: 110, height: 60)
    btn.center = CGPoint(x: UIScreen.main.bounds.width/2, y: UIScreen.main.bounds.height*0.90)
    btn.layer.cornerRadius = btn.bounds.height/2
    btn.tag = 0
    return btn
}()
    
var previewImg:UIImageView = {
    let img = UIImageView()
    img.frame = CGRect(x: 0, y: 0, width: 350, height: 350)
    img.contentMode = .scaleAspectFit
    img.center = CGPoint(x: UIScreen.main.bounds.width/2, y: UIScreen.main.bounds.height/3)
    return img
}()
    
var descriptionLbl:UILabel = {
    let lbl = UILabel()
    lbl.text = "No Image Content"
    lbl.frame = CGRect(x: 0, y: 0, width: 350, height: 50)
    lbl.textColor = .black
    lbl.textAlignment = .center
    lbl.center = CGPoint(x: UIScreen.main.bounds.width/2, y: UIScreen.main.bounds.height/1.5)
    return lbl
}()
  1. 添加 UIImagePickerController 协议响应 ViewController 类:
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationContro
  1. 创建一个 importFromCameraRoll 方法:
@objc func importFromCameraRoll() {
    if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
        let imagePicker = UIImagePickerController()
        imagePicker.delegate = self
        imagePicker.sourceType = .photoLibrary;
        imagePicker.allowsEditing = true
        self.present(imagePicker, animated: true, completion: nil)
    }
}
  1. viewDidLoad 方法中,把导入按钮和导入方法连接起来,然后将按钮添加到子视图中:
importButton.addTarget(self, action: #selector(importFromCameraRoll), for: .touchUpInside)
self.view.addSubview(previewImg)
self.view.addSubview(descriptionLbl)
self.view.addSubview(importButton)
  1. 创建一个 UIImage 的扩展,添加下面的函数,用于将 UIImage 对接转换成 CVPixelBuffer
extension UIImage {
    func buffer(with size:CGSize) -> CVPixelBuffer? {
        if let image = self.cgImage {
            let frameSize = size
            var pixelBuffer:CVPixelBuffer? = nil
            let status = CVPixelBufferCreate(kCFAllocatorDefault, Int(frameSize.width), Int(frameSize.height), kCVPixelFormatType_32BGRA , nil, &pixelBuffer)
            if status != kCVReturnSuccess {
                return nil
            }
            CVPixelBufferLockBaseAddress(pixelBuffer!, CVPixelBufferLockFlags.init(rawValue: 0))
            let data = CVPixelBufferGetBaseAddress(pixelBuffer!)
            let rgbColorSpace = CGColorSpaceCreateDeviceRGB()
            let bitmapInfo = CGBitmapInfo(rawValue: CGBitmapInfo.byteOrder32Little.rawValue | CGImageAlphaInfo.premultipliedFirst.rawValue)
            let context = CGContext(data: data, width: Int(frameSize.width), height: Int(frameSize.height), bitsPerComponent: 8, bytesPerRow: CVPixelBufferGetBytesPerRow(pixelBuffer!), space: rgbColorSpace, bitmapInfo: bitmapInfo.rawValue)
            context?.draw(image, in: CGRect(x: 0, y: 0, width: image.width, height: image.height))
            CVPixelBufferUnlockBaseAddress(pixelBuffer!, CVPixelBufferLockFlags(rawValue: 0))
            
            return pixelBuffer
        }else{
            return nil
        }
    }
}
  1. ViewController 类中,添加以下方式去分析导入的数据,和将结果显示在 UILabel 中:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
        previewImg.image = image
        if let buffer = image.buffer(with: CGSize(width:224, height:224)) {
            guard let prediction = try? mlModel.prediction(image: buffer) else {fatalError("Unexpected runtime error")}
            descriptionLbl.text = prediction.foodType
            print(prediction.foodTypeProbability)
        }else{
            print("failed buffer")
        }
    }
    dismiss(animated:true, completion: nil)
}

准备测试

就这样!玩的开心哈。运行 app 然后点击 Import 按钮去测试一下。现在,你可以理解如何去创建一个自定义的机器学习模型,并将它们实现在你的应用程序中!

想要下载整个项目,你可以在 GitHub 中找到它。关于本文,你如果有任何问题和想法,可以留在在下方的评论区,让我们知道。

最近的文章

「译」使用 Core ML, Style Transfer 和 Turi Create 创建一个像 Prisma App

本文是翻译于AppCoda社区,如有版权问题,请告知,会配合处理 原文地址如果你从去年一直关注 Apple 的公告,你就知道他们在机器学习领域进行了大量投资。自从他们去年在 WWDC 2017 上介绍了 Core ML 之后,就有大量利用机器学习能力的 app 如雨后春笋般涌现。然后,开发者总会面对一个挑战就是如何创建一个模型?幸运的是,Apple 在去年冬天宣布从 GraphLab 收购了 Turi Create 的时候,就解决了我们的问题。 Turi Create 是 Apple...…

继续阅读
更早的文章

「译」Create ML 介绍:如何在 Xcode 10 中训练自己的机器学习模型

本文是翻译于AppCoda社区,如有版权问题,请告知,会配合处理 原文地址为了防止你没有关注,苹果全球开发者会议于这周开始!这是一个大事件,对苹果当前的软件和框架都做了很多的改进。其中一个框架就是 Create ML 。去年,苹果介绍了 Core ML:一种快速的方法,可以让你用尽可能少的代码把预先训练好的机器学习模型导入到你的 app 中。今年,有了 Create ML ,苹果给了我们开发者直接在 Xcode Playgrounds 中创建自己的机器学习模型的能力!我们只需要一些数...…

继续阅读