先说结果:复赛27/3107,只能说一般般,没有打入前top20,并没有实现自己的目标。但是也是收获了不少经验,做一些总结和分享。
失败的经验:
贴一张最后决赛的结果:
其中GPU第一队,基本是大佬合集,看个人简介就知道,经常获得冠军的队。也是唯一一个实现map超过0.7的队伍。
自己的实现思路:
Unet关键点检测+resNet分类
要实现的目标:
输入一些dicom医学图像,实现输出关键点的位置和疾病类别分类。
自己实现过的一些思路:
不区分类别,直接将椎体和椎间盘11个关键点输入Unet,输出的预测热图。
输入的图像有很多突出的点(噪点),使用各向异性滤波来处理(平滑),但是这样处理的话,测试集也需要输入处理。
把整11个点做成高斯热图来输入,当做整个脊椎的热图,但是没有什么改进。
其中面对的一个问题,可以定位到目标大概位置,但是脊椎有很多相似的结构,导致预测的开头容易出现跳格的现象,所以设想一种改进的Loss,主要利用点之间的距离相同,对距离做一个约束,故把这种距离加入到Loss中,我把他命名为posiLoss,后来在一篇论文中看到了相似的改进。
class posiLoss(nn.Module):
def __init__(self,alph=50, beta=100):
super(posiLoss, self).__init__()
self.alph = alph
self.beta = beta
self.criterion_part1 = nn.MSELoss()
self.sz = 11
self.topKposi = 5
def posiLoss(self, pred_heatmap, gt_heatmap):
n,c,h,w = pred_heatmap.shape
n_loss = list()
for n_idx in range(n):
# print("n:",n)
pred_posiRation = self.relationPosi(pred_heatmap[n_idx])
gt_posiRation = self.relationPosi(gt_heatmap[n_idx])
psoiLossL = torch.Tensor(torch.abs(torch.sub(pred_posiRation, gt_posiRation))).cuda()
# print("psoiLoss", psoiLossL)
ret_psoiLoss = torch.sum(torch.topk(psoiLossL, self.topKposi).values)
# print("ret_psoiLoss", ret_psoiLoss)
n_loss.append(ret_psoiLoss)
ret_n_loss = torch.mean(torch.Tensor(n_loss))
return ret_n_loss
def relationPosi(self, heatmap):
# print(heatmap.shape)
ret = list()
ret.append(self.criterion_part1(heatmap[0], heatmap[1]))
for i in range(1, self.sz-1):
# print("i:",i)
up = self.criterion_part1(heatmap[i-1], heatmap[i])
down = self.criterion_part1(heatmap[i+1], heatmap[i])
# print("down",down)
ret.append(torch.mean(torch.Tensor((up, down))))
ret.append(self.criterion_part1(heatmap[self.sz-1], heatmap[self.sz -2]))
return torch.Tensor(ret)
def forward(self, pred_heatmap, gt_heatmap):
mse_loss = self.criterion_part1(pred_heatmap,gt_heatmap)
# print("mse_loss", mse_loss)
posiLosss = self.posiLoss(pred_heatmap,gt_heatmap)
# print("posiLosss",posiLosss)
return self.alph*mse_loss+self.beta*posiLosss
各种结果中UnetDouble+posiLoss+diffuse会最好。定位精度可以实现0.81,表里未记录。
一些未曾实现的想法:
6. 3DUnet,因为dicom文件是脊椎切片,是相关联的。
7. 传统方法:有论文显示,使用HOG和SVM来实现定位,准确率也可以很高。
8. 利用脊椎上的亮暗变化规律来定位中心值,因为不同图像之间差距很大,但是有一般的规律。
9.轴状位结合切片,作为输入信息。btw,主要原因是切片标注的数据实在是有点乱,很多标注不一致,希望天池可以做的更严谨一些。
GPU冠军方案:
检测网络:Cascade R-CNN(X-101)+ FPN + DCN
分类网络:ResNeSt269
结果:
参考链接:
Spark“数字人体”脊柱疾病智能诊断-GPU赛道-deep thinker-冠军比赛方案
GPU亚军方案:
中间加入FPN,我发现经常拿奖的一些方案都是加入了FPN的结构,来提升对小目标的检测。
由于数据集不平衡,所以在后面使用了加权的Loss,以及模型融合。
一些特点:
一.采用端到端检测网络,充分利用了图像全局与局部的信息。
二.使用定位框损失DIOU-Loss,提高边框定位精度。
三.通过加权分类损失应对类别极度不平衡的情况。
四.高亮抑制方法使得图像更易识别,伪3D数据增广有效地增加了样本多样性。
五.根据任务提出了基于中心加权检测模型融合方法。
六.极快的训练和推理速度,极大地方便方案的落地。
我的开源地址:https://github.com/SkySailing/tianchi_spinalAI_dection_competetion
有用的话,请点一个star,谢谢!!
参考:
Spark"数字人体"AI挑战赛_脊柱疾病智能诊断大赛_GPU赛道亚军比赛攻略_shiontao团队
天池11月之星:北大新星陈**、赵*与天池的参赛故事
天池论坛