前序文章:让我们谈谈turiCreate.聊聊iOS的机器学习这篇文章有讲到如何布置环境,以及turiCreate的基本功能块.
概括
对于这个功能来说.我第一实现试用的时候 很惊讶!准度非常高!效果也是非常不错的.随着我深入,发现他的问题也还是挺大的.他不是多标签的.不能像苹果提供CoreML模型一样反馈的一样的.而且最可怕的是:如果我要识别猫和狗,那么有可能是除了猫,其他的全部都是狗.当然有可能是全部是猫.
功能
数据
我们今天也不分辨猫和狗,这个CoreML的模型里基本都有了.我这边的资源是哆啦A梦,瓦力,我的同事,以及我.那这样他识别的如何呢!!
首先我们准备图片
分类.png
我们要自己先分类好
哆啦A梦.png
瓦力
搞笑的同事
我
我们有数据就可以开动了 环境我们在上一章就配置好了.我就默认大家配置好直接跳过配置环境这一块了!
打开环境
我们Mac打开terminal.app 就是命令框
打开到我们要放置图片的位置的上个文件夹cd /Users/admin/Desktop/script/demo-python-image-classification-master
启动turiCreate的环境source activate turijupyter notebook
创建脚本笔记本
然后我们给新的笔记本重命名就可以开始我们的征途了!
代码
一般我们习惯在引入turiCreate的库之后,用tc来替代它!import turicreate as tc
指定图像文件夹image_folder = 'image'
然后使用turiCreate读取所有图像文件,并且存储到data数据框data = tc.image_analysis.load_images(image_folder, with_path=True)
然后在这里turiCreate读取所有的图像文件之后会反馈一些信息. 是说这个文件无法识别.并不影响.(应该是一些隐藏文件)Unsupported image format. Supported formats are JPEG and PNG file: /Users/admin/Desktop/script/doraemon/.DS_Store
然后我们直接使用data数据 可以打印一些数据.data
可以看到data的包含的数据是 地址和图片的像素.当然我们也可以使用print_rows(num_rows=m, num_columns=n)函数,可以看到你想要看数量.但是我没有找到如何然数据全部显示的方法.
接下来是重点.添加标签.告诉turiCreat哪些是哪些.才能进行训练.
我们通过文件夹的名称来给图片打标记.
我们会使用到apply(lambda :)函数data['label'] = data['path'].apply(lambda path: 'doraemon' if 'doraemon' in path else 'yizhong' if 'yiz' in path else 'walle' if 'walle' in path else 'yyx' )
把Doraemon目录下的图片,按照文件夹的名称进行分类.这只是给我们对应的图片打上标记.比不意味着说分类就是这样其他剩下的都是 'yyx'.
我们在打印一下datadata
则得到了我们需要对应图片的类别
我们可以吧数据存储一下.之后 就可以直接读取这些数据,而不需要重新标记一遍data.save('doraemon-walle.sframe')
只看数据并不一定分配对了.turiCreate提供了explore()函数可以弹出一个页面.供我们查看data.explore()
这样我们就可以查看数据.我不知道我的turiCreate是不是版本问题,还是存在bug.鼠标悬停在某张图片上,并没有显示出大图.(如果有大佬知道因为的话,请告知).我的是在每条线出右键可以点击open frame in new window
数据探索完毕,都正确了,我们继续我们接下来的操作
我们然turiCreate吧data数据框分为训练集合和测试集合.train_data, test_data = data.random_split(0.8, seed=2)
训练集合是用来让机器进行观察学习的。电脑会利用训练集合的数据自己建立模型。但是模型的效果(例如分类的准确程度)如何?我们需要用测试集来进行验证测试。
这就如同老师不应该把考试题目都拿来给学生做作业和练习一样。只有考学生没见过的题,才能区分学生是掌握了正确的解题方法,还是死记硬背了作业答案。
我们让TuriCreate把80%的数据分给了训练集,把剩余20%的数据拿到一边,等待测试。这里我设定了随机种子取值为2,这是为了保证数据拆分的一致性。以便重复验证我们的结果。
好了,下面我们让机器开始观察学习训练集中的每一个数据,并且尝试自己建立模型。
下面代码第一次执行的时候,需要等候一段时间。因为TuriCreate需要从苹果开发者官网上下载一些数据。这些数据大概100M左右。
需要的时长,依你和苹果服务器的连接速度而异。反正在我这儿,下载挺慢的。
好在只有第一次需要下载。之后的重复执行,会跳过下载步骤。model = tc.image_classifier.create(train_data, target='label')
下载完毕后,你会看到TuriCreate的训练信息。
当你看到一下类似信息则 训练成功了
可以看出几轮下来 训练的准确还是验证的准确度,都已经非常高了。
我们用获得图片分类模型,来对测试集做预测predictions = model.predict(test_data)
我们把预测的结果(一系列图片对应的标记序列)存入了predictions变量。
然后,我们让TuriCreate告诉我们,在测试集上,我们的模型表现如何。
先别急着往下看,猜猜结果正确率大概是多少?从0到1之间,猜测一个数字。
猜完后,请继续。metrics = model.evaluate(test_data)print(metrics['accuracy'])
这就是正确率的结果:0.914285714286
为了验证这不是准确率计算部分代码的失误,我们来实际看看预测结果。predictions
这是打印出的预测标记序列:dtype: str
Rows: 35
['doraemon', 'doraemon', 'walle', 'walle', 'doraemon', 'walle', 'doraemon', 'walle', 'walle', 'walle', 'doraemon', 'doraemon', 'yyx', 'doraemon', 'doraemon', 'doraemon', 'doraemon', 'doraemon', 'yizhong', 'walle', 'walle', 'doraemon', 'yizhong', 'yyx', 'walle', 'doraemon', 'yyx', 'doraemon', 'walle', 'doraemon', 'doraemon', 'yyx', 'doraemon', 'doraemon', 'doraemon']
再看看实际的标签。test_data['label']
这是实际标记序列dtype: str
Rows: 35
['doraemon', 'doraemon', 'walle', 'walle', 'doraemon', 'walle', 'doraemon', 'walle', 'walle', 'yizhong', 'doraemon', 'doraemon', 'yyx', 'doraemon', 'doraemon', 'doraemon', 'doraemon', 'doraemon', 'yizhong', 'doraemon', 'walle', 'doraemon', 'yizhong', 'yyx', 'walle', 'doraemon', 'yyx', 'doraemon', 'walle', 'walle', 'doraemon', 'yyx', 'doraemon', 'doraemon', 'doraemon']
我们查找一下,到底哪些图片预测失误了。
你当然可以一个个对比着检查。但是如果你的测试集有成千上万的数据,这样做效率就会很低。
我们分析的方法,是首先找出预测标记序列(predictions)和原始标记序列(test_data['label'])之间有哪些不一致,然后在测试数据集里展示这些不一致的位置。test_data[test_data['label'] != predictions]
我们获得这个数据点对应的原始文件路径。wrong_pred_img_path = test_data[predictions != test_data['label']][0]['path']
wrong_pred_img_path1 = test_data[predictions != test_data['label']][1]['path']
wrong_pred_img_path2 = test_data[predictions != test_data['label']][2]['path']
然后我显示这些图片img = tc.Image(wrong_pred_img_path)
img.show()
我们就会发现确实存在一定层度上的干扰
到这里我们模型训练好了就是导出为CoreML模型.然后加载到Xcode上使用了!model.export_coreml('test1.mlmodel')
这里发现这个模型竟然要94M.而且基本不受资源多少的影响.如果我们可以适当减低准确度的话.可以在
创建模型的时候对他转移学习的模型选定为squeezenet_v1.1,默认是'resnet-50'model = tc.image_classifier.create(train_data,target='label',model='squeezenet_v1.1')
则生成的模型
那么我们只需要导入到Xcode就可以使用了.作者:Y_Swordsman
链接:https://www.jianshu.com/p/49f8dc5f2f47
原创文章转载需获作者授权并注明出处