返回列表

7th Place Solution(simple but messy)

392. Prostate cANcer graDe Assessment (PANDA) Challenge | prostate-cancer-grade-assessment

开始: 2020-04-21 结束: 2020-07-22 医学影像分析 数据算法赛
第7名方案(简单但杂乱)

第7名方案(简单但杂乱)

作者: ctrasd123, trchai, nina
比赛: Prostate Cancer Grade Assessment (前列腺癌分级评估)
排名: 第7名

首先,非常感谢主办方。

这个挑战与 APTOS-2019 非常相似,我曾作为课程作业研究了几个月。因此,我直接使用了我课程作业的流程(基于 Lex Toumbourou 的方案,非常感谢),并修改了一些细节。同样非常感谢 IafossQishen Ha 提供的有用的 Notebooks。

我们的模型很简单,但有点杂乱。

切片

我们尝试了 256x256x32、192x192x64、154x154x100,但它们在 Public LB(公开排行榜)上没有显示出差异。

我们还提出了一种新的切片方法。它可以在不破坏形状特征的情况下包含更多的病理部分。大尺寸切片确保形状特征不会丢失,而小尺寸切片确保空白区域不会太大。

def get_tiles_combine(img,mode=0):
    images = np.ones((1536, 1536, 3))*255
    h, w, c = img.shape
    result_all=[]
    pad_h = (256 - h % 256) % 256 + ((256 * mode) // 2)
    pad_w = (256 - w % 256) % 256 + ((256 * mode) // 2)
    #print(pad_h,pad_w,c)
    img2 = np.pad(img,[[pad_h // 2, pad_h - pad_h // 2], [pad_w // 2,pad_w - pad_w//2], [0,0]], 'constant',constant_values=255)
    windows=[256,256,256,256,192,192,128]
    x_start=0
    for i in range(len(windows)):
        result = []
        window_size=windows[i]
        for x in range((h+pad_h)//window_size):
            for y in range((w+pad_w)//window_size):
                tile=img2[x*window_size:(x+1)*window_size,y*window_size:(y+1)*window_size]
                result.append([x,y,tile.sum()])
        #print(len(result))
        result.sort(key=lambda ele:ele[2])
        result=result[:1536//window_size]
        #print(len(result),result)
        for y in range(min(1536//window_size,len(result))):
            xx=result[y][0]
            yy=result[y][1]
            result_all.append([xx,yy])
            images[x_start:x_start+window_size,y*window_size:(y+1)*window_size]=\
                img2[xx*window_size:(xx+1)*window_size,yy*window_size:(yy+1)*window_size].copy()
            img2[xx*window_size:(xx+1)*window_size,yy*window_size:(yy+1)*window_size]=255
        x_start=x_start+windows[i]
    return images 

模型

我们简单地使用了 Efficientnet-B0。我们尝试了 B1-B3、Densenet 和 Resnext,但它们在 Public LB 上没有显示出差异,并且需要更多的 GPU 内存。

根据 APTOS-2019 的经验,我们使用了 GeM 池化:

def gem(x, p=3, eps=1e-6):
    return F.avg_pool2d(x.clamp(min=eps).pow(p), (x.size(-2), x.size(-1))).pow(1./p)

class GeM(nn.Module):
    def __init__(self, p=3, eps=1e-6):
        super(GeM,self).__init__()
        self.p = Parameter(torch.ones(1)*p)
        self.eps = eps
    def forward(self, x):
        return gem(x, p=self.p, eps=self.eps)       
    def __repr__(self):
        return self.__class__.__name__ + '(' + 'p=' + '{:.4f}'.format(self.p.data.tolist()[0]) + ', ' + '