<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          從0梳理1場CV缺陷檢測賽事!

          共 6994字,需瀏覽 14分鐘

           ·

          2021-02-21 22:04

          ↑↑↑關注后"星標"Datawhale
          每日干貨?&?每月組隊學習,不錯過
          ?Datawhale干貨?
          作者:江保祥,廈門大學

          一、布匹缺陷檢測比賽分析

          1. 賽題背景

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

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

          2. 比賽要求

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

          3. 評估指標

          賽題分數(shù)計算方式:0.2ACC+0.8mAP

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

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

          mAP:參照PASCALVOC的評估標準計算瑕疵的mAP值。

          4. 提交說明

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

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

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

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

          2. 比賽難點

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

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

          完整代碼已開源 或后臺回復 缺陷檢測 下載
          開源地址:https://github.com/datawhalechina/team-learning-cv/tree/master/DefectDetection

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

          1. 開源框架選擇

          任務分析

          此次任務是布匹瑕疵檢測,首先考慮的應該是目標檢測框架。當前目標檢測主要分為one-stage和two-stage兩種類型,以YOLO,SSD等框架為代表的one-stage速度快,以Faster-RCNN為代表的two-stage框架精度高?;诒敬稳蝿諘r間有限制在1小時內(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

          訓練設置

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

          測試設置

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

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

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

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

          #讀取比賽數(shù)據(jù)標簽文件      
          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"]
          #獲取標簽對應的類別一共15種
          if temp["defect_name"]=="沾污":
          defect_name = '0'
          elif temp["defect_name"]=="錯花":
          defect_name = '1'
          .......
          #標注格式轉(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ù),并劃分訓練集和驗證集
          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. 模型訓練

          數(shù)據(jù)路徑設置:編輯一個數(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]],
          ...........

          模型訓練

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

          4. 測試模型并生成結果

          detect.py的輸出結果的格式修改成提交結果的格式

          #將輸出結果的格式變成比賽需要提交的格式,并存入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生成鏡像,并提交鏡像,至此就實現(xiàn)了比賽的Baseline了

          四、改進思路

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

          前面我們提到該布匹缺陷檢測任務的難點主要有:

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

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

          解決思路:

          • 過采樣種類較少的樣本
          • 數(shù)據(jù)擴增:在訓練方面,除了常規(guī)的數(shù)據(jù)增強之外,我們觀察到原始的標注存在不準確的情況,為了使網(wǎng)絡適應這種不確定性,我們在訓練時隨機對原始的標注框進行了抖動,是網(wǎng)絡能夠?qū)W習這種不確定性

          2. 缺陷具有極端的長寬比

          解決思路:

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

          3. 小目標問題

          解決思路:

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

          4.漲分Tricks

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

          半監(jiān)督學習

          利用訓練集訓練好的模型預測測試集,將預測結果作為偽標簽加入訓練

          測試增強

          對檢測圖片進行翻折、旋轉(zhuǎn)、色彩增強,然后分別對這些擴增圖片進行預測,將多個預測結果進行融合

          模型集成

          多種模型進行預測,將一張圖片的多個結果進行融合

          閱讀原文可以參與缺陷檢測實踐
          “整理不易,三連
          瀏覽 76
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  黄色电影中文字幕在线观看 | 国产一级黄色A片在线观看 | 人人草人人舔 | 911香蕉视频 | 天天操天天摸天天碰 |