检测器|案例解析:用Tensorflow和Pytorch计算骰子值( 二 )


因此 , 为了将骰子顶部图像放入我想要的文件夹结构中 , 我有几个选项 。

  1. 手工裁剪每个类的几百张图像:这个过程显然是缓慢的 。 对我来说也有太多的手工工作需要去做 。
  2. 使用新的骰子顶部模型裁剪出所有骰子顶部 , 然后将它们分类到文件夹中 。 这也需要大量的工作来排序 。 在这一点上 , 我猜你们都知道我下一步要做什么 。
  3. 使用我以前训练过的12类物体探测器根据预测的类别将图像分类到12个文件夹中 , 然后查看数据集以查找错误分类 。
我选择了3 , 因为它需要我做的机械工作较少 , 而且我发现其他问题在过去的一个聪明的解决方案 。
为此 , 我所要做的就是修改我用于将边界框输出到图像上的脚本以提供框坐标 , 以便我可以切割图像阵列以裁剪出图像中的骰子顶部 。 然后使用边界框中的预测类别 , 我将图像分类到不同的文件夹中 。 这让我可以在几分钟内生成2500张左右的裁剪图像 , 而不是话费太多时间手工裁剪2500张图像 。
接下来是清洁 。 下面是6s文件夹的屏幕截图 , 其中有很多9s的也隐藏在其中 。 对于这些骰子 , 9s和6s通常在底部附近标有线或点 , 对于没有标记的骰子 , 这意味着它是6 。
检测器|案例解析:用Tensorflow和Pytorch计算骰子值文章插图
另一个有趣的类别是看1s vs 7s
检测器|案例解析:用Tensorflow和Pytorch计算骰子值文章插图
这也让我对我的12类对象检测模型所产生的分类错误类型有了一个很好的感觉 。 根据角度 , 您会看到5s被标记为2s或6s , 11s或12s被标记为10s , 2s或1s , 因为模型对这些数字的接触相对较少 。
一旦数据集被分类到12个文件夹中 , 我就准备向它扔几个CNN以查看哪些有效 。
训练Pytorch CNN
有了数据集并按类分解到文件夹中 , 使用标准数据集和数据加载器函数来利用pytorch CNN管道非常简单 。 这里要注意的一件事是我制作了120张图像的验证集(每个类10张) 。 我做了一个平衡的验证集 , 即使对值1-6存在很大的不平衡 , 因为那些显示在所有骰子上 , 而值11和12仅出现在d12s上 , 因此它们表现最少 。
我发现使用经过预先训练的ResNet模型工作得相当好 , 我只是允许在几个时期内对权重进行微调 。 在大约15个时期之后 , 我使用ResNet 50获得了95%的验证设置准确度 , 并发现将其增加到ResNet 101可将其提高到97%的准确度 。 我最终坚持使用ResNet 101 , 因为目前模型足迹不是我的一个大问题 。
把它们放在一起
现在我已经完成了两件事 , 我只需将它们组合成一个管道 。 第一阶段模型将检测骰子面并将这些骰子面部馈送到第二模型以进行分类 。 然后根据后端模型的分类 , 我能够在屏幕上添加骰子值并显示它们 。
这是相对简单的 , 需要添加初始化Pytorch模型并添加其他函数来预处理图像 , 将结果映射到其标签 , 并将结果相加 。 唯一令人烦恼的部分是我没有一台当前可用的多GPU机器 , 并且当其中一些基于Tensorflow的时候使用多个模型会让人讨厌 。
对于其他项目 , 我在同一个GPU上使用了多个基于Pytorch的大型模型 , 就像我的Fate Grand Order机器人一样 。 但是我发现Tensorflow倾向于将所有可用的GPU资源分配给自己 。 因此 , 为了运行多个模型 , 我基本上处理了在任何给定点上哪一个处于活动状态 , 但对于这个用例 , 我只是将Pytorch CNN分配给我的CPU运行 。 这会降低评估速度 , 但暂时是一个可以快速解决的办法 。 接下来的技术购买可能会建立一个GPU集群 , 使这样的事情不那么烦人 。
检测器|案例解析:用Tensorflow和Pytorch计算骰子值文章插图
它得到正确的数值20
比较两种方法
在考虑这两种方法时 , 我认为主要的权衡是速度和准确性之间的权衡 。
我可以在单个GPU上运行的单一模型的第一种方法评估速度比我的GPU + CPU方法快得多 。 但是 , 在两个GPU上运行第二个管道可能会最大限度地减少这种差异 。
现在为了让事情变得有趣些 , 你可以看看两者之间的表现 。 为此 , 我从训练集和验证集中提取了25个示例 , 我想你可以称之为测试集 , 并在它们上运行两个模型 。 为此 , 我只是看看他们是否得到了正确的总骰子值 , 如果他们没有 , 我就注意到他们所犯的错误类型 。
第一个模型得到了25个中的8个完全正确(32%) , 而两个阶段的管道中有25个完全正确(64%) 。 因此 , 我在做这个博客时的一般假设似乎是正确的 , 即使两者仍有改进的余地 。