神经网络可以识别照片中的猫,找到沙发,改善视频录制,从幼犬或简单的草图中绘制图片。 我们已经习惯了。 关于神经网络的新闻几乎每天都会出现,并且已经变得司空见惯。 Grid Dynamics公司设定的任务不是平常的,而是艰巨的-教导神经网络从一张照片中找到庞大的在线商店目录中的特定螺钉或螺栓。 这个任务比找到猫要困难得多。

螺丝在线商店的问题有库存。 成千上万的模型。 每个螺钉都有其自身的描述和特性,因此没有希望使用过滤器。 怎么办 手动搜索还是在货架上的大型超市中搜索? 在这两种情况下,都是浪费时间。 结果,服务对象会感到疲倦并锤打钉子。 为了帮助他,我们将使用神经网络。 如果她能找到封条或沙发,那就让她做些有用的事情-拿起螺丝和螺栓。 我们将在
Grid Dynamics从事数据分析和机器学习的
Maria Matskevichus的报告中告诉您如何教用户如何快速准确地选择神经网络的螺钉。
买家问题
想象一下-我们买了一张桌子,但是丢失了一个小螺丝,如果没有它,就无法组装桌子。 我们去了在线商店进行搜索,我们看到15,000个独特的职位,每个职位都是我们的动力。
我们去过滤器-大约有10个,每个都有5到100个属性。 选择帽子的类型和颜色:平顶帽子-扁平和黄色铜-黄铜。 我们收到了问题。

这是什么 我们不是在寻找这个。 解雇引渡负责人!
过了一会儿,我们仍然选择2个合适的固定螺丝。

剩下的最简单的事情就是解密描述和特征。 每个制造商都以自己的方式描述螺钉。 描述特定模型的参数没有特定要求。
一切都会给客户带来困难。 浪费时间,紧张和技术支持的劳力,这可以帮助客户找到所需的模型。 在意识到买家的这些问题之后,我们的客户-一家大型美国公司-决定为客户提供通过照片进行快速,准确和简单的搜索,而不是进行缓慢且并不总是成功的语义搜索。

实施困难
我们承担了任务,并意识到存在几个问题。
螺丝看起来很像。 看图片。

这些是不同的螺丝。 如果翻转照片,您会发现重要特征不同-头。

在这张照片中?

这里的模型是相同的。 照明有所不同,但是在两张照片中都有一个螺丝模型。
有稀有物种需要分类。 例如,带有“耳朵”或戒指。
使用该应用程序的最低要求。 用户可以上传具有任何背景,外来物体,阴影,光线不足的照片,应用程序必须给出结果。 在白色背景上的螺钉或螺栓很少见。
该应用程序应实时工作。 用户正在这里和现在等待结果。
竞争对手。 最近,我们的客户竞争对手亚马逊推出了其
零件查找器 。 这是一个从照片中搜索螺钉和螺栓的应用程序。

除了Amazona,我们还有两个初创竞争对手,他们为客户提供自己的解决方案。 我们不仅要击败亚马逊,还要击败初创公司,这并不难。 一位竞争者提出了采用20个最流行的螺栓并对它们进行训练的
目标检测的想法。 但是,当神经网络从客户现场提供100、1000或全部15000颗螺钉会发生什么,物体检测将如何工作以及在何处获取大量数据的问题时,竞争对手没有找到答案。
解决方案
它应该是可扩展的,并且不取决于螺钉的种类和目录的大小。 为了解决该问题,我们决定将螺钉视为一组特征或属性。 每个属性是一组属性。

选择了以下特征:
- 帽子-头(32个属性);
- 外部涂层-表面处理(15个属性);
- 点-提示(12个属性);
- 线程覆盖率-线程覆盖率(4个属性)。
我们检查了所有标志的图,并意识到要描述15,000种不同的螺钉,它们只需要50个。它们将组成具有不同属性的不同标志的组合。 需要50颗螺钉和一枚硬币来测量照片中螺钉的比例。
于是他们决定了。 我们决定了这个主意。 需要更多数据。
资料
我们从客户那里收到数据,有些不高兴。 目录数据-对象的照片在一个空白背景的。

但是它们与应用程序要处理的数据不太对应。 用户将要使用任何背景,会用手掌拍照或用手指按住螺栓。 在其上训练网络的数据将与真实图像不一致。
然后我们决定听从
理查德·索克 (
Richard Soker)的建议。
与其花一个月没有老师的学习方法,不如花一个星期,标记数据并训练分类器。
因此,我们做到了-在打印机上打印了许多彩色背景,购买了这50个螺栓,并在背景上拍摄了训练数据。 因此,我们获得了桌子和地毯表面的所有可能选择。

收集数据后,下一步就是了解螺栓在图片中的位置(如果有的话)。
本地化
我们研究了两种本地化方法:
对象检测和
语义分割 。
对象检测返回对象周围最小区域的框。
语义分割返回掩码。 在我们的情况下,面罩更合适。 它保留了其形状,消除了背景,过多的阴影,并且使您可以比对象检测更好地对螺钉进行分类。

语义分割的任务是为每个像素返回其属于一个类的概率。 要训练这样的模型,需要标记的数据。 我们使用了
“ labelme”应用程序,通过该应用程序标记了样本。 我们用一枚硬币和一颗螺丝钉得到了大约一千个口罩。

型号
我们选择了
U-Net 。 Kaggle非常喜欢这个网络,我们现在也是如此。

U-Net是编码器-解码器的成功实现。
- 构造路径或编码器 。 这是U-Net的一部分,U-Net试图表示整个数据集,在更压缩的空间中以矢量表示形式出现。 她学习了这些迹象并发现了最重要的迹象。
- 扩展路径或解码器 。 尝试解码特征图并了解对象在图片中的位置。
我们决定了模型。 现在我们选择损失函数,我们将在学习过程中将其值最小化。
损失函数
细分的经典选项是
Dice系数 :
这是精度和查全率之间的谐波平均值。 谐波均值意味着我们平均地权衡了第一种误差和第二种误差。 我们的数据不平衡,这对我们而言并不十分合适。

总是有很多背景,而对象本身还不够。 因此,该模型将始终提供非常高的精度和非常低的查全率。 为了以不同方式权衡第一类和第二类错误,我们决定采用
Tversky指数 :
$$ display $$ S(P,G,α,β)= \ frac {| P \ cdot G |} {| P \ cdot G | +α| P / G | +β| G / P |} $$显示$$
Tversky索引具有两个系数α和β,分别权衡这两个误差。 如果取α=β= 0.5,则得到相同的骰子系数。 如果选择其他参数,
则会得到
Jaccard索引 -对象相似度的度量之一。 对于α=β= 1-Tversky索引等于Jaccard索引。
您还可以获得Fβ得分。 对于α+β= 1,Tversky指数对应于Fβ得分。
为了选择α和β,我们进行了几次实验。 他们假设该
模型将因第二种错误而受到更大的罚款 。 当模型将背景像素分类为对象像素时,还不错。 如果对象周围有小的背景框,则正常。 但是,当模型将螺钉像素分类为背景像素时,螺钉上会出现孔洞,这会变得不均匀,这会干扰我们的分类。
因此,我们决定增加参数β,使其更接近1,使参数α接近0。

图片显示,当β= 0.7和α= 0.3时,可获得最佳掩模。 我们决定停止此操作,并根据所有数据训练模型。
培训课程
学习策略非常棘手。 由于我们是在个人时间手动标记数据,因此我们决定使用U-Net的一项功能。 它在一个新通道上细分每个新类-添加一个新通道,并在其上定位了一个对象。
因此,在我们的培训中,没有一幅既包含硬币又包含螺栓的图片。 所有图片都包含一个类别:10%-硬币,90%-螺丝。

这样就可以正确分配工作并节省硬币上的时间-这是一个,但是形式很简单。 我们很容易学会对其进行细分,这使我们可以将90%的工作转移到螺钉上。 它们具有不同的形状和颜色,因此了解如何对其进行细分非常重要。
我们的网络已经学会了对那些不在我们样本中的实例进行细分。 例如,不存在异常形状的螺栓,但是模型也很好地对其进行了细分。 她学会了概括螺钉和螺栓的符号,并将其用于新数据,这非常好。

分类
这是对象定位之后的下一阶段。 很少有人训练卷积神经网络来对对象进行分类;他们经常使用
转移学习 。 让我们看一下卷积神经网络的体系结构,然后简要回顾一下转移学习是什么。

在早期阶段,网络学习识别边界和角度。 后来,它可以识别简单的形状:矩形,圆形,正方形。 越接近顶部,就越能识别其所训练的数据的特征。 在最顶部,模型可以识别类。
世界上大多数物体都由简单的形式组成并且具有共同的特征。 您可以加入经过大量数据培训的网络,并将这些属性用于我们的分类。 该网络将在较小的数据集上进行培训,而不会花费大量资源。 这就是我们所做的。

一旦决定了转学的一般技术,就需要选择一个预先训练的模型。
选型
我们的应用程序实时工作。 该模型应该是轻便且可移动的-参数很少,但准确。 考虑到这两个因素,我们牺牲了一些准确性以支持亮度。 因此,我们选择的不是最准确的,而是轻巧的模型
-Xception 。

在Xception中,代替了通常的卷积-
卷积 -
可分离卷积 。 因此,Xception比其他网络(例如,使用VGG)轻。

普通卷积同时进行通道间和维间卷积。 可分离卷积共享:首先是维间卷积
-Depthwise ,然后是
通道间 。 结果结合起来。
Xception执行可分离的卷积,虽然它产生的效果与普通的卷积相同,但参数较少。

我们将公式中的值替换为用于计算参数的值,例如,用于16个过滤器。 对于普通卷积,您需要计算的参数是“可分离卷积”的7倍。 因此,Xception更准确,更少。

培训课程
首先,我们决定建立一些基准并在原始图片中训练模型。 我们有4个分类器,每个分类器负责一个特定的属性。 结果不令人满意。

然后他们在盒子上训练了模型,然后返回了物体检测结果。 线程覆盖率的准确性得到了很好的提高。 但是对于其他分类器,结果也不尽人意。

然后他们决定只给分类器他们想要并且将要分类的那部分螺丝。 头只给帽子,提示-只带头。 为此,我们制作了蒙版,获得了一个轮廓,在该轮廓上圈出了最小面积的矩形,并计算了旋转角度。

目前,我们仍然不知道螺钉头和尖端在哪一侧。 为了找到答案,他们将盒子切成两半,看着正方形。

包含头部的区域始终大于包含尖端的区域。 比较面积,我们确定螺丝的哪一部分,哪一部分。 它有效,但并非在所有情况下都适用。

当螺钉的长度与盖的直径相当时,将获得一个正方形,而不是一个矩形。 转动它时,我们得到一张图片,如第3幅所示。该模型无法很好地对该选项进行分类。
然后,我们将所有长螺钉取下,计算它们的旋转角度,并建立
旋转网浅层神经网络,该网络将螺钉取下并预测旋转角度。

然后将此辅助模型用于较小的短螺钉和螺栓。 我们取得了很好的结果-一切正常,小螺丝也旋转。 在这一阶段,误差实际上减小到零。 我们获取了这些数据,对分类器进行了训练,发现对于每个分类器(除Finish之外),准确性都得到了显着提高。 太好了-我们将继续努力。

但是由于某种原因,Finish没有起飞。 我们研究了错误并看到了图片。

在不同的照明条件和不同的相机设置下,同一对螺丝的颜色也不同。 这不仅会混淆模型,还会混淆人。 灰色可以变成粉红色,黄色可以变成橙色。 回想一下蓝金装-同样的故事。 螺钉的反射面会产生误导。
我们在互联网上研究了类似的案例,发现中国科学家试图通过颜色对汽车进行分类,并且
面临着同样的汽车问题。

作为解决方案,中国科学家创建了一个浅层网络。 它的功能是在两个分支中,它们最后串联在一起。 这种架构称为
ColorNet 。

我们为任务实施了解决方案,并且准确性提高了近2倍。 有了这样的结果和模型,您可以工作并从在线商店目录中的表中查找螺丝。

我们只有4个针对4个属性的分类器,还有许多其他分类器。 因此,您需要创建某种过滤器,该过滤器将接收目录数据并以某种方式对其进行过滤。
筛选
每个分类器返回一个软标签和一个类。 我们获取了软标签和数据库的值,计算出一些
分数 -将每个功能的所有标签相乘。

分数显示所有分类器对该功能组合最有可能出现的信心。 分数越高,目录中的螺丝和图片中的螺丝越可能相似。
流水线
原来是这样的应用程序。

- 输入 :从原始图片开始。
- 本地化 :确定螺栓或螺钉的位置以及硬币的位置。
- 转换和旋转 。
- 分类 :我们会仔细修剪所有东西,分类并确定尺寸。
- 过滤 。
- 退出到特定的SKU位置。
如何实施一个复杂的项目
局部吃掉大象 。 将大问题分成几部分。
标记将反映现实的数据。 不要担心数据标记-这是最安全的方法,它将迅速确保最高的模型质量。 数据合成方法通常比使用真实数据产生更差的结果。
测试一下 。 在建立许多模型之前,我们先取一小部分数据,用手标记一下,然后测试每个假设的操作。 之后,他们才训练了U-Net,分类器和旋转。
不要重新发明轮子 。 通常,您面临的问题已经有了解决方案。 在Internet上浏览,阅读文章-一定要找到一些东西!
关于我们的Visual Search应用程序的故事不仅涉及螺钉的分类。 它是关于如何创建一个没有类似物的复杂项目的,但是即使有类似物,它们也不能满足我们为应用程序设置的要求。
有关Grid Dynamics项目以及数据科学团队面临的其他挑战的更多信息,请参见该公司的
技术博客 。
带有这种偏差的报告-在真正的非标准项目中使用机器学习算法-我们只是在寻找UseData Conf 。 这是有关我们最感兴趣的领域的更多信息。
如果您知道如何恶作剧以使模型飞行,请发送应用程序 。 如果您知道融合并不能保证速度,并准备告诉您什么是更重要的注意事项,我们将在9月16日等待您。