使用centernet進行大規模遙感影像目標檢測

        時間又過了好久了。。。這一次我再來更新一下目標檢測這一塊的內容,爲什麼要更新這一塊呢,主要是看到了YOLOX的發佈,晚上11點躺在牀上看的,終於看到了一個硬貨,曠世科技還是牛逼。。一句話總結,什麼Anchor,什麼nms,統統不要,直接一把梭,端對端輸出結果,最終精度又高,網絡又簡潔,真是不錯。好了,希望不要被曠世的人看見,我這彩虹屁吹的。
       很久很久之前,我就Anchor非常不爽,爲什麼神經網絡這麼簡潔的東西,要加這麼個玩意,不就是讓網絡訓練的更加穩定一些麼,這個東西的添加,再某個程度上來說,大大增加了開發難度,容易在編程的時候搞暈頭腦,雖然說精度尚可,但是我隱隱約約總感覺這玩意絕對淘汰,所以我一直期待一種真正的工程版的Anchor-Free算法,今天要講的就是centernet這個網絡,我非常喜歡這篇文章,非常簡單,非常有效,而且可擴展性有非常的好。
       原理部分我就不多講了,我們先直接看結果吧
                            
       30張樣本,檢測出來的飛機還是不錯的!
      當然這裏面還有一些核心算法,我用python代碼給大家講一下,這篇論文裏面也有幾個需要注意的地方,尤其是用到遙感工程項目裏面。
      第一個,groundTruth準備
      這一部分,我們需要準備真值中心點,還有長寬,中心點偏移,這裏需要注意一點,就是原始論文裏面有這樣一句話,--We do not normalize the scale and directly use the raw pixel coordinates. We instead scale the loss by a constant λsize.
       The overall training objective !,意思就是說使用原始的長寬輸入到真值裏面,然後計算loss,這個實在是太重要了,因爲我發現很多知乎公衆號裏邊,他媽的根本就沒提這個細節,我就按照很多通用做法,把它scale成一定的比例,當成真值,
結果發現長寬輸出會出現負數,這就明顯比對了,請使用下面這個代碼!!
def get_hw_center(json_path, h, w, scale):
    """
    從json格式中讀取目標的寬高和中心點位置
    json_path: json文件的路徑
    h:         原始圖像的高度
    w:         原始圖像的寬度
    scale;    特徵圖與原圖的比例,centernet爲1/4
    """
    myObject = []
    with open(json_path, 'r', encoding='utf-8') as f:
        ret_dic = json.load(f)
        imgPath = ret_dic['path']
        target_Obj['imgPath'] = imgPath

        object = (ret_dic['outputs']['object'])
        numObject = len(object)
        print(numObject)

        for i in range(0, numObject):
            obj = object[i]['bndbox']
            xmin = obj['xmin']
            ymin = obj['ymin']
            xmax = obj['xmax']
            ymax = obj['ymax']

            obj_width = np.abs(xmax - xmin)*scale  # 原圖中目標的寬度,原版論文無需歸一化
            obj_height = np.abs(ymax - ymin)*scale  # 原圖中目標的高度,原版論文無需歸一化

            centerPoint = [(xmax+xmin)/2*scale, (ymax+ymin) /
                           2*scale]  # 目標在特徵圖中的中心點座標
            target_Obj['height'] = np.array(obj_height).copy()
            target_Obj['width'] = np.array(obj_width).copy()
            target_Obj['centerPoint'] = np.array(centerPoint).copy()

            myObject.append(target_Obj.copy())

        return myObject
 
      第二個,網絡結構裏面更改
      原論文---We modify both ResNets and DLA-34 using deformable convolution layers [12] and use the Hourglass network as is,意思就是說,resnet,DLA,hourglass這些網絡,作者在上採樣階段,用了可形變卷積來替換,
這一個可以多說一點,形變卷積可以學習到傳統卷積無法學下到的長距離信息。
 
      第三個,損失函數
      這個是最重要的了,我們一定要看原論文,特別注意熱圖,長寬,中心點偏移三者的權重,論文推薦比例爲[1,0.1,1],當然這是實驗科學,具體的還要根據各位的自己數據來!
      我們上代碼:
class L1Loss(nn.Module):
    """
    L1 loss,論文證明,該loss要比smooth L1 loss要好!
    """

    def __init__(self):
        super(L1Loss, self).__init__()

    def forward(self, pred, mask, target):
        numPoint = mask[:, 0, :, :].float().sum()  # 目標點個數

        loss = F.l1_loss(pred * mask, target * mask,
                         reduction='elementwise_mean')
        return loss/(numPoint+1e-4)

     好吧,先寫到這裏,下一步我會來更新超大影像的目標檢測及相關工程應用上的精度 與效率如何,需要代碼請加qq 1044625113。

     用一句話來總結我的想法,只做有用的東西,不做灌水的東西!大家共勉!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章