NSFW模型的iOS CoreML项目[Swift]
一个使用CoreML和开放nsfw模型的小型iOS项目。
自从WWDC2017首次宣布以来,Apple的Core ML已经问世了一段时间。 这是一个令人兴奋的新框架,有了iOS 11,在macOS和iOS上运行ML模型变得更加容易。 Apple提供了许多已经采用Core ML模型格式的开源模型,可以在这里找到。
我的示例项目将使用Yahoo的开放式nsfw模型和python coremltools进行转换。
为了编写Core ML并在您的设备上运行它,您将需要:
- Xcode 9 Beta
- iOS 11测试版
- 打开nsfw模型
- Python coremltools 0.4.0 我不会详细介绍安装Python的细节。 您将需要Python 2.7作为coremltools。
- 入门项目 我已经编写了一些UI代码,因此您可以专注于对ML部分进行编码🙂
1.将.caffemodel转换为.mlmodel
由于Yahoo的开放式nsfw模型为caffe模型格式,因此我们需要首先将其转换为CoreML模型格式。 我用python coremltools编写了一个简短的脚本来完成该任务。 该软件包的文档可以在这里找到。
在您刚刚从Yahoo的GitHub页面下载的“ open_nsfw_master ”项目中,进入其子文件夹“ nsfw_model ”并创建convert.py 。
import coremltools#将caffe模型转换为Core ML模型caffe_model =('resnet_50_1by2_nsfw.caffemodel','deploy.prototxt') coreml_model = coremltools.converters.caffe.convert(caffe_model, image_input_names ='数据', is_bgr = True, red_bias = -104, blue_bias = -123, green_bias = -117, image_scale = 1)#保存模型coreml_model.save('nsfw.mlmodel')
需要注意的一点是:隐蔽方法的输入基于下面打开的nsfw项目中classify_nsfw.py的代码。
#…#负载变压器 #请注意,这些参数是硬编码的,以获得最佳结果caffe_transformer = caffe.io.Transformer({'data':nsfw_net.blobs ['data']。data.shape})caffe_transformer.set_transpose('data',(2,0 ,1)) #将图像通道移动到externalmostcaffe_transformer.set_mean('data',np.array([104,117,123])) #减去每个channelcaffe_transformer.set_raw_scale('data',255)中的数据集平均值 #从[0,1]缩放为[0,255] caffe_transformer.set_channel_swap('data',(2,1,0)) #从RGB交换通道到BGR#…
打开“终端”,cd到您的本地目录,其中包含convert.py , resnet_50_1by2_nsfw.caffemodel和deploy.prototxt 。
运行“ python convert.py ”。 控制台将开始转换并打印模型的每一层。 完成后,您将在同一目录中获得一个可供使用的nsfw.mlmodel 。
2.将nsfw.mlmodel添加到Xcode项目
只需将nsfw.mlmodel拖到左侧的文件导航器中即可。 确保在右侧导航器的“目标成员身份”中选中了您的项目。 Xcode将为您自动在Swift或Objetive-C中生成模型类的源代码。 要查看自动生成的类,请单击nsfw模型类旁边的小箭头。
在本教程中,我将使用Swift。 如果要切换语言,请在导航器中单击您的项目,转到“构建设置”,然后搜索CoreML Model Compiler –代码生成 。 您可以从CoreML代码生成语言下的不同选项中进行选择。
现在,我们准备在代码中创建nsfw模型。 只需使用生成的nsfw类的初始化程序,然后在ViewController.swift中的IBOutlet之前添加以下行:
让模型= nsfw()
3.代码
让我们快速看一下nsfw类的生成代码。 由于nsfw模型的输入类型为CVPixelBuffer (224 x 224) 而且现在只有UIImage ,让我们编写一些代码进行转换。 在ViewController.swift的末尾,将以下扩展添加到UIImage 。
// MARK:— UIImage 扩展程序UIImage { func buffer()-> CVPixelBuffer? { var pixelBuffer:CVPixelBuffer? =零宽度= 224 让高度= 224让属性= [kCVPixelBufferCGImageCompatibilityKey: kCFBooleanTrue, kCVPixelBufferCGBitmapContextCompatibilityKey: kCFBooleanTrue]作为CFDictionary CVPixelBufferCreate(kCFAllocatorDefault,width,height, kCVPixelFormatType_32ARGB,attrs,&pixelBuffer) CVPixelBufferLockBaseAddress(pixelBuffer !, CVPixelBufferLockFlags(rawValue:0))让colorspace = CGColorSpaceCreateDeviceRGB() 让bitmapContext = CGContext(data: CVPixelBufferGetBaseAddress(pixelBuffer!), 宽度:宽度, 高度:高度 bitsPerComponent:8 bytesPerRow: CVPixelBufferGetBytesPerRow(pixelBuffer!), 空间:色彩空间, bitmapInfo: CGImageAlphaInfo.noneSkipFirst.rawValue)! bitmapContext.draw(self.cgImage !,在: CGRect(x:0,y:0,width:width,height:height))返回pixelBuffer } }
在ViewController内,我创建了一个名为detectPhoto(image:UIImage)的函数,除了在从相机胶卷中选择一张照片后将标签更改为“ predicting”之外,它现在实际上并没有执行任何操作。 这是主要部分:现在,我们将添加用于预测照片是否适合工作的代码。 在完成所有准备工作之后,此步骤相当容易。 在detectPhoto(image:UIImage)中///之后添加以下代码。
//将UIImage转换为CVPixelBuffer 让buffer = image.buffer()! //预测 守护让输出=尝试? model.prediction(data:buffer)else { fatalError(“意外的运行时错误。”) } //获取预测结果 let proba = output.prob [1] .doubleValue //更新答案 labelself.answerLabel.text =字符串(格式:“%。6f”,proba)
4.获得预测
在手机或模拟器上运行该应用程序。 从您的相册中选择一张照片,最终乐谱将打印在屏幕上。
从nsfw模型的GitHub页面上的REAMDE:
网络获取图像并给出输出概率(分数在0–1之间),该概率可用于过滤不适合工作图像的图像。 得分 0.8表示该图像很有可能是NSFW。 中间范围的分数可以针对不同的NSFW级别进行分类。
您还可以在其博客页面上找到有关该模型的信息。
这是我得到的两个示例结果。 可爱的小猫绝对比穿着比基尼的辣妹更安全的工作。😉希望这个小项目对您有所帮助。 您还可以在这里找到该项目的完整版本。