1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        從0梳理1場(chǎng)CV缺陷檢測(cè)賽事!

        共 6994字,需瀏覽 14分鐘

         ·

        2021-02-21 22:04

        ↑↑↑關(guān)注后"星標(biāo)"Datawhale
        每日干貨?&?每月組隊(duì)學(xué)習(xí),不錯(cuò)過
        ?Datawhale干貨?
        作者:江保祥,廈門大學(xué)

        一、布匹缺陷檢測(cè)比賽分析

        1. 賽題背景

        去年的廣東工業(yè)大賽已入選到全球人工智能技術(shù)大賽熱身賽,大賽聚焦布匹疵點(diǎn)智能檢測(cè),要求選手研究開發(fā)高效可靠的計(jì)算機(jī)視覺算法,提升布匹疵點(diǎn)檢驗(yàn)的準(zhǔn)確度,降低對(duì)大量人工的依賴,提升布樣疵點(diǎn)質(zhì)檢的效果和效率。

        比賽地址:https://tianchi.aliyun.com/competition/entrance/531864/introduction

        2. 比賽要求

        要求算法既要檢測(cè)布匹是否包含疵點(diǎn),又要給出疵點(diǎn)具體的位置和類別,既考察疵點(diǎn)檢出能力、也考察疵點(diǎn)定位和分類能力。

        3. 評(píng)估指標(biāo)

        賽題分?jǐn)?shù)計(jì)算方式:0.2ACC+0.8mAP

        ACC:是有瑕疵或無瑕疵的分類指標(biāo),考察瑕疵檢出能力。

        其中提交結(jié)果name字段中出現(xiàn)過的測(cè)試圖片均認(rèn)為有瑕疵,未出現(xiàn)的測(cè)試圖片認(rèn)為是無瑕疵。

        mAP:參照PASCALVOC的評(píng)估標(biāo)準(zhǔn)計(jì)算瑕疵的mAP值。

        4. 提交說明

        平臺(tái)采用了基于GPU計(jì)算資源的提交鏡像的方式,將本地代碼打包成鏡像提交,推送至阿里云容器鏡像倉庫后,在天池提交頁面中輸入鏡像地址、用戶名和倉庫密碼。由比賽平臺(tái)拉取鏡像運(yùn)行, 運(yùn)行結(jié)束即可在成績(jī)頁面查詢運(yùn)行日志及評(píng)測(cè)結(jié)果。

        二、比賽數(shù)據(jù)分析

        1. 數(shù)據(jù)大小

        數(shù)據(jù)大小 官方一共提供了9576張圖片用于訓(xùn)練其中有瑕疵圖片5913張,無瑕疵圖片3663張 瑕疵類別共有34個(gè)類別,在最終提交結(jié)果上對(duì)一些相似類別進(jìn)行了合并后,共分為15個(gè)瑕疵類別。圖片尺寸:4096 * 1696。

        2. 比賽難點(diǎn)

        種類較多,且數(shù)據(jù)分布不均 缺陷形狀具有極端的長(zhǎng)寬比 圖片尺寸較大,部分缺陷尺寸小,小目標(biāo)問題。

        三、快速實(shí)現(xiàn)比賽Baseline

        完整代碼已開源 或后臺(tái)回復(fù) 缺陷檢測(cè) 下載
        開源地址:https://github.com/datawhalechina/team-learning-cv/tree/master/DefectDetection

        視頻講解:https://www.bilibili.com/video/BV1dK4y1Q7dc

        1. 開源框架選擇

        任務(wù)分析

        此次任務(wù)是布匹瑕疵檢測(cè),首先考慮的應(yīng)該是目標(biāo)檢測(cè)框架。當(dāng)前目標(biāo)檢測(cè)主要分為one-stage和two-stage兩種類型,以YOLO,SSD等框架為代表的one-stage速度快,以Faster-RCNN為代表的two-stage框架精度高?;诒敬稳蝿?wù)時(shí)間有限制在1小時(shí)內(nèi),因此采用單階段YOLOV5的方案

        環(huán)境配置

        # pip install -U -r requirements.txt

        #Output:
        Cython
        numpy==1.17
        opencv-python
        torch>=1.4
        matplotlib
        pillow
        tensorboard
        PyYAML>=5.3
        torchvision
        scipy
        tqdm

        訓(xùn)練設(shè)置

        $ python train.py --data coco.yaml --cfg yolov5s.yaml --weights '' --batch-size 64
        yolov5m 40
        yolov5l 24
        yolov5x 16

        測(cè)試設(shè)置

        $ python detcet.py --source ./inference/images/ --weights yolov5s.pt  --conf 0.4

        2. 數(shù)據(jù)預(yù)處理

        數(shù)據(jù)格式轉(zhuǎn)換

        代碼詳見convertTrainLabel.py ,部分代碼及分析如下

        #讀取比賽數(shù)據(jù)標(biāo)簽文件      
        josn_path = "./train_data/guangdong1_round2_train2_20191004_Annotations/Annotations/anno_train.json"
        image_path = "./train_data/guangdong1_round2_train2_20191004_images/defect/"
        with open(josn_path, 'r') as f:
        temps = tqdm(json.loads(f.read()))
        for temp in temps:
        name = temp["name"].split('.')[0]
        path = os.path.join(image_path, name, temp["name"])
        im = cv2.imread(path)
        sp = im.shape
        image_h, image_w = sp[0], sp[1]
        x_l, y_l, x_r, y_r = temp["bbox"]
        #獲取標(biāo)簽對(duì)應(yīng)的類別一共15種
        if temp["defect_name"]=="沾污":
        defect_name = '0'
        elif temp["defect_name"]=="錯(cuò)花":
        defect_name = '1'
        .......
        #標(biāo)注格式轉(zhuǎn)換 江都區(qū)并存入列表
        x_center = (x_l + x_r)/(2*image_w)
        y_center = (y_l + y_r)/(2*image_h)
        w = (x_r - x_l)/(image_w)
        h = (y_r - y_l)/(image_h)
        name_list.append(temp["name"])
        c_list.append(defect_name)
        image_h_list.append(image_w)
        image_w_list.append(image_h)
        x_center_list.append(x_center)
        y_center_list.append(y_center)
        w_list.append(w)
        h_list.append(h)
        .....

        #讀取列表 list 數(shù)據(jù),并劃分訓(xùn)練集和驗(yàn)證集
        index = list(set(name_list))
        print(len(index))
        for fold in [0]:
        val_index = index[len(index) * fold // 5:len(index) * (fold + 1) // 5]
        print(len(val_index))
        for num, name in enumerate(name_list):
        print(c_list[num], x_center_list[num], y_center_list[num], w_list[num], h_list[num])
        row = [c_list[num], x_center_list[num], y_center_list[num], w_list[num], h_list[num]]
        if name in val_index:
        path2save = 'val/'
        else:
        path2save = 'train/'

        #數(shù)據(jù)寫入 yolov5文件格式
        if not os.path.exists('convertor/fold{}/labels/'.format(fold) + path2save):
        os.makedirs('convertor/fold{}/labels/'.format(fold) + path2save)
        with open('convertor/fold{}/labels/'.format(fold) + path2save + name.split('.')[0] + ".txt", 'a+') as f:
        for data in row:
        f.write('{} '.format(data))
        f.write('\n')
        if not os.path.exists('convertor/fold{}/images/{}'.format(fold, path2save)):
        os.makedirs('convertor/fold{}/images/{}'.format(fold, path2save))
        sh.copy(os.path.join(image_path, name.split('.')[0], name),
        'convertor/fold{}/images/{}/{}'.format(fold, path2save, name))

        3. 模型訓(xùn)練

        數(shù)據(jù)路徑設(shè)置:編輯一個(gè)數(shù)據(jù)路徑文件夾yaml文件

        例如:data/coco128.yaml

        # train and val datasets (image directory or *.txt file with image paths)
        train: ./process_data/images/train/
        val: ./process_data/images/val/

        # number of classes
        nc: 15

        # class names
        names: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12','13', '14', '15']

        模型文件選擇:yolov5x.yaml, yolov5m.yaml, yolov5l.yaml yolov5s.yaml文件

        可以選擇合適的模型文件,從左到右精度下降,但是速率增大

        nc: 15  # number of classes
        depth_multiple: 1.33 # model depth multiple
        width_multiple: 1.25 # layer channel multiple
        anchors:
        - [116,90, 156,198, 373,326] # P5/32
        - [30,61, 62,45, 59,119] # P4/16
        - [10,13, 16,30, 33,23] # P3/8
        backbone:
        # [from, number, module, args]
        [[-1, 1, Focus, [64, 3]], # 0-P1/2
        [-1, 1, Conv, [128, 3, 2]], # 1-P2/4
        [-1, 3, BottleneckCSP, [128]],
        ...........

        模型訓(xùn)練

        $ python train.py --data coco.yaml --cfg yolov5s.yaml --weights '' --batch-size 64
        yolov5m 40
        yolov5l 24
        yolov5x 16

        4. 測(cè)試模型并生成結(jié)果

        detect.py的輸出結(jié)果的格式修改成提交結(jié)果的格式

        #將輸出結(jié)果的格式變成比賽需要提交的格式,并存入list,方便后面寫入result.json文件中
        if save_json:
        name = os.path.split(txt_path)[-1]
        print(name)
        x1, y1, x2, y2 = float(xyxy[0]), float(xyxy[1]), float(xyxy[2]), float(xyxy[3])
        bbox = [x1, y1, x2, y2]
        img_name = name
        conf = float(conf)
        #add solution remove other
        result.append(
        {'name': img_name+'.jpg', 'category': int(cls+1), 'bbox': bbox,
        'score': conf})
        print("result: ", {'name': img_name+'.jpg', 'category': int(cls+1), 'bbox': bbox,'score': conf})
        #寫入result.json文件中
        if save_json:
        if not os.path.exists(save_dir):
        os.makedirs(save_dir)
        with open(os.path.join(save_dir, "result.json"), 'w') as fp:
        json.dump(result, fp, indent=4, ensure_ascii=False)

        最后就是docker生成鏡像,并提交鏡像,至此就實(shí)現(xiàn)了比賽的Baseline了

        四、改進(jìn)思路

        在實(shí)現(xiàn)比賽的Baseline后,可以說是完成了第一步,后面如果想要獲取好的成績(jī)就需要我們根據(jù)比賽的任務(wù),比賽的難點(diǎn)。進(jìn)行調(diào)整方案,修改網(wǎng)絡(luò),修改策略。

        前面我們提到該布匹缺陷檢測(cè)任務(wù)的難點(diǎn)主要有:

        • 數(shù)據(jù)種類分布不均勻
        • 缺陷具有極端的長(zhǎng)寬比
        • 小目標(biāo)問題

        1. 數(shù)據(jù)種類分布不均勻

        解決思路:

        • 過采樣種類較少的樣本
        • 數(shù)據(jù)擴(kuò)增:在訓(xùn)練方面,除了常規(guī)的數(shù)據(jù)增強(qiáng)之外,我們觀察到原始的標(biāo)注存在不準(zhǔn)確的情況,為了使網(wǎng)絡(luò)適應(yīng)這種不確定性,我們?cè)谟?xùn)練時(shí)隨機(jī)對(duì)原始的標(biāo)注框進(jìn)行了抖動(dòng),是網(wǎng)絡(luò)能夠?qū)W習(xí)這種不確定性

        2. 缺陷具有極端的長(zhǎng)寬比

        解決思路:

        • anchor 設(shè)置:考慮到樣本的長(zhǎng)寬比差異較大,通過聚類分析可以發(fā)現(xiàn),原始的anchor并不能滿足當(dāng)前任務(wù)的需要,通過增加anchor數(shù)目,提高檢測(cè)性能。
        • 可變形卷積:增強(qiáng)特征提取能力,提高檢測(cè)性能 方法:在 backbone結(jié)構(gòu)的最后一個(gè)block采用可變形卷積核 優(yōu)點(diǎn):可變形卷積能夠計(jì)算每個(gè)點(diǎn)的偏移,從最合適的地方取特征進(jìn)行卷積

        3. 小目標(biāo)問題

        解決思路:

        • 針對(duì)小目標(biāo)的擴(kuò)增方式:Copy-Pasted 也就是將小目標(biāo)貼到圖像中的任意位置并生成新的標(biāo)注,并且粘貼的小目標(biāo)可以進(jìn)行隨機(jī)變換(縮放,翻折,旋轉(zhuǎn)等),這種方式通過增加每個(gè)圖像中小目標(biāo)的數(shù)量,匹配的 anchor 的數(shù)量也會(huì)隨之增加,這進(jìn)而提升了小目標(biāo)在訓(xùn)練階段對(duì) loss 計(jì)算的貢獻(xiàn)。
        • 多尺度訓(xùn)練:多尺度訓(xùn)練(Multi Scale Training, MST)通常是指設(shè)置幾種不同的圖片輸入尺度,訓(xùn)練時(shí)從多個(gè)尺度中隨機(jī)選取一種尺度,將輸入圖片縮放到該尺度并送入網(wǎng)絡(luò)中
        • FPN 增加融合因子 Effective Fusion Factor in FPN for Tiny Object Detection

        4.漲分Tricks

        在實(shí)現(xiàn)對(duì)網(wǎng)絡(luò)的改進(jìn)后,我們可以使用一些比賽的漲分技巧

        半監(jiān)督學(xué)習(xí)

        利用訓(xùn)練集訓(xùn)練好的模型預(yù)測(cè)測(cè)試集,將預(yù)測(cè)結(jié)果作為偽標(biāo)簽加入訓(xùn)練

        測(cè)試增強(qiáng)

        對(duì)檢測(cè)圖片進(jìn)行翻折、旋轉(zhuǎn)、色彩增強(qiáng),然后分別對(duì)這些擴(kuò)增圖片進(jìn)行預(yù)測(cè),將多個(gè)預(yù)測(cè)結(jié)果進(jìn)行融合

        模型集成

        多種模型進(jìn)行預(yù)測(cè),將一張圖片的多個(gè)結(jié)果進(jìn)行融合

        閱讀原文可以參與缺陷檢測(cè)實(shí)踐
        “整理不易,點(diǎn)三連
        瀏覽 76
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            国产颜射 | 亚洲无码专区视频在线 | 男人的天堂久草 | 亚洲无遮挡| ass众多明星裸体pics | 第五色丁香欧美小说在线观看 | 可以免费看美女操逼 | 做爰高潮小视频在线观看 | 国产精品淫片 | 91伊人网|