TYS的博客

算法小白努力学习中

0%

工作内容

2021.12.23-12.25

重叠与密集细胞区域的检测文献调研。

调研了两篇密集区域目标检测的文章

PS-RCNN 两个阶段来分别检测未遮挡与严重遮挡的目标

迭代检测的方法,将历史的特征图卷积后作为第二次的输入

查看一下目前faster-rcnn的所有密集、重叠区域检测结果的情况,挑选出了一些检测结果差的样本。

2021.12.25~2021.12.31

密集、重叠细胞区域存在的检测难点,严重遮挡的细胞智能提供较少的视觉信息,检测得到的置信度低,容易被NMS最大值抑制去除。其中一种解决方案是Soft-NMS,Soft-NMS按照检测框之间的重合程度(IOU)进行置信度衰减,但是衰减的形式为人工设计,具有较大的局限性,且置信度降低的检测框后续也可能因不满足置信度阈值的要求而被去除。

针对密集、重叠细胞区域存在的检测失效的问题,拟采用迭代检测的方法来检测两组具有不同遮挡的细胞实例。第一轮检测没有遮挡或者轻微遮挡的细胞,在实例分割分支会得到的已检测到细胞的mask,之后采用该mask去覆盖原特征图的相应位置得到masked feature。在第二轮检测中使用masked feature去检测被遗漏的遮挡较严重的细胞。通过这样的迭代检测方式去提升网络对被遮挡细胞的检测能力。

image-20211231210503997

在该迭代检测的方法中,需要细胞边界的mask信息,因此需要使用语义分割进行细胞的位置标注。

先完成结果写入到labelme的json的形式,完成结果的迭代,目前完成细胞质标注约500余张,版本一迭代完成,形成了闭环,下图为mask-rcnn推断的结果,红色为细胞,绿色为细胞核。

image-20211231213015456

跑一下带有mask的检测网络如mask-rcnn

1
python tools/train.py  configs/mask_rcnn/mask_rcnn_r50_fpn_2x_coco.py --work-dir ./work_dir/mask_rcnn_new/

12.29检测结果出现了问题

  1. 只检测细胞边检
  2. 只检测细胞核边界
  3. 同时检测,目前存在失效的问题 不知道为什么 考虑结合语义分割网络,目前已找到问题未修改dataset coco数据集合与网络输出的分类类别,在结果写入json中出现了seg重复定义的bug。

mmdetection

遇到的问题

  1. 只检测细胞边检

  2. 只检测细胞核边界

  3. 同时检测,目前存在失效的问题 不知道为什么 考虑结合语义分割网络

目前怀疑的问题是dataset的类别没有进行改动

制作包含mask的coco数据集

1. coco数据集格式

coco数据集的官网https://cocodataset.org/

1
2
3
4
5
6
7
8
9
10
11
"annotations": [
{
"id": int,
"image_id": int,
"category_id": int,
"segmentation": RLE or [polygon],
"area": float,
"bbox": [x,y,width,height],
"iscrowd": 0 or 1,
}
]

标注的信息

cocoapi提供了将polygon转为rle格式的代码 annToRLE

labelme中通过group来判断边界框与mask的归属性。

2. 训练Mask-RCNN

pycococreator

跑通了mask-rcnn跑出的分割结果是与图片大小相同的mask

3. mmdet中对COCO类的包装

coco中imgToAnns记录了某一个img_id对应所有的ann_id

_parse_ann_info包含了一张图片的所有的bbox与segm信息

result2json将检测与分割的结果写为coco的json格式。

model.show_result展示检测结果

4. 标注的标准

对于处于边界的细胞,完整程度要大于5/6

对于细胞质非常小,几乎不可见的细胞种类,不标注细胞核,直接标注为细胞cell

参考文献

https://patrickwasp.com/create-your-own-coco-style-dataset/

https://github.com/waspinator/pycococreator/

mmdetection训练

如何制作数据集https://github.com/spytensor/prepare_detection_dataset

将labelme格式的数据转化为coco格式数据,需要对文件进行改写。

// 修改类别,修改image字段 修改area

1
annotation['area'] = annotation['bbox'][2]  *  annotation['bbox'][3]

json编辑器dadroit

通过目录的软连接将数据创建到data文件夹下

https://blog.csdn.net/duanyajun987/article/details/97659685

修改mmdetection/mmdet/datasets/coco.py CLASSES

mmdetection/mmdet/core/evaluation/class_names.py 修改

1
2
3
4
def coco_classes():
return [
'Prim', 'Lym', 'Mono', 'Plas', 'Red','Promy','Myelo','Late','Rods','Lobu','Eosl'
]

修改configs/models/retinanet_r50_fpn.py

1
num_classes=11,

训练数据集

1
python tools/train.py configs/retinanet/retinanet_r50_fpn_1x_coco.py  --work-dir work_dirs --resume-from work_dirs/latest.pth --gpus 2

多卡训练

1
bash ./tools/dist_train.sh  configs/retinanet/retinanet_r50_fpn_1x_coco.py  2  --work-dir work_dirs --resume-from work_dirs/latest.pth

查看显卡使用情况

1
watch -n 1 -d nvidia-smi

真正的训练文件mmdet/apis/train.py

修改epoch configs/_base_/schedules/schedules_1x.pyrunner = dict(type='EpochBasedRunner', max_epochs=240)修改epoch数量

修改batchsizeconfigs/datasets/coco_detection.py samples_per_gpu参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
data = dict(
samples_per_gpu=2,
workers_per_gpu=2,
train=dict(
type=dataset_type,
ann_file=data_root + 'annotations/instances_train2017.json',
img_prefix=data_root + 'train2017/',
pipeline=train_pipeline),
val=dict(
type=dataset_type,
ann_file=data_root + 'annotations/instances_val2017.json',
img_prefix=data_root + 'val2017/',
pipeline=test_pipeline),
test=dict(
type=dataset_type,
ann_file=data_root + 'annotations/instances_val2017.json',
img_prefix=data_root + 'val2017/',
pipeline=test_pipeline))

test

1
python tools/test.py configs/retinanet/retinanet_r50_fpn_1x_coco.py checkpoints/retinanet_r50_fpn_1x_coco_20200130-c2398f9e.pth --show
1
python tools/test.py configs/retinanet/retinanet_r50_fpn_1x_coco.py work_dirs/latest.pth --out test_result/latest.pkl --eval bbox --show-dir detect_results

mmdetection 结果炫酷可视化

TSNE

热力图(好看的colorbarhttps://www.cnblogs.com/zb-ml/p/13561449.html)

docker环境

1
docker run -dit --name sty_cell --gpus  all   -p 10022:22 --shm-size=16g  -v /mnt/sda/sty/data:/Data  nvidia/cuda:11.2.2-cudnn8-devel-ubuntu18.04

创建docker环境,安装anaconda,安装mmcv mmdet

训练faster-rcnn

修改 /mmdet/datasets/coco.py

1
CLASSES = ( 'Prim', 'Lym', 'Mono', 'Plas', 'Red','Promy','Myelo','Late','Rods','Lobu','Eosl')

修改config/_base_/models/faster_rcnn_r50_fpn.py

1
num_classes=11

指定GPU训练数据集

1
CUDA_VISIBLE_DEVICES=1 python tools/train.py configs/faster_rcnn/faster_rcnn_r50_fpn_2x_coco.py  --work-dir work_dir/faster_rcnn 

mmdetection 结果评价函数

{‘bboxes’: array([[119., 111., 244., 252.]], dtype=float32), ‘labels’: array([8]), ‘bboxes_ignore’: array([], shape=(0, 4), dtype=float32), ‘masks’: [[[119.0, 111.0, 244.0, 252.0]]], ‘seg_map’: ‘ER0437_233.png’}

1
python tools/test.py configs/faster_rcnn/faster_rcnn_r50_fpn_2x_coco.py work_dir/faster_rcnn/epoch_80.pth --work-dir . --out ./tmp.pkl
1
python tools/analysis_tools/analyze_results.py configs/faster_rcnn/faster_rcnn_r50_fpn_2x_coco.py ./tmp.pkl ./results
1
python tools/train.py configs/faster_rcnn/faster_rcnn_r50_fpn_2x_coco.py --work-dir/ ./work_dirs/faster_rcnn1

COCO数据集标注文件有三种信息

  • annotations标注的列表

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    {
    "id": 1655,
    "image_id": 1011,
    "category_id": 1,
    "bbox": [
    38.760299625468164,
    84.26966292134831,
    100.1198501872659,
    90.47940074906366
    ],
    "area": 9058.784048029847
    }
  • categories标注列表

    1
    2
    3
    4
    {
    "id": 1,
    "name": "Prim"
    }
  • images列表

    1
    2
    3
    4
    5
    6
    {
    "height": 363,
    "width": 360,
    "id": 0,
    "file_name": "ER0437_233.jpg"
    }

    coco_eval做了些什么?

    首先创建哈希表,_gts与_dts键位image_id与category_id,值为标注与预测bbox与类别信息。

    分析结果

    对结果进行分析

    mmdetection检测结果

    单纯用Precision与Recall评价检测器并不公平,AP计算了不同Recall下的Precision,综合性地评价了检测器,PR曲线,对所有BBox给出的置信度从高到低进行排序,当把置信度取某一个值S时,依次对前n个大于置信度的BBox计算Precison与Recall得到一组(P, R)结果。在计算AP时,都要对P-R曲线做一次修正,将P值修正为当r>R时最大的P

$$
Precision = \frac{TP}{TP + FP} \
Recall = \frac{TP}{TP + FN} \
AP = \int_{0}^{1} \max({P(r) | r \ge R}) dR
$$
对于BBox是TP还是FP的算法判断,如某一个BBox预测的label为1,则需要计算其与该图片中所有label为1的GT Box的IOU值,当大于iou_thres时,则该预测box为TP,否则为FP。当某一个GT被置信度最大的BBox匹配后,会从GT Box集合中移除。

TP + FN为测试集中该种类的样本的个数,因此不需要计算FN的个数,一个BBox与GT BOX是一一对应的,最后未检出的GT为FN

preview

类别平衡问题,mAP,所有类别的检测性能(AP)取平均,就是检测算法在这个IOU下的性能。

位置偏差

不同场景下对预测位置准确度的要求不同。 mmAP,设置一组iou阈值,每一个IOU

https://zhuanlan.zhihu.com/p/60707912 画出不同IOU下的PR曲线。

可以计算一个mAP,对这些性能取平均,在coco数据集中,mAP的计算针对10个IOU阈值下的AP取平均值np.linspace(0.5, 0.95, 10)

https://blog.csdn.net/lppfwl/article/details/108018950

https://zhuanlan.zhihu.com/p/55575423

训练结果

使用AdamW余弦退火算法,参数如下的训练结果

1
2021.11.29 今日跑完了transformer-fg 结果一般 到了80%的准确度后未提升。训练faster-rcnn 计算map各个分类下的曲线

明日计划完成faster-rcnn输出的特征热力图,与各个分类的map曲线,画一下分类Token的TSNE降维后的数据。

文献调研,调研一下骨髓血细胞分类的历史文献,并做PPT。

Pytorch Tensor

https://zhuanlan.zhihu.com/p/64551412

$\qquad$Tensor多维数组底层实现是使用一块连续内存的1维数组,Tensor在元信息里保存了多维数组的形状,在访问元素时,通过多维度索引转化成1维数组相对于数组起始位置的偏移量即可找到对应的数据。

$\qquad$某些Tensor操作(如transpose、permute、narrow、expand)与原Tensor是共享内存中的数据,不会改变底层数组的存储,但原来在语义上相邻、内存里也相邻的元素在执行这样的操作后,在语义上相邻,但在内存不相邻,即不连续了(is not contiguous)。

1
2
3
4
5
def window_partition(x, window_size):
B, H, W, C = x.shape
x = x.view(B, H // window_size, window_size, W // window_size, window_size, C)
windows = x.permute(0, 1, 3, 2, 4, 5).contiguous().view(-1, window_size, window_size, C)
return windows

以上述代码为例,在permute后,只是改变了tensor的元信息,现坐标相对于一维数组的变化,上述代码permute后,每个坐标对应的stride会发生改变。stride可以理解为每个下标的权重。

数组 t 在内存中实际以一维数组形式存储,通过 flatten 方法查看 t 的一维展开形式,实际存储形式与一维展开一致。

文献阅读

Morphogo: An Automatic Bone Marrow Cell Classification System on Digital Images Analyzed by Artificial Intelligence

骨髓血细胞检测难点

  • 正常骨髓中的细胞类别较多,包含处于不同发育阶段从早期到功能成熟的的间充质细胞、内皮细胞和造血细胞
Human-level recognition of blast cells in acute myeloid leukaemia with convolutional neural networks
  • 数字化过程,使用低倍镜,选择单层细胞且无重叠区域,每个细胞的形态学特征可以更好的被识别,将细胞划分与 AML 的形态学分类相关的子类别。对于每个AOI,使用100倍的油浸镜挑选并标注100个左右的白细胞。
  • 观察者间的差异,多人对同一批数据进行标注。 观察者内部的差异与自我一致性,多个月后同一人重新标注。
  • 采用Resnext网络,采用五折交叉验证进行训练,对于数据集采用随机划分的方式。可以按病人进行划分,避免训练与测试集的相关性,但是检测结果差别不大。
  • 类别不均衡问题采用旋转,随机水平或者垂直反转来扩充数据集。
  • 评价指标,准确率、敏感性、特异性。positave与negative是指是否属于某一个特定类别的数量。TP与TF为网络正确判定是否属于该类别图像的数量。
  • gold standard annotation 最佳标注的一种描述。通过该细胞与其他区域细胞的对比确定该细胞的类别。
  • 描述网络检测结果 混淆矩阵,特征图
Hierarchical Vision Transformer using Shifted Windows
  • 自然语言处理与视觉任务的差别,视觉目标尺寸变化较大 ,而自然语言处理中的word token大小固定。对于高分图像,self-attention计算复杂度是图像的大小的平方时间复杂度。
  • shift of the window
  • VIT缺点 在密集的视觉任务或高分辨图像中,不适合作为通用的backbone
  • https://zhuanlan.zhihu.com/p/411311520
Squeeze-and-Excitation Networks
  • convolutional filters are expected to be informative combinations by fusing spatial and channel-wise information together within local receptive fields.

  • 自适应的调整通道间的相应,通过对通道间的相关性进行建模。