前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Turi Create 机器学习模型实战:你也能轻松做出Prisma 风格的图片!

Turi Create 机器学习模型实战:你也能轻松做出Prisma 风格的图片!

作者头像
iOSDevLog
发布2018-10-10 11:20:18
1.5K0
发布2018-10-10 11:20:18
举报
文章被收录于专栏:iOSDevLogiOSDevLog

如果你一直有关注Apple去年所发布的消息,就会知道他们在机器学习上投入了大量心力。自他们去年在WWDC 2017上推出Core ML以来,已经有大量结合机器学习技术的应用程序涌现。

但是,开发人员经常遇到的其中一个挑战是:如何创建模型?幸运的是,Apple在去年冬天宣布从GraphLab收购了Turi Create,正正解决了我们的问题。Turi Create是Apple的工具,可以帮助开发人员简化创建客制化模型的步骤。使用Turi Create,你可以建立自己的客制化机器学习模型。

Turi Create 快速入门

如果你有关注其他机器学习教学文章,你可能会觉得奇怪,「今年Apple不是有发布一个叫Create ML的工具吗?那相较于Create ML来说,Turi Create有什么优势?」

虽然对于刚开始研究机器学习的人来说,Create ML 是一个很好的工具,但它在使用方面严重受到限制,例如只能使用文本或图像数据。虽然这已经可以完成大多数的项目,但是对于稍微复杂的机器学习应用程序(例如风格转换(Style Transfer)), Create ML 就可能会变得毫无用处。

使用Turi Create,你除了可以创建所有原本使用Create ML创建出的Core ML模型之外,更能创造更多不同类型的模型!由于Turi Create比Create ML复杂得多,因此它与其他机器学习工具如KerasTensorFlow有高度的整合性。在我们的CreateML教学之中,你看到我们可以使用Create ML制作Core ML模型的类型。以下是你可以使用Turi Create制作的演算法类型:

你可以看到列表中包含了分类器与回归器(regressors),它们都可以使用Create ML 或Turi Create 来完成。这就是为什么Turi Create被更有经验的数据科学家所青睐,因为它提供了一种在Create ML中无法提供的可定制性。

什么是风格转换?

现在你大致了解到什么是Turi Create,那么让我们来看看什么是风格转换。风格转换是一种使用另一张图像风格将图像重新组合的技术,即是什么意思?看看下面利用Prisma 创造出来的图像:

Style Transfer Example

如你所见,上面早餐餐盘的图像风格转换成漫画了。由Gatys等人发表了一篇论文,描述如何使用卷积神经网路(Convolutional Neural Networks, CNNs)将一张图像的美术风格转换到另一张图像,风格转换就开始兴起。

卷积神经网路是一种机器学习的神经网路,通常应用于图像辨识及分类。它已经成功地解决电脑视觉方面的问题,例如:脸部辨识、物件辨识等。这是一个复杂的议题,所以我不会在这里讨论太多。

构建自己的风格转换应用程序

现在你已经了解了本教学涵盖到的工具和概念,我们终于可以开始了!我们将会利用Turi Create 构建自己的风格转换模型,并把它汇入iOS 项目来看看效果!

coreml-turi-create-1

首先,在这里下载起始项目,在本次的教学中我们将会用到Python 2、Jupyter Notebook和Xcode 9。

训练风格转换模型

Turi Create是一个Python套件,但它并没有内建在macOS里面,所以让我带你快速安装它。你的macOS应该已经安装了Python,若你的设备还没有安装Pythonpip,你可以在这里了解安装流程。

安装Turi Create 及Jupyter

打开终端机并输入下列指令:

代码语言:javascript
复制
pip install turicreate==5.0b2

Python套件安装过程大约1-2分钟。与此同时,我们可以下载Jupyter Notebook。Jupyter Notebook是一个供开发人员使用、支持许多语言的编译器,它包含丰富和互动的输出视觉效果。由于Turi Create仅支持Python 2,因此请在终端机输入以下命令以安装适用于Python 2的Jupyter Notebook。

代码语言:javascript
复制
python  -m  pip install  --upgrade pip

python  -m  pip install jupyter

coreml-turi-terminal-message

当所有的套件都安装好,就可以开始创造我们的演算法了!

使用Turi Create 撰写程序

我们即将构建的风格转换模型会以梵谷的作品星夜(Starry Night)为基础。简单来说,我们创造的模型可以将任何图像转换成星夜(Starry Night)风格的复制品。

starry-night-1093721_1280

首先,下载训练数据并解压,里面有一个content资料夹和一个style资料夹。打开content资料夹,你会看到大约有70张不同的图片。这个资料夹包含了各式各样的图片,这样就可以让我们的演算法知道有什么类型的图片需要做转换。因为我们想要转换所有图像,我们就需要有多样化的图片才行。

而在Style资料夹中就很简单地只有一张图片:StarryNight.jpg。这个资料夹包含了我们想要转换的美术风格来源。

现在,让我们打开Jupyter Notebook开始撰写代码。输入下列指令到终端机中:

代码语言:javascript
复制
jupyter notebook

这将会打开Safari 并显示这个页面:

coreml-turi-create-4

点击New按钮,然后按下Python 2!

备注:请确认你的Jupyter Notebook是在使用Python 2,这一点非常重要,因为目前Turi Create并不支持Python 3。译者注: Turi Create未来可能会支持Python 3

按下按钮后,将会弹出一个新页面,这就是我们要建立模型的地方。按下第一个Cell,并汇入Turi Create 套件:

代码语言:javascript
复制
import  turicreate as  tc

按下SHIFT+Enter 来执行这一个Cell 中的代码,等待套件汇入完成。下一步,来创建一个包含图像资料夹的参考。请确认你已经把代码中的参数设为资料夹的路径。

代码语言:javascript
复制
style  =  tc.load_images('/Path/To/Folder/style')

content  =  tc.load_images('/Path/To/Folder/content')

执行代码后,你应该会收到这样输出讯息:

coreml-turi-create-6

不用太担心这样的警告。接下来,我们将输入指令来创建风格转换模型。强烈建议你一台在拥有GPU运算资源的Mac上执行下列代码,像是最新的MacBook Pro或iMac。如果你选择在MacBook Air上执行,那么程序将会透过CPU来运算,这可能会花上好几天的时间。

代码语言:javascript
复制
model  =  tc.style_transfer.create(style,  content)

执行代码,这可能因为你的设备而花上一段很长的时间才能完成,像我在MacBook Air上透过CPU运算就花了3天半才完成。如果你没有足够的时间,不用担心,你可以在这里下载最后的Core ML模型(CoreML模型名为“StarryStyle”)。然而,可以的话你还是试试执行整个程序,感受一下它是怎样运作的!

coreml-turi-create-7

你可以看到表格中包含了三个栏位: Iteration(叠代次数)Loss(损失)Elapsed Time(花费时间)。在机器学习之中,会有特定函数执行多次向前和向后运算。当函数向前运算就是cost,往后运算就是loss。每次执行函数时,目的是调整参数来减少Loss。因此每次更改参数时,就会在增加一次Iteration,目标是为了得到更少的Loss。在训练的过程中,你可以发现Loss会渐渐地变少。而Elapsed time指的就是运算所消耗的时间。

当模型已经完成训练,只需要储存它就可以了!这可以简单地用一行代码来完成!

代码语言:javascript
复制
model.export_coreml("StarryStyle.mlmodel")

image

就这样完成了,你可以到函式库看看最终的模型!

coreml-turi-create-9

Xcode 项目概览

现在我们已经有了自己的模型,剩下来要做的就是将它汇入到Xcode 项目之中。打开Xcode 9 来看一下我们的项目。

turi create demo app

构建并执行项目,这样可以确认我们可以编译此项目。应用程序目前还未能运作,当你按下Van Gogh!按钮,你会发现什么事都没发生!现在,轮到我们来撰写代码了,让我们开始吧!

实战机器学习

首先,将我们的模型文件(即是StarryStyle.mlmodel)拖曳到项目之中,请确保你有勾选Copy Items If Needed,以及已经选了目标项目。

Import Core ML Model

接下来,我们需要在ViewController.swift加入代码来处理机器学习流程,大部分的代码会在transformImage()函数中撰写。让我们从汇入Core ML套件并调用模型开始吧!

代码语言:javascript
复制
import  CoreML

...

@IBAction func  transformImage(_  sender:  Any)  {

    // Style Transfer Here

    let  model  =  StarryStyle()

}

这行代码简单地将Core ML模型指定为叫做model的常数。

图像转换

下一步,我们需要将使用者所选取的图像转换成可读数据。再看看StarryStyle.mlmodel文件,你就会发现它接受的图像尺寸是256×256,因此我们必须执行转换。在我们的transformImage()函数下方加入一个新的函数。

代码语言:javascript
复制
func  pixelBuffer(from image:  UIImage)  ->  CVPixelBuffer?  {

    // 1

    UIGraphicsBeginImageContextWithOptions(CGSize(width:  256,  height:  256),  true,  2.0)

    image.draw(in:  CGRect(x:  0,  y:  0,  width:  256,  height:  256))

    let  newImage  =  UIGraphicsGetImageFromCurrentImageContext()!

    UIGraphicsEndImageContext()

    // 2

    let  attrs  =  [kCVPixelBufferCGImageCompatibilityKey:  kCFBooleanTrue,  kCVPixelBufferCGBitmapContextCompatibilityKey:  kCFBooleanTrue]  as  CFDictionary

    var  pixelBuffer  :  CVPixelBuffer?

    let  status  =  CVPixelBufferCreate(kCFAllocatorDefault,  256,  256,  kCVPixelFormatType_32ARGB,  attrs,  &pixelBuffer)

    guard  (status  ==  kCVReturnSuccess)  else  {

        return  nil

    }

    // 3

    CVPixelBufferLockBaseAddress(pixelBuffer!,  CVPixelBufferLockFlags(rawValue:  0))

    let  pixelData  =  CVPixelBufferGetBaseAddress(pixelBuffer!)

    // 4

    let  rgbColorSpace  =  CGColorSpaceCreateDeviceRGB()

    let  context  =  CGContext(data:  pixelData,  width:  256,  height:  256,  bitsPerComponent:  8,  bytesPerRow:  CVPixelBufferGetBytesPerRow(pixelBuffer!),  space:  rgbColorSpace,  bitmapInfo:  CGImageAlphaInfo.noneSkipFirst.rawValue)

    // 5

    context?.translateBy(x:  0,  y:  256)

    context?.scaleBy(x:  1.0,  y:  -1.0)

    // 6

    UIGraphicsPushContext(context!)

    image.draw(in:  CGRect(x:  0,  y:  0,  width:  256,  height:  256))

    UIGraphicsPopContext()

    CVPixelBufferUnlockBaseAddress(pixelBuffer!,  CVPixelBufferLockFlags(rawValue:  0))

    return  pixelBuffer

}

这是一个辅助函数(Helper Function),与我们之前Core ML教学文章所使用的函数有点相似。如果你已经忘了,别担心,让我一步一步解释这个函数。

  1. 因为我们的模型只能接受尺寸为256 x 256的图像,所以我们将图片转换为正方形,接着将正方形图像指定到另一个newImage的常数。
  2. 现在,我们将newImage转换成为CVPixelBuffer。如果你对CVPixelBuffer不熟悉,它基本上是一个图像缓冲区,用来将像素存于主要记忆体中。你可以在这里了解更多关于CVPixelBuffers的资讯。
  3. 取得图片中的所有像素后,我们将它转换成设备所对应的RGB色彩空间。接着,将所有数据创建为CGContext,当我们需要渲染(或改变)某些底层的属性时,就可以简单地调用它,这是我们在下列两行代码中透过转化及缩放图像所做的事。
  4. 最后,我们将图像内容放入当前内容中,渲染图像,并移除堆叠最上层的内容。当这些变更都完成后,回传像素缓冲器。

这其实是一些非常进阶的Core Image代码,已经超出了本篇教学文章的范围。如果有某些部分不了解其实不用担心。整段代码的主要目的,是藉由转换一张图像为像素缓冲器来提取它的数据,让Core ML可以更方便地读取它。

将风格转换应用于图像

现在我们有了Core ML辅助函数,让我们回到transformImage()并实战代码。在我们声明 model常数的那行下面,输入下列代码:

代码语言:javascript
复制
let  styleArray  =  try?  MLMultiArray(shape:  [1]  as  [NSNumber],  dataType:  .double)

styleArray?[0]  =  1.0

Turi Create允许你将多于一种「风格」打包到模型之中,虽然这次的项目只有一种风格,就是Starry Night。如果你想添加更多种风格,你可以加入更多图片到style资料夹中。我们将styleArray声明 为MLMultiArray,这是一种被Core ML所使用来作模型输入及输出的阵列型态。由于我们只有一种风格,所以只有一种形状及数据元素,因此我们将styleArray的数据元素设为1。

coreml-turi-create-14

最后,只需要利用我们的模型进行预测,并将结果设置为imageView

代码语言:javascript
复制
if  let  image  =  pixelBuffer(from:  imageView.image!)  {

    do  {

        let  predictionOutput  =  try  model.prediction(image:  image,  index:  styleArray!)

        let  ciImage  =  CIImage(cvPixelBuffer:  predictionOutput.stylizedImage)

        let  tempContext  =  CIContext(options:  nil)

        let  tempImage  =  tempContext.createCGImage(ciImage,  from:  CGRect(x:  0,  y:  0,  width:  CVPixelBufferGetWidth(predictionOutput.stylizedImage),  height:  CVPixelBufferGetHeight(predictionOutput.stylizedImage)))

        imageView.image  =  UIImage(cgImage:  tempImage!)

    }  catch  let  error  as  NSError  {

        print("CoreML Model Error: \(error)")

    }

}

这个函数首先检查imageView之中是否有图像。在这段代码中,我们先定义了predictionOutput用来储存模型预测的输出结果。我们以使用者的影像以及风格阵列作为参数,调用模型的prediction方法。预测的结果是像素缓冲器,但是我们无法将像素缓冲器设定为UIImageView,因此我们想出了一个非常有创意的方法来实现。

首先,我们将像素缓冲器predictionOutput.stylizedImage设置为CIImage类型的图像。然后,创建一个tempContext变量,它是CIContext的实例。我们调用context的内建函数(也就是createCGImage),它从ciImage产生CGImage。最后,我们可以将imageView设置为tempImage。这样就完成了!如果有任何错误,我们可以将错误印出来好好处理。

构建并执行项目。你可以从图库中选一张图片,然后测试应用程序!

Core ML Style Transfer Demo

你可能会注意到模型的输出结果看起来不太接近原本的Starry Night,而这种情况可以有很多原因。可能我们需要更多的训练数据?或是我们训练数据时需要更多次的叠代次数?我强烈的建议你回到前面几个步骤,再玩玩这些参数,直到你满意输出结果为止!

总结

教学文章就到此为止了!我已经向你介绍了Turi Create,并创造了你自己​​的风格转换模型,如果是在5 年前,一个人定必无法完成。你也学习到了如何将Core ML 模型汇入iOS 应用程序中,并有创意地应用它!

但是,风格转换只是一个开始。如我在前文提过,Turi Create 可以用来创造各类型的应用程序,下面是一些帮助你更进一步的资源:

如果需要完整的项目,请到GitHub下载。如果你有任何意见或问题,请在下面留言,与我分享你的想法。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018.09.25 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Turi Create 快速入门
  • 什么是风格转换?
  • 构建自己的风格转换应用程序
  • 训练风格转换模型
    • 安装Turi Create 及Jupyter
      • 使用Turi Create 撰写程序
      • Xcode 项目概览
      • 实战机器学习
        • 图像转换
          • 将风格转换应用于图像
          • 总结
          相关产品与服务
          TI-ONE 训练平台
          TI-ONE 训练平台(以下简称TI-ONE)是为 AI 工程师打造的一站式机器学习平台,为用户提供从数据接入、模型训练、模型管理到模型服务的全流程开发支持。TI-ONE 支持多种训练方式和算法框架,满足不同 AI 应用场景的需求。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档