简介人们一直在尝试手动编写算法代码来理解人类生成的内容,但收效甚微。例如,计算机很难“掌握”图像的语义内容。对于这类问题,AI科学家曾尝试通过分析汽车、猫、大衣等低级像素来解决,但结果并不尽如人意。尽管颜色直方图和特征检测器在一定程度上起作用,但在大多数实际应用中它们的准确性仍然极低。在过去十年中,大数据和深度学习的结合从根本上改变了我们处理计算机视觉、自然语言处理和其他机器学习(ML)应用程序的方式。例如,从垃圾邮件检测到真实文本再到视频合成等任务都取得了惊人的进展,并且这些特定应用程序中的准确度指标已达到超人水平。然而,这些改进的一个显着副作用是嵌入向量的使用增加,嵌入向量是通过在深度神经网络中获取中间结果而产生的模型组件。OpenAI相关的网页提供了以下相当恰当的概述:“嵌入是一种特殊的数据表示格式,对于机器学习模型和相关算法都易于使用。嵌入是文本语义的信息密集型表示。每个嵌入都可以被表示为浮点数的向量;因此,向量空间中两个嵌入之间的距离与原始格式中两个输入之间的语义相似性有关。例如,如果两个文本相似,则它们的向量的表示也应该是相似的。”下表显示了嵌入空间中的三个查询图像及其对应的前五个图像。在这里,我使用了UnsplashLite网站提供的前1000张图像作为数据集。为嵌入任务训练新模型从理论上讲,训练新的ML模型并生成嵌入听起来很简单:采用最新架构支持的预构建模型,并使用一些数据对其进行训练。从表面上看,使用最新的模型架构似乎可以轻松实现最先进的结果。然而,这与事实相去甚远。接下来,让我们回顾一些与训练嵌入模型相关的常见陷阱(这些也适用于一般的机器学习模型):1.数据不足:在没有足够数据的情况下从头开始训练新的嵌入模型,这往往会导致一种称为过度拟合的现象。事实上,只有最大的全球组织才有足够的数据从头开始训练新模型;其他公司或个人必须依靠迭代微调。这种微调其实对应一个过程;在这个过程中,一般是基于一个包含大量数据的训练好的模型,并在此基础上,使用较小的数据集进行连续的抽取操作。2、超参数选择不当:超参数是用来控制训练过程的常量,比如模型学习的速度或者单批次训练使用的数据量。微调模型时,选择一组合适的超参数很重要,因为对特定值的微小更改可能会导致截然不同的结果。最近的研究表明,ImageNet-1k的准确率提高了5%以上(这是很多),这一成就是通过改进训练程序并从头开始训练相同的模型来实现的。3.高估自监督模型:术语自监督是指通过利用数据本身而不是标签来学习输入数据的“基础”的训练过程。一般来说,自监督方法非常适合预训练(使用大量未标记数据以自监督方式训练模型,然后使用较小的标记数据集微调模型),但直接使用自监督嵌入可能导致性能不佳。4.解决上述三个问题的常用方法是先用大量数据训练自监督模型,然后再在标记数据上微调模型。这已被证明对NLP非常有效,但对CV(计算机视觉)不是很有效。这里显示的是Meta的data2vec训练技术的一个例子。这是一种自我监督的方法,用于训练跨各种非结构化数据类型的深度神经网络。(来源:MetaAI博客)使用嵌入模型的陷阱在训练嵌入模型的过程中存在一些常见错误。对于许多希望使用嵌入立即在学术数据集(例如ImageNet(用于图像分类)和SQuAD(用于问答))上使用预训练模型的开发人员来说,这是很常见的。然而,尽管目前有大量的预训练模型可用,但要获得最大的嵌入性能,应避免以下陷阱:1.训练和推理数据不匹配:使用其他组织训练的现成模型已成为开发的重要组成部分机器学习应用程序。一种无需花费数千GPU/TPU小时进行重新训练即可完成此操作的流行方法。了解特定嵌入模型的局限性以及它如何影响应用程序性能非常重要;在不了解模型的训练数据和方法的情况下,很容易误解结果。例如,经过训练以嵌入音乐的模型在应用于真实语音应用时往往表现不佳;反之亦然。2.层选择不当:当使用全监督神经网络作为嵌入模型时,特征通常取自激活的倒数第二层(一般称为倒数第二层)。但是,这可能会导致性能不佳;当然,具体情况还是要看实际应用。例如,使用早期激活可以提高使用图像分类训练模型嵌入徽标和/或品牌图像时的性能。这是因为该方案更好地保留了一些对图像分类至关重要但不是很复杂的低级特征(边缘和角)。3.不同的推理条件:为了从嵌入模型中提取最大性能,训练和推理条件必须相同。实际上,情况往往并非如此。例如,使用TorchVision的标准resnet50模型,当使用双三次和最近邻插值进行下采样时,会产生两个完全不同的结果(见下文)。BicubicInterPolationNearestInterPolation预测类coucalrobin,美国罗宾,TurdusMigratorius概率27.28%47.65%嵌入向量[0.1392,0.3572,0.1988,...]部署嵌入模型一旦您成功通过了前面的培训并克服了与验证模型相关的所有障碍,那么下一个关键步骤就是扩展和部署程序。但嵌入式模型部署说起来容易做起来难。MLOps是与DevOps相关的一个领域,专门为此而设计。1.选择合适的硬件:与大多数其他ML模型一样,嵌入模型可以在各种类型的硬件上运行,从标准的日常CPU到可编程逻辑(FPGA)。该网站上发布的几乎所有研究论文都侧重于分析成本效益权衡,并强调大多数组织在解决该问题时面临的困难。2.在模型部署方面,已经有很多现成的MLOP和分布式计算平台(包括很多开源平台)可用。然而,弄清楚这些东西是如何工作的,并弄清楚它们如何适合您的应用程序本身就是一个挑战。3.嵌入向量的存储方案:随着应用程序的扩展,您需要找到一种可扩展且更持久的嵌入向量存储解决方案。这就是矢量数据库的用武之地。一切都由我自己完成!如果是这种情况,请记住一些关键事项:首先,ML与软件工程有很大不同:传统的机器学习起源于统计学,这是一个与软件工程截然不同的数学分支。正则化和特征选择等重要的机器学习概念在数学方面有着坚实的基础。虽然用于训练和推理的现代库使得训练和生成嵌入模型变得非常容易,但了解不同的超参数和训练方法如何影响嵌入模型的性能仍然至关重要。其次,学习使用PyTorch或Tensorflow等框架并非易事。事实上,这些库极大地加快了现代ML模型的训练、验证和部署;另一方面,构建新模型或实现现有模型对于经验丰富的ML开发人员或熟悉HDL的程序员来说是直观的。但尽管如此,这个领域涉及的基本概念对于大多数软件开发人员来说可能很难自己掌握。当然,还有一个问题是选择哪个框架,因为这两个框架使用的执行引擎有很多不同(我推荐大家使用PyTorch)。最后,找到适合您的代码库的MLOps平台需要时间。总而言之,有数百种不同的选项供您选择。当然,仅仅评估每个选项的优缺点本身就可能是一项长达数年的研究项目。话虽如此,我不建议学习ML和MLOps;因为这是一个相对漫长而乏味的过程,可能会占用手头最重要的事情的时间。使用Towhee加速数据科学应用程序开发Towhee是一个开源项目,旨在帮助软件工程师开发和部署只需几行代码即可利用嵌入式模型的应用程序。Towhee项目为软件开发人员提供了构建ML应用程序的自由和灵活性,而无需深入嵌入模型和机器学习。一个简单的例子管道(Pipeline)是由多个子任务(在Towhee中也称为算子)组成的单个嵌入生成任务。通过抽象管道中的整个任务,Towhee帮助用户在生成嵌入时避免上面提到的许多陷阱。>>>fromtowheeimportpipeline>>>embedding_pipeline=pipeline('image-embedding-resnet50')>>>embedding=embedding_pipeline('https://docs.towhee.io/img/logo.png')以上在例如,图像解码、图像变换、特征提取和嵌入归一化是编译到单个管道中的四个子步骤——开发人员无需担心模型和推理细节。此外,Towhee为各种任务提供了预置的嵌入管道,包括音频/音乐嵌入、图像嵌入、人脸嵌入等。方法链API调用Towhee还提供了一个名为DataCollection的Python非结构化数据处理框架。简而言之,DataCollection是一种方法链式API,允许开发人员在真实数据上快速构建嵌入和其他ML模型的原型。在下面的示例中,我们使用resnet50嵌入模型来计算使用DataCollection的嵌入。在这个例子中,我们将构建一个简单的应用程序。在这个程序中,我们可以使用一位数3来过滤素数:>>>fromtowhee.functionalimportDataCollection>>>defis_prime(x):...ifx<=1:...returnFalse...foriinrange(2,int(x/2)+1):...ifnotx%i:...returnFalse...returnTrue...>>>dc=(...DataCollection.range(100)....filter(is_prime)#第一阶段:寻找素数....filter(lambdax:x%10==3)#第二阶段:寻找以3结尾的素数....map(str)#第二阶段:转换为字符串...)...>>>dc.to_list()使用DataCollection,您可以只使用一行代码开发整个应用程序。例如,下面将向您展示如何开发一个反向图像搜索应用程序。Towhee训练如上所述,完全或自监督训练的模型通常擅长一般任务。然而,有时您会想要创建一个擅长特定事物的嵌入模型,例如区分猫和狗。为此,Towhee提供了一个训练/微调框架:>>>fromtowhee.trainer.training_configimportTrainingConfig>>>training_config=TrainingConfig(...batch_size=2,...epoch_num=2,...output_dir='quick_start_output'...)您还需要指定要训练的数据集:>>>train_data=dataset('train',size=20,transform=my_data_transformer)>>>eval_data=dataset('eval',size=10,transform=my_data_transformer)一旦一切就绪,从现有的操作符训练一个新的嵌入模型是小菜一碟:>>>op.train(...training_config,...train_dataset=train_data,...eval_dataset=eval_data...)完成上述代码后,您可以在应用程序中使用相同的运算符而无需更改其余代码。上面显示的是嵌入模型试图编码的图像核心区域的注意力热图。在未来的Towhee版本中,我们将直接将注意力热图和其他可视化工具集成到我们的微调框架中。示例应用程序:反向图像搜索为了演示如何使用Towhee,让我们快速构建一个小型反向图像搜索应用程序。反向图像搜索是众所周知的。因此,我们不深入细节,直接进入主题:>>>importtowhee>>>fromtowhee.functionalimportDataCollection我们将使用一个小数据集和10个查询图像。在程序中,我们使用DataCollection加载数据集和查询图片:>>>dataset=DataCollection.from_glob('./image_dataset/dataset/*.JPEG').unstream()>>>query=DataCollection.from_glob('./image_dataset/query/*.JPEG').unstream()下一步是计算整个数据集集合的嵌入:>>>dc_data=(...dataset.image_decode.cv2()....image_embedding.timm(model_name='resnet50')...)...此步骤创建一组局部嵌入向量-一个用于数据集中的每个图像。这个阶段我们可以查询最近邻数据:>>>result=(...query.image_decode.cv2()#Decodeallimagesinthequeryset....image_embedding.timm(model_name='resnet50')#使用'resnet50'嵌入模型计算嵌入....towhee.search_vectors(data=dc_data,cal='L2',topk=5)#Searchdataset....map(lambdax:x.ids)#获取类似结果的ID(文件路径)....select_from(dataset)#获取结果图像...)...另外,我们提供了一种使用Ray框架部署应用程序的方法。为此,你只需要调用命令query.set_engine('ray'),其他的就很简单了!总之,我们不认为Towhee项目是一个成熟的端到端模型服务或MLOps平台,这不是我们想要实现的目标。相反,我们的目标是加速需要嵌入和其他ML任务的应用程序的开发。然而,通过Towhee开源项目,我们希望能够在本地机器上实现嵌入式模型和流水线的快速原型制作(Pipeline+Trainer),尤其是开发以ML为中心的应用程序(数据收集)只需几行代码,并允许轻松快速地部署到集群(通过Ray框架)。译者介绍朱宪忠,51CTO社区编辑,51CTO专家博主,讲师,潍坊某高校计算机教师,自由编程资深人士。早期专注于各种微软技术(编译成三本与ASP.NETAJX和Cocos2d-X相关的技术书籍)。/ESP32/RaspberryPi等物联网开发技术和Scala+Hadoop+Spark+Flink等大数据开发技术。原标题:MakingMachineLearningMoreAccessibleforApplicationDevelopers,作者:FrankLiu链接:https://dzone.com/articles/making-machine-learning-more-accessible-for-applic-1
