国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

計(jì)算機(jī)設(shè)計(jì)大賽 深度學(xué)習(xí)YOLO抽煙行為檢測 - python opencv

這篇具有很好參考價(jià)值的文章主要介紹了計(jì)算機(jī)設(shè)計(jì)大賽 深度學(xué)習(xí)YOLO抽煙行為檢測 - python opencv。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

1 前言

?? 優(yōu)質(zhì)競賽項(xiàng)目系列,今天要分享的是

?? 基于深度學(xué)習(xí)YOLO抽煙行為檢測

該項(xiàng)目較為新穎,適合作為競賽課題方向,學(xué)長非常推薦!

??學(xué)長這里給一個(gè)題目綜合評分(每項(xiàng)滿分5分)

  • 難度系數(shù):3分
  • 工作量:3分
  • 創(chuàng)新點(diǎn):4分

?? 更多資料, 項(xiàng)目分享:

https://gitee.com/dancheng-senior/postgraduate文章來源地址http://www.zghlxwxcb.cn/news/detail-834837.html

1 課題背景

公共場合抽煙的危害很大,國家也相應(yīng)地出臺了在公共場合禁煙的政策。以前實(shí)行相關(guān)的政策都是靠工作人員巡邏發(fā)現(xiàn)并出言禁止,這樣做效率很低下。計(jì)算機(jī)視覺領(lǐng)域發(fā)展迅速,而抽煙檢測也屬于一種計(jì)算機(jī)視覺目標(biāo)檢測的行為,可以采用目標(biāo)檢測的方法來實(shí)現(xiàn)。目前,目標(biāo)檢測在很多領(lǐng)域都取得顯著成就,但是在抽煙檢測領(lǐng)域方面進(jìn)行研究卻幾乎沒有。該研究可以有效節(jié)省成本,對公共場合禁煙政策的實(shí)行有很大的推動作用。

2 實(shí)現(xiàn)效果

計(jì)算機(jī)設(shè)計(jì)大賽 深度學(xué)習(xí)YOLO抽煙行為檢測 - python opencv,python

計(jì)算機(jī)設(shè)計(jì)大賽 深度學(xué)習(xí)YOLO抽煙行為檢測 - python opencv,python
計(jì)算機(jī)設(shè)計(jì)大賽 深度學(xué)習(xí)YOLO抽煙行為檢測 - python opencv,python

左圖為原圖,右圖為推理后的圖片,以圖片方式展示,視頻流和實(shí)時(shí)流也能達(dá)到這個(gè)效果,由于視頻轉(zhuǎn)GIF大小原因,這里暫不演示。

3 Yolov5算法

3.1 簡介

YOLO系列是基于深度學(xué)習(xí)的回歸方法。該系列陸續(xù)誕生出YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5。YOLOv5算法,它是一種單階段目標(biāo)檢測的算法,該算法可以根據(jù)落地要求靈活地通過chaneel和layer的控制因子來配置和調(diào)節(jié)模型,所以在比賽和落地中應(yīng)用比較多。同時(shí)它有YOLOv5x、YOLOv5l、YOLOv5m、YOLOv5s四種模型。
具有以下優(yōu)點(diǎn):

  • 在pytorch環(huán)境下編寫;
  • 可以很容易編譯成ON?NX和Core ML;
  • 運(yùn)行速度很快,每秒可以達(dá)到140FPS的速度;
  • 模型精度高;
  • 集成了YOLOv3和YOLOv4的部分優(yōu)秀特性,進(jìn)行了推陳出新的改進(jìn)。

3.2 相關(guān)技術(shù)

Mosaic數(shù)據(jù)增強(qiáng)

Mosaic數(shù)據(jù)增強(qiáng)技術(shù)采用了四張圖片的隨機(jī)縮放、隨機(jī)剪裁、隨機(jī)排布的方式對數(shù)據(jù)進(jìn)行拼接,相比CutMix數(shù)據(jù)增強(qiáng)多用了兩張圖片。在目標(biāo)識別過程中,要識別的目標(biāo)有大目標(biāo)、中等目標(biāo)、小目標(biāo),并且三種目標(biāo)的占比例不均衡,其中,小目標(biāo)的數(shù)量是最多的,但是出現(xiàn)的頻率很低,這種情況就會導(dǎo)致在bp時(shí)對小目標(biāo)的優(yōu)化不足,模型正確識別小目標(biāo)的難度比識別中、大目標(biāo)的難度要大很多,于是對于小目標(biāo)來說很容易出現(xiàn)誤檢和漏檢的情況。Mosaic數(shù)據(jù)增強(qiáng)技術(shù)做出改進(jìn)后,上述的問題得到有效的解決。
該技術(shù)的優(yōu)點(diǎn)是:

  • 豐富了數(shù)據(jù)集,采用“三個(gè)隨機(jī)”的方式對數(shù)據(jù)進(jìn)行拼接豐富了檢測的數(shù)據(jù)集,尤其是隨機(jī)縮放增加了很多小目標(biāo),克服了小目標(biāo)的不足,讓網(wǎng)絡(luò)的魯棒性得到提高;
  • 減少GPU的使用,在Mosaic增強(qiáng)訓(xùn)練時(shí),四張圖片拼接在一起,GPU可以直接計(jì)算四張圖片的數(shù)據(jù),讓Mini-batch的大小減少了很多,這使得一個(gè)GPU就可以達(dá)到比較可觀的效果。
    計(jì)算機(jī)設(shè)計(jì)大賽 深度學(xué)習(xí)YOLO抽煙行為檢測 - python opencv,python

自適應(yīng)anchor
自適應(yīng)anchor是check_anchors函數(shù)通過遺傳算法與Kmeans迭代算出的最大可能召回率的anchor組合。在網(wǎng)絡(luò)模型的訓(xùn)練過程中,網(wǎng)絡(luò)在初始化的錨框的基礎(chǔ)上輸出預(yù)測框,然后與真實(shí)框groundtruth進(jìn)行對比,計(jì)算兩個(gè)框之間的差值,再根據(jù)差值進(jìn)行反向更新,迭代網(wǎng)絡(luò)參數(shù),最后求出最佳的錨框值。自適應(yīng)的anchor能夠更好地配合網(wǎng)絡(luò)訓(xùn)練,提高模型的精度,減少對anchor的設(shè)計(jì)難度,具有很好的實(shí)用性。

自適應(yīng)圖片縮放
為了提高模型的推理速度,YOLOv5提出自適應(yīng)圖片縮放,根據(jù)長寬比對圖像進(jìn)行縮放,并添加最少的黑邊,減少計(jì)算量。該方法是用縮放后的長邊減去短邊再對32進(jìn)行取余運(yùn)算,求出padding。在訓(xùn)練時(shí)并沒有采用縮減黑邊的方法,該方法只是在測試模型推理的時(shí)候才使用,這樣提高了目標(biāo)檢測的準(zhǔn)確率和速度。

Focus結(jié)構(gòu)
該結(jié)構(gòu)采用切片操作,將特征切片成四份,每一份將當(dāng)成下采樣的特征,然后在channel維度進(jìn)行concat。例如:原始608 608
3的數(shù)據(jù)圖片,經(jīng)過切片操作先變成304 304 12的特征圖,再經(jīng)過一次32個(gè)卷積核的卷積操作,變成304 304 32的特征圖。
計(jì)算機(jī)設(shè)計(jì)大賽 深度學(xué)習(xí)YOLO抽煙行為檢測 - python opencv,python
計(jì)算機(jī)設(shè)計(jì)大賽 深度學(xué)習(xí)YOLO抽煙行為檢測 - python opencv,python
CSP結(jié)構(gòu)
YOLOv5中的CSP[5]結(jié)構(gòu)應(yīng)用于兩處,一處是CSP1_X結(jié)構(gòu)應(yīng)用于Backbone的主干網(wǎng)絡(luò)中,另一處的CSP2_X結(jié)構(gòu)應(yīng)用于Neck中,用于加強(qiáng)網(wǎng)絡(luò)的特征融合的能力。CSPNet主要從網(wǎng)絡(luò)結(jié)構(gòu)設(shè)計(jì)的角度解決推理中從計(jì)算量很大的問題。該結(jié)構(gòu)的優(yōu)點(diǎn)有:1)增強(qiáng)CNN的學(xué)習(xí)能力,使得模型在輕量化的同時(shí)保持較高的準(zhǔn)確性;2)減低計(jì)算的瓶頸問題;3)減低內(nèi)存的分險(xiǎn)。

PFN+PAN結(jié)構(gòu)
這個(gè)結(jié)構(gòu)是FPN和PAN的聯(lián)合。FPN是自頂向下的,將高層的特征信息通過上采樣的方式進(jìn)行傳遞融合,得到進(jìn)行預(yù)測的特征圖,而PAN正好與FPN的方向是相反的方向,它是自底向上地采取特征信息。兩個(gè)結(jié)構(gòu)各自從不同的主干層對不同的檢測層進(jìn)行參數(shù)聚合。兩個(gè)結(jié)構(gòu)的強(qiáng)強(qiáng)聯(lián)合讓得到的特征圖的特征更加明顯和清楚。

Bounding box的損失函數(shù)
Bounding
box損失函數(shù)[6]增加了相交尺度的衡量方式,有效緩解了當(dāng)兩個(gè)框不相交和兩個(gè)框大小完全相同的兩種特殊情況。因?yàn)楫?dāng)預(yù)測框和目標(biāo)框不相交時(shí),IOU=0,無法反應(yīng)兩個(gè)框距離的遠(yuǎn)近的時(shí)候,此時(shí)的損失函數(shù)不可導(dǎo);兩個(gè)框大小完全相同,兩個(gè)IOU也相同,IOU_LOSS無法區(qū)分以上兩種特殊情況。

nms非極大值抑制
在目標(biāo)檢測過程的后續(xù)處理中,對于大量的目標(biāo)框的篩選問題,通常會進(jìn)行nms操作,以此來達(dá)到一個(gè)不錯(cuò)的效果。YO?LOv5算法同樣采用了加權(quán)的nms操作。

4 數(shù)據(jù)集處理及實(shí)驗(yàn)

數(shù)據(jù)集準(zhǔn)備

由于目前針對吸煙圖片并沒有現(xiàn)成的數(shù)據(jù)集,我們使用Python爬蟲利用關(guān)鍵字在互聯(lián)網(wǎng)上獲得的圖片數(shù)據(jù),編寫程序爬了1w張,篩選下來有近1000張可用,以及其他途徑獲取到的,暫時(shí)可用數(shù)據(jù)集有5k張,

深度學(xué)習(xí)圖像標(biāo)注軟件眾多,按照不同分類標(biāo)準(zhǔn)有多中類型,本文使用LabelImg單機(jī)標(biāo)注軟件進(jìn)行標(biāo)注。LabelImg是基于角點(diǎn)的標(biāo)注方式產(chǎn)生邊界框,對圖片進(jìn)行標(biāo)注得到xml格式的標(biāo)注文件,由于邊界框?qū)z測精度的影響較大因此采用手動標(biāo)注,并沒有使用自動標(biāo)注軟件。

考慮到有的朋友時(shí)間不足,博主提供了標(biāo)注好的數(shù)據(jù)集和訓(xùn)練好的模型,需要請聯(lián)系。

數(shù)據(jù)標(biāo)注簡介

通過pip指令即可安裝

?

pip install labelimg

在命令行中輸入labelimg即可打開

計(jì)算機(jī)設(shè)計(jì)大賽 深度學(xué)習(xí)YOLO抽煙行為檢測 - python opencv,python

5 部分核心代碼

?



    # data/smoke.yaml


    # COCO 2017 dataset http://cocodataset.org
    # Download command: bash yolov5/data/get_coco2017.sh
    # Train command: python train.py --data ./data/coco.yaml
    # Dataset should be placed next to yolov5 folder:
    #   /parent_folder
    #     /coco
    #     /yolov5


    # train and val datasets (image directory or *.txt file with image paths)
    train: data\train.txt  # 上面我們生成的train,根據(jù)自己的路徑進(jìn)行更改
    val: data\test.txt  # 上面我們生成的test
    #test: ../coco/test-dev2017.txt  # 20k images for submission to https://competitions.codalab.org/competitions/20794
    
    # number of classes
    nc: 1   #訓(xùn)練的類別
    
    # class names
    names: ['smoke']
    
    # Print classes
    # with open('data/coco.yaml') as f:
    #   d = yaml.load(f, Loader=yaml.FullLoader)  # dict
    #   for i, x in enumerate(d['names']):
    #     print(i, x)


    # model/yolov5s.yaml

    # parameters
    nc: 1  # number of classes
    depth_multiple: 0.33  # model depth multiple
    width_multiple: 0.50  # layer channel multiple
    
    # anchors
    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
    
    # YOLOv5 backbone
    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]],
       [-1, 1, Conv, [256, 3, 2]],  # 3-P3/8
       [-1, 9, BottleneckCSP, [256]],
       [-1, 1, Conv, [512, 3, 2]],  # 5-P4/16
       [-1, 9, BottleneckCSP, [512]],
       [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32
       [-1, 1, SPP, [1024, [5, 9, 13]]],
      ]
    
    # YOLOv5 head
    head:
      [[-1, 3, BottleneckCSP, [1024, False]],  # 9
    
       [-1, 1, Conv, [512, 1, 1]],
       [-1, 1, nn.Upsample, [None, 2, 'nearest']],
       [[-1, 6], 1, Concat, [1]],  # cat backbone P4
       [-1, 3, BottleneckCSP, [512, False]],  # 13
    
       [-1, 1, Conv, [256, 1, 1]],
       [-1, 1, nn.Upsample, [None, 2, 'nearest']],
       [[-1, 4], 1, Concat, [1]],  # cat backbone P3
       [-1, 3, BottleneckCSP, [256, False]],
       [-1, 1, nn.Conv2d, [na * (nc + 5), 1, 1]],  # 18 (P3/8-small)
    
       [-2, 1, Conv, [256, 3, 2]],
       [[-1, 14], 1, Concat, [1]],  # cat head P4
       [-1, 3, BottleneckCSP, [512, False]],
       [-1, 1, nn.Conv2d, [na * (nc + 5), 1, 1]],  # 22 (P4/16-medium)
    
       [-2, 1, Conv, [512, 3, 2]],
       [[-1, 10], 1, Concat, [1]],  # cat head P5
       [-1, 3, BottleneckCSP, [1024, False]],
       [-1, 1, nn.Conv2d, [na * (nc + 5), 1, 1]],  # 26 (P5/32-large)
    
       [[], 1, Detect, [nc, anchors]],  # Detect(P5, P4, P3)
      ]


    # 訓(xùn)練部分主函數(shù)


    if __name__ == '__main__':
        check_git_status()
        parser = argparse.ArgumentParser()
        parser.add_argument('--epochs', type=int, default=300)
        parser.add_argument('--batch-size', type=int, default=16)
        parser.add_argument('--cfg', type=str, default='models/yolov5s.yaml', help='*.cfg path')
        parser.add_argument('--data', type=str, default='data/smoke.yaml', help='*.data path')
        parser.add_argument('--img-size', nargs='+', type=int, default=[640, 640], help='train,test sizes')
        parser.add_argument('--rect', action='store_true', help='rectangular training')
        parser.add_argument('--resume', action='store_true', help='resume training from last.pt')
        parser.add_argument('--nosave', action='store_true', help='only save final checkpoint')
        parser.add_argument('--notest', action='store_true', help='only test final epoch')
        parser.add_argument('--noautoanchor', action='store_true', help='disable autoanchor check')
        parser.add_argument('--evolve', action='store_true', help='evolve hyperparameters')
        parser.add_argument('--bucket', type=str, default='', help='gsutil bucket')
        parser.add_argument('--cache-images', action='store_true', help='cache images for faster training')
        parser.add_argument('--weights', type=str, default='', help='initial weights path')
        parser.add_argument('--name', default='', help='renames results.txt to results_name.txt if supplied')
        parser.add_argument('--device', default='0', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
        parser.add_argument('--adam', action='store_true', help='use adam optimizer')
        parser.add_argument('--multi-scale', action='store_true', help='vary img-size +/- 50%')
        parser.add_argument('--single-cls', action='store_true', help='train as single-class dataset')
        opt = parser.parse_args()
        opt.weights = last if opt.resume else opt.weights
        opt.cfg = check_file(opt.cfg)  # check file
        opt.data = check_file(opt.data)  # check file
        print(opt)
        opt.img_size.extend([opt.img_size[-1]] * (2 - len(opt.img_size)))  # extend to 2 sizes (train, test)
        device = torch_utils.select_device(opt.device, apex=mixed_precision, batch_size=opt.batch_size)
        if device.type == 'cpu':
            mixed_precision = False
    
        # Train
        if not opt.evolve:
            tb_writer = SummaryWriter(comment=opt.name)
            print('Start Tensorboard with "tensorboard --logdir=runs", view at http://localhost:6006/')
            train(hyp)
    
        # Evolve hyperparameters (optional)
        else:
            tb_writer = None
            opt.notest, opt.nosave = True, True  # only test/save final epoch
            if opt.bucket:
                os.system('gsutil cp gs://%s/evolve.txt .' % opt.bucket)  # download evolve.txt if exists
    
            for _ in range(10):  # generations to evolve
                if os.path.exists('evolve.txt'):  # if evolve.txt exists: select best hyps and mutate
                    # Select parent(s)
                    parent = 'single'  # parent selection method: 'single' or 'weighted'
                    x = np.loadtxt('evolve.txt', ndmin=2)
                    n = min(5, len(x))  # number of previous results to consider
                    x = x[np.argsort(-fitness(x))][:n]  # top n mutations
                    w = fitness(x) - fitness(x).min()  # weights
                    if parent == 'single' or len(x) == 1:
                        # x = x[random.randint(0, n - 1)]  # random selection
                        x = x[random.choices(range(n), weights=w)[0]]  # weighted selection
                    elif parent == 'weighted':
                        x = (x * w.reshape(n, 1)).sum(0) / w.sum()  # weighted combination
    
                    # Mutate
                    mp, s = 0.9, 0.2  # mutation probability, sigma
                    npr = np.random
                    npr.seed(int(time.time()))
                    g = np.array([1, 1, 1, 1, 1, 1, 1, 0, .1, 1, 0, 1, 1, 1, 1, 1, 1, 1])  # gains
                    ng = len(g)
                    v = np.ones(ng)
                    while all(v == 1):  # mutate until a change occurs (prevent duplicates)
                        v = (g * (npr.random(ng) < mp) * npr.randn(ng) * npr.random() * s + 1).clip(0.3, 3.0)
                    for i, k in enumerate(hyp.keys()):  # plt.hist(v.ravel(), 300)
                        hyp[k] = x[i + 7] * v[i]  # mutate
    
                # Clip to limits
                keys = ['lr0', 'iou_t', 'momentum', 'weight_decay', 'hsv_s', 'hsv_v', 'translate', 'scale', 'fl_gamma']
                limits = [(1e-5, 1e-2), (0.00, 0.70), (0.60, 0.98), (0, 0.001), (0, .9), (0, .9), (0, .9), (0, .9), (0, 3)]
                for k, v in zip(keys, limits):
                    hyp[k] = np.clip(hyp[k], v[0], v[1])
    
                # Train mutation
                results = train(hyp.copy())
    
                # Write mutation results
                print_mutation(hyp, results, opt.bucket)
    
                # Plot results
                # plot_evolution_results(hyp)



?

6 最后

?? 更多資料, 項(xiàng)目分享:

https://gitee.com/dancheng-senior/postgraduate

到了這里,關(guān)于計(jì)算機(jī)設(shè)計(jì)大賽 深度學(xué)習(xí)YOLO抽煙行為檢測 - python opencv的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包