TMJ第四轮训练结果

Posted on Oct 26, 2024

概述

TMJ 隔了很久没做了,这次收集到的数据比较大,数据量大了,处理实际也上升一个量级,光是切割数据集都需要一小时以上。

实验过程

实验分两个类型做,第一种是通过先训练 Yolo 模型再进行一轮的 CNN 训练,第二种是直接基于 labelme 的结果切割图片之后进行 CNN 训练。

第一种

刚拿到数据的时候按螺丝松紧模型的方法做过一次,效果不是很好,猜测是 Left 和 Right 的差距比较大,当前的数据量下不应该引入 Left 和 Right 的影响因素的。

第二种

鉴于第一种的结果出现的问题,第二种开始做的时候,就考虑先区分 Left 和 Right 了。这部分代码处理的逻辑会麻烦一点,要基于 labelme 的结果重新写一个数据预处理的代码,处理的代码逻辑如下:

{
  "version": "5.5.0",
  "flags": {},
  "shapes": [
    {
      "label": "N",
      "points": [
        [
          246.82051282051276,
          117.38461538461546
        ],
        [
          527.6708860759495,
          433.64556962025324
        ]
      ],
      "group_id": null,
      "description": "",
      "shape_type": "rectangle",
      "flags": {},
      "mask": null
    },
    {
      "label": "N",
      "points": [
        [
          2409.641025641026,
          130.2051282051283
        ],
        [
          2719.897435897436,
          437.8974358974359
        ]
      ],
      "group_id": null,
      "description": "",
      "shape_type": "rectangle",
      "flags": {},
      "mask": null
    }
  ],
  "imagePath": "xxx忽略"
  "imageData": "xxx忽略"
  "imageHeight": 1504,
  "imageWidth": 2868
}

从上面一个的 json 文件可以看出,label 为 N 的区域被标记了两个区域,从坐标上看,因为图片的宽度也就是 imageWidth 为2868,那么我们是可以粗略的用每个区域的 points 这个二维数组的第一个元素里的第一个值作为区分 Left 和 Right 的标记,参考下图,两个区域的 x1,如果比 imageWidth 的一半小,那就判为 Left,否则就判为 Right。

依据上面的规则对数据再进行处理,可以得到 Left 和 Right 的数据集如下。

接下来就是实验结果的部分,分为 Left 和 Right,以及将 Right 翻转成 Left 这三部分的结果。

Left

Left 的训练集的情况如下,按照惯例,训练集的数据量是所有图片的80%,测试集和验证集分别是10%。

Folder: N, Total Training Images: 2336
Folder: non_N, Total Training Images: 884

训练集的准确率已经很高了,达到99%。

在自己定义的测试集中,达到70%的准确率。

从这个混淆矩阵中可以得到以下信息:

  1. 真实标签为 N 的样本中,模型预测为 N 的有 486 个,预测为 non_N 的有 168 个。
  2. 真实标签为 non_N 的样本中,模型预测为 N 的有 41 个,预测为 non_N 的有 32 个。
  3. 这些数据可以用来计算模型在不同标签上的准确率(precision)、召回率(recall)和 F1 分数等指标,从而评估模型的性能。

例如,对于 N 类别:

  • 准确率 = 486 / (486 + 41) = 92.2%
  • 召回率 = 486 / (486 + 168) = 74.3%
  • F1分数 = 2 * 92.2% * 74.3% / (92.2% + 74.3%) = 82.3%

对于 non_N 类别:

  • 准确率 = 32 / (41 + 32) = 43.8%
  • 召回率 = 32 / (168 + 32) = 16.0%
  • F1 分数 = 2 * 43.8% * 16.0% / (43.8% + 16.0%) = 23.5%

从这个结果可以看出,该模型在 N 类别上表现较好,但在 non_N 类别上存在一定的误分问题,需要进一步优化模型,当然优化的方向是比较明确的,就是增加 non_N 图片的数量,从训练集来看,N 的图片在3000左右,non_N 只有1100左右。

Right 的结果跟 Left 差不多,下面主要就放一下结果。

Left + Right

关于这个数据集的准备就更麻烦一点,需要把 right 的图片翻转之后,并入到 left 中,翻转的依据是左右两边的解剖结构是类似的,通过翻转可以增加 non_N 和 N 的样本数。

可以看到翻转之后的图片的 non_N/N 的样本量增大了。

训练过程如下。

结果就不详细解读了,看看图就可以了,总体上说,样本量增大了,对模型的效果还是可以的。

其他

数据格式问题

文件命名一定要避免中文字符,包括标点符号,比如中文的括号是(),这种字符在代码处理的时候都会比较麻烦,建议用英文的下划线_来替换。

图片异常

在进行切图的时候遇到一张图片有问题,可以 review 一下。

2024-10-26 14:49:34,802 - ERROR - 无法读取图片: /tf/oral/TMJ10-13/dataset/P750720.png

Yolo问题

鉴于现在样本量已经不小了,从 labelme 的结果已经可以训练不错的模型了,如果想训练 Yolo 模型再去语义分割图片再进行 CNN 在当前的阶段应该不是很必要了,除非要做到数十万的大型研究,此时用 labelme 标记样本的人力需求太大才有必要用 Yolo 来做大规模的机器图片分割。