看到的时候自然知道,只需要几行Python代码,就可以建立自己的机器视觉模型,快速准确地识别海量图像。快来试试吧!0.视觉进化的作用使得人类处理图像的效率非常高。在这里,我给你看一张图。如果我问你:你能分辨出图中哪只猫哪只狗吗?你可能会立即觉得自己受到了极大的侮辱。并大声质问我:你觉得我智商有问题吗?!冷静下来。另一种提问方式:您能否将您区分猫狗图片的方法描述为严格的规则,并将其教给计算机,以便它可以为我们人类区分数千张图片?对于大多数人来说,此时感受到的不是屈辱,而是压力。如果你是一个有毅力的人,你可以尝试各种标准:图片某个位置的像素颜色,某个部分的边缘形状,某个水平位置的连续颜色长度......你告诉计算机这些描述,而且真的可以判断左边的猫和右边的狗。问题是,计算机真的能区分猫和狗的照片吗?我又拿出一张照片给你。你会发现几乎所有的规则定义都需要重写。当机器终于能够用近乎投机取巧的方法正确区分出两张图片中的动物时,我拿出一张新的图片……几个小时后,你决定放弃。不要气馁。您遇到的不是新问题。就连首席大法官也有同样的烦恼。1964年,在“Jacobellisv.Ohio”一案中,美国最高法院大法官波特·斯图尔特曾针对某部电影中出现的一个特定图像分类问题说过一句名言,“我不打算讨论它的概念。Giveshortandcleardefinitions...butIknowitwhenIsee”(我一看到就知道)。原文如下:我今天不会尝试进一步定义我所理解的包含在速记描述中的材料种类(“硬核色情”),也许我永远无法成功地做到这一点。但是一看就知道,这个案子涉及的电影不是那个。考虑到精神文明建设需要,该段暂不翻译。人类无法详细、具体、准确地向计算机描述图像判别规则。这是否意味着计算机无法识别图像?当然不是。2017年12月的《科学美国人》杂志将“视觉人工智能”(像人类一样看东西的AI)定义为2017年的新兴技术之一。你已经听说过自动驾驶汽车的神奇之处吧?没有机器识别图像能做到吗?你的朋友可能(不止一次)向你展示了如何使用面部识别解锁你的新iPhoneX,对吧?没有机器识别图像能做到吗?在医学领域,计算机分析科学图像(如X光片)的能力已经超越了拥有多年经验的医生。没有机器识别图像能做到吗?你可能会突然感到有点困惑——这是奇迹吗?不。计算机所做的就是学习。通过从足够数量的样本中学习,机器可以从数据中构建自己的模型。其中,可能涉及到大量的判断标准。然而,人类不需要告诉机器任何这些。完全是自己领悟和掌握的。你可能会感到非常兴奋。那么,让我告诉你一个更振奋人心的消息——你可以轻松地自己搭建一个图片分类系统!不相信?请按照我下面的介绍尝试一下。1.我们不从数据中识别猫和狗。这个问题不够新鲜。让我们识别哆啦A梦,好吗?是的,我说的是哆啦A梦。跟谁区别呢?起初我想找一只霸王龙,但后来我认为这是作弊,因为它们看起来太不一样了。既然哆啦A梦是机器人,那我们再找一个机器人来区分一下。一提到机器人,我马上就会想到它。是的,机器人瓦力(WALLE)。我为你准备了119张哆啦A梦的照片和80张WALL-E的照片。图片已上传至本Github项目(https://link.jianshu.com/?t=https%3A%2F%2Fgithub.com%2Fwshuyi%2Fdemo-python-image-classification)。请点击此链接(https://link.jianshu.com/?t=https%3A%2F%2Fgithub.com%2Fwshuyi%2Fdemo-python-image-classification%2Farchive%2Fmaster.zip)下载压缩包。然后在本地解压。作为我们的演示目录。解压后会在该目录下看到一个image文件夹,里面包含两个子目录,分别是doraemon和walle。打开哆啦A梦的目录,看看里面都有什么图片。如您所见,哆啦A梦的画面真是五花八门。各种场景、背景颜色、表情、动作、角度……不胜枚举。这些图片大小不同,纵横比也不同。我们再看看瓦力,也是类似的情况。数据已经有了,我们来准备环境配置。2.环境我们使用Python集成运行环境Anaconda。请到本网站(https://link.jianshu.com/?t=https%3A%2F%2Fwww.continuum.io%2Fdownloads)下载最新版本的Anaconda。向下滚动页面以找到下载位置。根据您当前使用的系统,网站会自动推荐合适的版本供您下载。我使用的是macOS,下载文件格式是pkg。下载页面区域左侧为Python3.6版本,右侧为2.7版本。请选择版本2.7。双击下载的pkg文件,根据中文提示一步步安装。安装Anaconda之后,我们需要安装TuriCreate。请到您的“终端”(Linux、macOS)或“命令提示符”(Windows),进入我们刚刚下载并解压的示例目录。执行以下命令,让我们创建一个名为turi的Anaconda虚拟环境。然后,我们激活turi虚拟环境。在此环境中,我们安装最新版本的TuriCreate。安装完成后,执行:这会进入Jupyternotebook环境。我们创建一个新的Python2笔记本。这将调出一个空白笔记本。单击左上角的笔记本名称并将其更改为有意义的笔记本名称“demo-python-image-classification”。准备工作完成后,我们就可以开始编写程序了。3.代码首先,我们读入了TuriCreate包。它是苹果公司收购的机器学习框架,为开发者提供了非常简单的数据分析和人工智能接口。importturicreateastc我们指定图片所在的文件夹image。img_folder='image'前面说了,在image下面,有两个文件夹,哆啦A梦和瓦力。注意,如果以后需要识别其他图片(比如猫狗),请将图片中不同类别的图片分别存放在不同的文件夹中。这些文件夹的名称是图片的类别名称(猫和狗)。然后,我们告诉TuriCreate读取所有图像文件并将它们存储在数据框中。data=tc.image_analysis.load_images(img_folder,with_path=True)这里可能会有错误提示。Unsupportedimageformat.SupportedformatsareJPEGandPNGfile:/Users/wsy/Dropbox/var/wsywork/learn/demo-workshops/demo-python-image-classification/image/walle/.DS_Store这个例子提示有几个.DS_Store文件是TuriCreate无法识别的,不能作为图像读取。这些.DS_Store文件是由Apple的macOS系统创建的隐藏文件,用于保存目录的自定义属性,例如图标位置或背景颜色。我们可以忽略这些信息。接下来我们看一下data数据框里面都有什么。从data可以看出,data包含两列信息,第一列是图片的地址,第二列是对图片长宽的描述。因为我们使用了119张哆啦A梦图片和80张瓦力图片,所以数据总量为199。数据读取完整性验证通过。接下来我们需要让TuriCreate知道不同图片的标签信息。也就是说,图片是哆啦A梦还是瓦力?这就是为什么在开始时,您必须将不同类别的图片保存到不同的文件夹中。此时,我们使用文件夹名称来标记图片。data['label']=data['path'].apply(lambdapath:'doraemon'if'doraemon'inpathelse'walle')这条语句将doraemon目录下的图片标记为data数据框中的doraemon。否则视为walle。我们来看看标注后的数据框。从数据可以看出,数据条目数(行数)是一样的,但是多了一个标签列(label)来表示图片的类别。让我们存储数据。data.save('doraemon-walle.sframe')是一个存储动作,可以让我们保存当前的数据处理结果。后续分析只需要读入这个sframe文件,不需要从头处理文件夹。从这个例子中,您可能看不到任何优势。但是试想一下,如果你的图片有好几个G,甚至好几个T,你每次做分析处理的时候,都得从头读取文件,从头做标记,会非常耗时。让我们更深入地研究一下数据框。TuriCreate提供了一个非常方便的explore()函数来帮助我们直观地探索数据框信息。data.explore()这时候TuriCreate会弹出一个页面给我们展示dataframe的内容。本来打印data数据框,我们只能看到图片的大小,现在可以浏览图片的内容了。如果你觉得图片太小,没关系。将鼠标悬停在缩略图上可以查看更大的图像。探索数据框。让我们回到笔记本继续写代码。在这里,我们告诉TuriCreate将数据框拆分为训练集和测试集。train_data,test_data=data.random_split(0.8,seed=2)训练集用于机器观察和学习。计算机使用训练集中的数据自行构建模型。但是模型的有效性如何(例如,分类的准确性如何)?我们需要使用测试集进行验证测试。这就好比老师不应该用试题来给学生做作业和练习一样。只有通过测试学生从未见过的题目,才能区分学生是掌握了正确的解题方法,还是死记硬背了作业答案。我们让TuriCreate将80%的数据分配给训练集,把剩下的20%的数据拿来做测试。这里我将随机种子值设置为2,这是为了保证数据拆分的一致性。为了复制我们的结果。好吧,让我们让机器开始观察和学习训练集中的每一个数据,并尝试自己建立一个模型。以下代码第一次执行时,需要等待一段时间。因为TuriCreate需要从苹果官方开发者网站下载一些数据。这些数据大概有100M左右。所需时间取决于您与Apple服务器的连接速度。反正在我这里,下载很慢。幸运的是,只需要第一次下载。随后的重复执行将跳过下载步骤。model=tc.image_classifier.create(train_data,target='label')下载后会看到TuriCreate的训练信息。调整图像大小...对调整大小的图像执行特征提取...已完成168/168进度:从5%的训练数据创建验证集。可能还要等一下。您可以设置``validation_set=None``来禁用验证跟踪。您会发现TuriCreateh会帮助您调整图像大小并自动捕获图像的特征。然后它会从训练集中抽取5%的数据作为验证集,迭代寻找最佳参数配置,达到最佳模型。这里可能会有一些警告信息,忽略即可。当你看到如下信息时,说明训练工作已经成功完成。可以看到经过几轮之后,不管是训练的准确率还是验证的准确率都已经很高了。接下来,我们使用得到的图像分类模型对测试集进行预测。predictions=model.predict(test_data)我们将预测结果(一系列图片对应的标记序列)存入predictions变量。然后我们让TuriCreate告诉我们我们的模型在测试集上的表现如何。不要急着往下看,猜猜结果的正确率是多少?从0到1,猜一个数字。猜完后,继续。metrics=model.evaluate(test_data)print(metrics['accuracy'])这是正确率的结果:0.967741935484第一次看到的时候惊呆了。我们只用了100多条数据进行训练,就能够在测试集(机器从未见过的图片数据)上获得如此高的识别准确率。为了验证这不是代码精度计算部分的错误,我们实际来看一下预测结果。predictions这是打印出来的预测标签序列:dtype:strRows:31['doraemon','doraemon','doraemon','doraemon','walle','doraemon','walle','doraemon','walle','walle','doraemon','doraemon','doraemon','doraemon','doraemon','walle','doraemon','doraemon','walle','walle','doraemon','doraemon','walle','walle','walle','doraemon','doraemon','walle','walle','doraemon','walle']然后查看实际标签。test_data['label']这是实际的标签序列:dtype:strRows:31['doraemon','doraemon','doraemon','doraemon','walle','doraemon','walle','walle','walle','walle','doraemon','doraemon','doraemon','doraemon','doraemon','walle','doraemon','doraemon','walle','walle','doraemon','doraemon','walle','walle','walle','doraemon','doraemon','walle','walle','doraemon','walle']让我们看看预测了哪些图片错误。当然你可以一一检查。但是如果你的测试集有几万条数据,这样效率会很低。我们分析的方法是先找出预测的标签序列(predictions)和原始标签序列(test_data['label'])之间的不一致性,然后在测试数据集中显示这些不一致性。test_data[test_data['label']!=predictions]我们发现在31个测试数据中,只有1个标签预测错误。原始代币是Wall-E,我们的模型预测机器猫。我们得到这个数据点对应的原始文件路径。wrong_pred_img_path=test_data[predictions!=test_data['label']][0]['path']然后,我们将图像读入img变量。img=tc.Image(wrong_pred_img_path)使用TuriCreate提供的show()函数,我们来查看这张图片的内容。img.show()因为深度学习的一个问题就是模型过于复杂,我们无法准确判断机器是如何错误识别这张图片的。但我们不难从这张图中发现一些特征——除了瓦力,还有另外一个机器人。如果你看过电影,你应该知道这两个机器人之间的关系。这里我们按无表。问题是右上角的圆头机器人看起来与棱角分明的瓦力有很大不同。不过,别忘了哆啦A梦也是圆头的。4.原理执行完上一节的代码,你应该明白了如何搭建自己的图像分类系统。在不了解原理的情况下,您已经出色地开发了这个模型。不是吗?如果对原理不感兴趣,请跳过这部分,看“小结”。喜欢深究知识,就说说原理吧。虽然你只写了几行代码,但是你搭建的模型已经够复杂够高大上了。它就是传说中的卷积神经网络(CNN)。它是一种深度机器学习模型。最简单的卷积神经网络是这样的:最左边是输入层。也就是我们输入的图片。在这种情况下,哆啦A梦和瓦力。在计算机中,图片是按照不同的颜色(RGB,即红、绿、蓝)分层存储的。就像下面的例子。根据分辨率的不同,计算机会将每一层的图像存储成一定大小的矩阵。对应某行某列位置,存储的只是一个数字。这就是为什么当你运行代码时,你会发现TuriCreate做的第一件事就是调整图像的大小。因为如果输入图像有不同的大小,则无法执行以下步骤。有了输入数据,依次进入下一层,即卷积层(ConvolutionalLayer)。卷积层听起来神秘而复杂。但原理很简单。它由多个过滤器组成。每个过滤器都是一个小矩阵。使用的时候,在输入数据上,移动这个小矩阵,在矩阵原来重叠的位置乘以数字,然后相加。这样,原来的矩阵经过“卷积”就变成了一个数。下面的动画非常形象地为你讲解了这个过程。这个过程就是不断地从一个矩阵中寻找某些特征。这样的特征可能类似于边缘的形状。下一层称为“池化层”。这翻译简直无语。我觉得翻译成“汇总层”或者“采样层”会好很多。在下文中,我们将其称为“采样层”。采样的目的是避免让机器认为“它必须在网格的左上角有一个锐边”。事实上,在一张图片中,我们要识别的物体可能会发生位移。因此,我们需要采用汇总抽样的方法,将某个特征的位置模糊化,从“特定点”扩展到“某个区域”。如果这让你觉得不够直观,请参考下面的动图。这里用到的是“最大值采样”(Max-Pooling)。以原来的2x2范围为一个块,从中求出最大值,记录在新的结果矩阵中。一个有用的规则是,随着层数不断向右推进,一般的结果图像(其实形式上应该叫矩阵)会越来越小,但层数会越来越多更多的。只有这样,我们才能提取图片中的规律信息,尽可能多地掌握规律。如果您仍然不满意,请访问此网站(https://link.jianshu.com/?t=http%3A%2F%2Fscs.ryerson.ca%2F%7Eaharley%2Fvis%2Fconv%2Fflat.html)。它生动地为你分析了卷积神经网络中每一层都发生了什么。左上角是用户输入的地方。请用鼠标手写数字(0-9)。字迹丑陋没关系。我输入了一个7。观察输出结果,模型正确判断出最佳选择是7,第二种可能是3。正确答案。让我们看看模型构建的细节。让我们将鼠标移动到第一个卷积层。停在任何像素。计算机通过特征检测告诉我们这个点是从上一层图形中得到的哪些像素点。同样的,将鼠标悬停在第一个最大池化层上,计算机也可以直观地告诉我们像素是从哪个像素块中采样的。这个网站值得您光顾。可以帮助你理解卷积神经网络的内涵。回头看我们的例子图:下一层叫做全连接层(FullyConnectedLayer),它实际上是将上一层输出的矩阵全部压缩成一个维度,变成了一个长输出结果。之后就是输出层,对应的结果就是我们需要机器掌握的分类。如果你只看前两层,你会很容易把它和你之前学过的深度神经网络(DNN)联系起来。既然我们已经有了深度神经网络,为什么还要费心去使用卷积层和采样层来让模型变得如此复杂呢?这里有两方面的考虑:第一是计算量。图像数据的输入一般都比较大。如果我们直接用几个深度神经层将它连到输出层,每一层的输入和输出都将是巨大的,总的计算量是难以想象的。二是模式特征的捕捉。即使计算量非常大,深度神经网络也可能无法像人们希望的那样识别图像模式。因为它学到了太多的噪音。卷积层和采样层的引入可以有效滤除噪声,突出图片中的图案对训练结果的影响。你可能会想,我们只写了几行代码,用到的卷积神经网络一定和上图差不多,只有4、5层吧?不是这样的,你用的层数足足有50层!它的学名,叫做Resnet-50,是微软研发的成果。2015年,它赢得了ILSRVC比赛。在ImageNet数据集上,其分类识别效果已经超越了人类。我在这里附上相应论文的地址(https://link.jianshu.com/?t=https%3A%2F%2Farxiv.org%2Fabs%2F1512.03385),有兴趣的可以参考.请看上图最下面的那个,大致就是这个样子。足够的深度,足够的复杂性。如果你之前对深度神经网络有所了解,你会觉得更加不可思议。这么多层,这么少的训练数据,怎么能得到这么好的测试结果呢?而如果想要得到好的训练效果,大量图片的训练过程岂不是要花很长时间?没错,如果你从头开始构建一个Resnet-50并在ImageNet数据集上训练它,即使你有一个好的硬件设备(GPU)也需要很长时间。如果您是在自己的笔记本电脑上训练……算了。那么,TuriCreate真的是奇迹吗?不需要长时间训练,只需要小样本,就能得到高水平的分类结果?不,数据科学中没有奇迹。造成这种看似神奇的效果的原因是什么?本题留作思考题,请善用搜索引擎和问答网站,帮助您找到答案。5.总结通过本文,您掌握了以下内容:如何在Anaconda虚拟环境中安装Apple的机器学习框架TuriCreate。如何在TuriCreate中读入文件夹中的图片数据。并使用文件夹的名称来标记图片。如何在TuriCreate中训练深度神经网络来区分图像。如何使用测试数据集来测试图像分类的效果。并找到错误分类的图片。卷积神经网络(CNN)的基本组成和工作原理。但限于篇幅,我们没有提及或深入解释以下问题:如何批量获取训练和测试图像数据。如何使用预处理功能转换TuriCreate无法识别的图片格式。如何从头开始构建卷积神经网络(CNN),并完全控制模型的层和参数。如何在不花很长时间训练,只需要小样本的情况下获得高层次的分类效果(提示关键词:迁移学习,迁移学习)。请在实践中思考以上问题。欢迎留言和发邮件与我分享你的想法。原文链接:https://www.jianshu.com/u/7618ab4a30e4
