YOLO Vision 2026:

YOLOv7: Eğitilebilir 'Bag-of-Freebies'#

YOLOv7, Temmuz 2022'de yayınlandığı dönemde gerçek zamanlı nesne tespiti alanında önemli bir ilerlemeydi. V100 GPU üzerinde %56.8 AP elde ederek çıktığı zaman yeni kıyas ölçütleri belirledi. YOLOv7, hız ve doğruluk açısından YOLOR, YOLOX, Scaled-YOLOv4 ve YOLOv5 gibi dönemin nesne dedektörlerini geride bıraktı. Model, başka hiçbir veri seti veya önceden eğitilmiş ağırlık kullanılmadan sıfırdan MS COCO veri seti üzerinde eğitilir. YOLOv7'nin kaynak kodu GitHub üzerinde mevcuttur. YOLO11 ve YOLO26 gibi daha yeni modellerin o zamandan beri gelişmiş verimlilikle daha yüksek doğruluk elde ettiğini unutma.

YOLOv7 comparison with SOTA object detectors

SOTA nesne tespit edicilerinin karşılaştırması#

YOLO karşılaştırma tablosundaki sonuçlardan, önerilen yöntemin hız-doğruluk dengesi açısından kapsamlı bir şekilde en iyisi olduğunu biliyoruz. YOLOv7-tiny-SiLU ile YOLOv5-N (r6.1) modelini karşılaştırırsak, yöntemimiz 127 fps daha hızlı ve AP açısından %10,7 daha doğrudur. Ayrıca, YOLOv7 161 fps kare hızında %51,4 AP değerine sahipken, aynı AP'ye sahip PPYOLOE-L modeli yalnızca 78 fps kare hızına sahiptir. Parametre kullanımı açısından YOLOv7, PPYOLOE-L'den %41 daha azdır.

114 fps çıkarım hızına sahip YOLOv7-X'i 99 fps çıkarım hızına sahip YOLOv5-L (r6.1) ile karşılaştırırırsak, YOLOv7-X AP'yi %3.9 oranında iyileştirebilir. YOLOv7-X benzer ölçekteki YOLOv5-X (r6.1) ile karşılaştırılırsa, YOLOv7-X'in çıkarım hızı 31 fps daha hızlıdır. Ek olarak, parametre ve hesaplama miktarı açısından YOLOv7-X, YOLOv5-X (r6.1) ile karşılaştırıldığında parametrelerde %22 ve hesaplamada %8 azalma sağlar, ancak AP'yi %2.2 oranında artırır (Kaynak).

Performans
ModelParametreler
(M)
FLOPs
(G)
Boyut
(piksel)
FPSAPtest / val
50-95
APtest
50
APtest
75
APtest
S
APtest
M
APtest
L
YOLOX-S9.026.864010240.5% / 40.5%-----
YOLOX-M25.373.86408147.2% / 46.9%-----
YOLOX-L54.2155.66406950.1% / 49.7%-----
YOLOX-X99.1281.96405851.5% / 51.1%-----
PPYOLOE-S7.917.464020843.1% / 42.7%60.5%46.6%23.2%46.4%56.9%
PPYOLOE-M23.449.964012348.9% / 48.6%66.5%53.0%28.6%52.9%63.8%
PPYOLOE-L52.2110.16407851.4% / 50.9%68.9%55.6%31.4%55.3%66.1%
PPYOLOE-X98.4206.66404552.2% / 51.9%69.9%56.5%33.3%56.3%66.4%
YOLOv5-N (r6.1)1.94.5640159- / 28.0%-----
YOLOv5-S (r6.1)7.216.5640156- / 37.4%-----
YOLOv5-M (r6.1)21.249.0640122- / 45.4%-----
YOLOv5-L (r6.1)46.5109.164099- / 49.0%-----
YOLOv5-X (r6.1)86.7205.764083- / 50.7%-----
YOLOR-CSP52.9120.464010651.1% / 50.8%69.6%55.7%31.7%55.3%64.7%
YOLOR-CSP-X96.9226.86408753.0% / 52.7%71.4%57.9%33.7%57.1%66.8%
YOLOv7-tiny-SiLU6.213.864028638.7% / 38.7%56.7%41.7%18.8%42.4%51.9%
YOLOv736.9104.764016151.4% / 51.2%69.7%55.9%31.8%55.5%65.0%
YOLOv7-X71.3189.964011453.1% / 52.9%71.2%57.8%33.8%57.1%67.4%
YOLOv5-N6 (r6.1)3.218.41280123- / 36.0%-----
YOLOv5-S6 (r6.1)12.667.21280122- / 44.8%-----
YOLOv5-M6 (r6.1)35.7200.0128090- / 51.3%-----
YOLOv5-L6 (r6.1)76.8445.6128063- / 53.7%-----
YOLOv5-X6 (r6.1)140.7839.2128038- / 55.0%-----
YOLOR-P637.2325.612807653.9% / 53.5%71.4%58.9%36.1%57.7%65.6%
YOLOR-W679.8453.212806655.2% / 54.8%72.7%60.5%37.7%59.1%67.1%
YOLOR-E6115.8683.212804555.8% / 55.7%73.4%61.1%38.4%59.7%67.7%
YOLOR-D6151.7935.612803456.5% / 56.1%74.1%61.9%38.9%60.4%68.7%
YOLOv7-W670.4360.012808454.9% / 54.6%72.6%60.1%37.3%58.7%67.1%
YOLOv7-E697.2515.212805656.0% / 55.9%73.5%61.2%38.0%59.9%68.4%
YOLOv7-D6154.7806.812804456.6% / 56.3%74.0%61.8%38.8%60.1%69.5%
YOLOv7-E6E151.7843.212803656.8% / 56.8%74.4%62.1%39.3%60.5%69.0%

Genel Bakış#

Gerçek zamanlı nesne tespiti; çoklu nesne takibi, otonom sürüş, robotik ve tıbbi görüntü analizi dahil olmak üzere birçok computer vision sisteminde önemli bir bileşendir. Son yıllarda gerçek zamanlı nesne tespiti geliştirme çalışmaları, verimli mimariler tasarlamaya ve çeşitli CPU, GPU ve sinirsel işleme birimlerinin (NPU) çıkarım hızını iyileştirmeye odaklanmıştır. YOLOv7, uç cihazlardan buluta kadar hem mobil GPU'ları hem de GPU cihazlarını destekler.

Mimari optimizasyona odaklanan geleneksel gerçek zamanlı nesne dedektörlerinin aksine YOLOv7, eğitim sürecinin optimizasyonuna odaklanır. Bu, "eğitilebilir ücretsiz avantajlar paketi" (trainable bag-of-freebies) olarak bilinen bir kavram olan, çıkarım maliyetini artırmadan nesne tespiti doğruluğunu iyileştirmek için tasarlanmış modülleri ve optimizasyon yöntemlerini içerir.

Temel Özellikler#

YOLOv7 birkaç temel özellik sunar:

  1. Model Yeniden Parametrelendirme: YOLOv7, gradyan yayılım yolu kavramıyla farklı ağlardaki katmanlara uygulanabilir bir strateji olan planlı bir yeniden parametrelendirilmiş model önerir.

  2. Dinamik Etiket Atama: Çoklu çıktı katmanlarına sahip modelin eğitimi yeni bir sorun ortaya çıkarır: "Farklı dalların çıktıları için dinamik hedefler nasıl atanır?" Bu sorunu çözmek için YOLOv7, kabadan inceye (coarse-to-fine) lider yönlendirmeli etiket atama adında yeni bir etiket atama yöntemi sunar.

  3. Genişletilmiş ve Bileşik Ölçekleme: YOLOv7, parametreleri ve hesaplamayı etkili bir şekilde kullanabilen gerçek zamanlı nesne dedektörü için "genişletme" ve "bileşik ölçekleme" yöntemleri önerir.

  4. Verimlilik: YOLOv7 tarafından önerilen yöntem, en gelişmiş gerçek zamanlı nesne dedektörünün parametrelerini yaklaşık %40, hesaplamasını ise %50 oranında etkili bir şekilde azaltabilir; ayrıca daha hızlı çıkarım hızına ve daha yüksek tespit doğruluğuna sahiptir.

Kullanım Örnekleri#

Ultralytics, yolov7.pt önceden eğitilmiş ağırlıklarını veya ultralytics/cfg/models/v7/ YAML dosyalarını yayınlamaz ve YOLOv7 için yerel PyTorch eğitimi ile çıkarımı Ultralytics Python paketi tarafından desteklenmez. Ancak, aşağıda gösterildiği gibi ana YOLOv7 deposunda eğitilmiş bir YOLOv7 kontrol noktasını ONNX veya TensorRT'ye dışarı aktararak Ultralytics'e getirebilirsin.

ONNX Dışa Aktarımı#

YOLOv7 ONNX modelini Ultralytics ile kullanmak için:

  1. (İsteğe bağlı) Ultralytics'i kur ve gerekli bağımlılıkların otomatik olarak yüklenmesi için bir ONNX modelini dışa aktar:

    pip install ultralytics
    yolo export model=yolo26n.pt format=onnx
  2. YOLOv7 deposundaki dışarı aktarıcıyı kullanarak istediğin YOLOv7 modelini dışarı aktar:

    git clone https://github.com/WongKinYiu/yolov7
    cd yolov7
    python export.py --weights yolov7-tiny.pt --grid --end2end --simplify --topk-all 100 --iou-thres 0.65 --conf-thres 0.35 --img-size 640 640 --max-wh 640
  3. Aşağıdaki betiği kullanarak ONNX model grafiğini Ultralytics ile uyumlu olacak şekilde değiştir:

    import numpy as np
    import onnx
    from onnx import helper, numpy_helper
    
    # Load the ONNX model
    model_path = "yolov7/yolov7-tiny.onnx"  # Replace with your model path
    model = onnx.load(model_path)
    graph = model.graph
    
    # Fix input shape to batch size 1
    input_shape = graph.input[0].type.tensor_type.shape
    input_shape.dim[0].dim_value = 1
    
    # Define the output of the original model
    original_output_name = graph.output[0].name
    
    # Create slicing nodes
    sliced_output_name = f"{original_output_name}_sliced"
    
    # Define initializers for slicing (remove the first value)
    start = numpy_helper.from_array(np.array([1], dtype=np.int64), name="slice_start")
    end = numpy_helper.from_array(np.array([7], dtype=np.int64), name="slice_end")
    axes = numpy_helper.from_array(np.array([1], dtype=np.int64), name="slice_axes")
    steps = numpy_helper.from_array(np.array([1], dtype=np.int64), name="slice_steps")
    
    graph.initializer.extend([start, end, axes, steps])
    
    slice_node = helper.make_node(
        "Slice",
        inputs=[original_output_name, "slice_start", "slice_end", "slice_axes", "slice_steps"],
        outputs=[sliced_output_name],
        name="SliceNode",
    )
    graph.node.append(slice_node)
    
    # Define segment slicing
    seg1_start = numpy_helper.from_array(np.array([0], dtype=np.int64), name="seg1_start")
    seg1_end = numpy_helper.from_array(np.array([4], dtype=np.int64), name="seg1_end")
    seg2_start = numpy_helper.from_array(np.array([4], dtype=np.int64), name="seg2_start")
    seg2_end = numpy_helper.from_array(np.array([5], dtype=np.int64), name="seg2_end")
    seg3_start = numpy_helper.from_array(np.array([5], dtype=np.int64), name="seg3_start")
    seg3_end = numpy_helper.from_array(np.array([6], dtype=np.int64), name="seg3_end")
    
    graph.initializer.extend([seg1_start, seg1_end, seg2_start, seg2_end, seg3_start, seg3_end])
    
    # Create intermediate tensors for segments
    segment_1_name = f"{sliced_output_name}_segment1"
    segment_2_name = f"{sliced_output_name}_segment2"
    segment_3_name = f"{sliced_output_name}_segment3"
    
    # Add segment slicing nodes
    graph.node.extend(
        [
            helper.make_node(
                "Slice",
                inputs=[sliced_output_name, "seg1_start", "seg1_end", "slice_axes", "slice_steps"],
                outputs=[segment_1_name],
                name="SliceSegment1",
            ),
            helper.make_node(
                "Slice",
                inputs=[sliced_output_name, "seg2_start", "seg2_end", "slice_axes", "slice_steps"],
                outputs=[segment_2_name],
                name="SliceSegment2",
            ),
            helper.make_node(
                "Slice",
                inputs=[sliced_output_name, "seg3_start", "seg3_end", "slice_axes", "slice_steps"],
                outputs=[segment_3_name],
                name="SliceSegment3",
            ),
        ]
    )
    
    # Concatenate the segments
    concat_output_name = f"{sliced_output_name}_concat"
    concat_node = helper.make_node(
        "Concat",
        inputs=[segment_1_name, segment_3_name, segment_2_name],
        outputs=[concat_output_name],
        axis=1,
        name="ConcatSwapped",
    )
    graph.node.append(concat_node)
    
    # Reshape to [1, -1, 6]
    reshape_shape = numpy_helper.from_array(np.array([1, -1, 6], dtype=np.int64), name="reshape_shape")
    graph.initializer.append(reshape_shape)
    
    final_output_name = f"{concat_output_name}_batched"
    reshape_node = helper.make_node(
        "Reshape",
        inputs=[concat_output_name, "reshape_shape"],
        outputs=[final_output_name],
        name="AddBatchDimension",
    )
    graph.node.append(reshape_node)
    
    # Get the shape of the reshaped tensor
    shape_node_name = f"{final_output_name}_shape"
    shape_node = helper.make_node(
        "Shape",
        inputs=[final_output_name],
        outputs=[shape_node_name],
        name="GetShapeDim",
    )
    graph.node.append(shape_node)
    
    # Extract the second dimension
    dim_1_index = numpy_helper.from_array(np.array([1], dtype=np.int64), name="dim_1_index")
    graph.initializer.append(dim_1_index)
    
    second_dim_name = f"{final_output_name}_dim1"
    gather_node = helper.make_node(
        "Gather",
        inputs=[shape_node_name, "dim_1_index"],
        outputs=[second_dim_name],
        name="GatherSecondDim",
    )
    graph.node.append(gather_node)
    
    # Subtract from 100 to determine how many values to pad
    target_size = numpy_helper.from_array(np.array([100], dtype=np.int64), name="target_size")
    graph.initializer.append(target_size)
    
    pad_size_name = f"{second_dim_name}_padsize"
    sub_node = helper.make_node(
        "Sub",
        inputs=["target_size", second_dim_name],
        outputs=[pad_size_name],
        name="CalculatePadSize",
    )
    graph.node.append(sub_node)
    
    # Build the [2, 3] pad array:
    # 1st row -> [0, 0, 0] (no padding at the start of any dim)
    # 2nd row -> [0, pad_size, 0] (pad only at the end of the second dim)
    pad_starts = numpy_helper.from_array(np.array([0, 0, 0], dtype=np.int64), name="pad_starts")
    graph.initializer.append(pad_starts)
    
    zero_scalar = numpy_helper.from_array(np.array([0], dtype=np.int64), name="zero_scalar")
    graph.initializer.append(zero_scalar)
    
    pad_ends_name = "pad_ends"
    concat_pad_ends_node = helper.make_node(
        "Concat",
        inputs=["zero_scalar", pad_size_name, "zero_scalar"],
        outputs=[pad_ends_name],
        axis=0,
        name="ConcatPadEnds",
    )
    graph.node.append(concat_pad_ends_node)
    
    pad_values_name = "pad_values"
    concat_pad_node = helper.make_node(
        "Concat",
        inputs=["pad_starts", pad_ends_name],
        outputs=[pad_values_name],
        axis=0,
        name="ConcatPadStartsEnds",
    )
    graph.node.append(concat_pad_node)
    
    # Create Pad operator to pad with zeros
    pad_output_name = f"{final_output_name}_padded"
    pad_constant_value = numpy_helper.from_array(
        np.array([0.0], dtype=np.float32),
        name="pad_constant_value",
    )
    graph.initializer.append(pad_constant_value)
    
    pad_node = helper.make_node(
        "Pad",
        inputs=[final_output_name, pad_values_name, "pad_constant_value"],
        outputs=[pad_output_name],
        mode="constant",
        name="PadToFixedSize",
    )
    graph.node.append(pad_node)
    
    # Update the graph's final output to [1, 100, 6]
    new_output_type = onnx.helper.make_tensor_type_proto(
        elem_type=graph.output[0].type.tensor_type.elem_type, shape=[1, 100, 6]
    )
    new_output = onnx.helper.make_value_info(name=pad_output_name, type_proto=new_output_type)
    
    # Replace the old output with the new one
    graph.output.pop()
    graph.output.extend([new_output])
    
    # Save the modified model
    onnx.save(model, "yolov7-ultralytics.onnx")
  4. Ardından değiştirilmiş ONNX modelini yükleyebilir ve Ultralytics içinde normal bir şekilde çıkarım çalıştırabilirsin:

    from ultralytics import ASSETS, YOLO
    
    model = YOLO("yolov7-ultralytics.onnx", task="detect")
    
    results = model(ASSETS / "bus.jpg")

TensorRT Dışa Aktarımı#

  1. ONNX Dışa Aktarımı bölümündeki 1-2 adımlarını takip et.

  2. TensorRT Python paketini yükle:

    pip install tensorrt
  3. Değiştirilmiş ONNX modelini TensorRT motoruna dönüştürmek için aşağıdaki betiği çalıştır:

    from ultralytics.utils.export import export_engine
    
    export_engine("yolov7-ultralytics.onnx", half=True)
  4. Modeli Ultralytics içinde yükle ve çalıştır:

    from ultralytics import ASSETS, YOLO
    
    model = YOLO("yolov7-ultralytics.engine", task="detect")
    
    results = model(ASSETS / "bus.jpg")

Alıntılar ve Teşekkür#

Gerçek zamanlı nesne tespiti alanına yaptıkları önemli katkılardan dolayı YOLOv7 yazarlarına teşekkür ederiz:

Alıntı
@inproceedings{wang2023yolov7,
  title={YOLOv7: Trainable Bag-of-Freebies Sets New State-of-the-Art for Real-Time Object Detectors},
  author={Wang, Chien-Yao and Bochkovskiy, Alexey and Liao, Hong-Yuan Mark},
  booktitle={Proceedings of the IEEE/CVF conference on Computer Vision and Pattern Recognition (CVPR)},
  pages={7464--7475},
  year={2023}
}

Resmi YOLOv7 makalesi CVF 2023 Açık Erişim içinde yayınlandı ve arXiv üzerinde bir ön baskısı bulunmaktadır. Yazarlar çalışmalarını halka açık hale getirdiler ve kod tabanına GitHub üzerinden erişilebilir. Alanı ilerlettikleri ve çalışmalarını daha geniş topluluk için erişilebilir kıldıkları için çabalarını takdir ediyoruz.

SSS#

YOLOv7 nedir ve gerçek zamanlı nesne tespitinde neden bir çığır açan gelişme olarak kabul edilir?#

YOLOv7, Temmuz 2022'de yayınlanan, çıktığı dönemde mükemmel hız ve doğruluk elde eden önemli bir gerçek zamanlı nesne tespiti modeliydi. Hem parametre kullanımı hem de çıkarım hızı açısından YOLOX, YOLOv5 ve PPYOLOE gibi dönemin modellerini geride bıraktı. YOLOv7'nin ayırt edici özellikleri arasında, çıkarım maliyetlerini artırmadan performansını optimize eden model yeniden parametrelendirmesi ve dinamik etiket ataması yer alır. Mimarisi ve diğer güncel nesne dedektörleriyle karşılaştırma ölçütleri hakkında daha fazla teknik detay için YOLOv7 makalesine göz at.

YOLOv7, YOLOv4 ve YOLOv5 gibi önceki YOLO modellerine göre nasıl bir iyileştirme sağlıyor?#

YOLOv7, eğitim sürecini geliştiren ve çıkarım doğruluğunu artıran model yeniden parametrelendirmesi ve dinamik etiket ataması dahil olmak üzere çeşitli yenilikler sunar. YOLOv5 ile karşılaştırıldığında YOLOv7 hızı ve doğruluğu önemli ölçüde artırır. Örneğin, YOLOv7-X, YOLOv5-X ile karşılaştırıldığında doğruluğu %2.2 oranında artırır ve parametreleri %22 oranında azaltır. Ayrıntılı karşılaştırmalar YOLOv7 comparison with SOTA object detectors performans tablosunda bulunabilir.

YOLOv7'yi Ultralytics araçları ve platformları ile kullanabilir miyim?#

Şu itibarıyla Ultralytics yalnızca YOLOv7 ONNX ve TensorRT çıkarımını desteklemektedir. YOLOv7'nin ONNX ve TensorRT olarak dışarı aktarılan versiyonunu Ultralytics ile çalıştırmak için Kullanım Örnekleri bölümünü kontrol et.

Kendi veri setimi kullanarak özel bir YOLOv7 modelini nasıl eğitebilirim?#

Özel bir YOLOv7 modelini kurmak ve eğitmek için şu adımları izle:

  1. YOLOv7 deposunu klonla:

    git clone https://github.com/WongKinYiu/yolov7
  2. Klonlanan dizine git ve bağımlılıkları yükle:

    cd yolov7
    pip install -r requirements.txt
  3. Veri setini haznele ve depoda sağlanan kullanım talimatlarına göre model parametrelerini yapılandır. Daha fazla rehberlik için en son bilgi ve güncellemeler amacıyla YOLOv7 GitHub deposunu ziyaret et.

  4. Eğitimden sonra, Kullanım Örnekleri bölümünde gösterildiği gibi modeli Ultralytics'te kullanmak üzere ONNX veya TensorRT formatına dışarı aktarabilirsin.

YOLOv7'de sunulan temel özellikler ve optimizasyonlar nelerdir?#

YOLOv7, gerçek zamanlı nesne tespitinde devrim yaratan çeşitli temel özellikler sunar:

  • Model Yeniden Parametrelendirme: Gradyan yayılım yollarını optimize ederek modelin performansını artırır.
  • Dinamik Etiket Atama: Farklı dallardaki çıktılar için dinamik hedefler atamak amacıyla kabadan inceye lider yönlendirmeli bir yöntem kullanır ve doğruluğu iyileştirir.
  • Genişletilmiş ve Bileşik Ölçekleme: Modeli çeşitli gerçek zamanlı uygulamalar için ölçeklendirmek amacıyla parametreleri ve hesaplamayı verimli bir şekilde kullanır.
  • Verimlilik: Diğer en gelişmiş modellere kıyasla parametre sayısını %40, hesaplamayı ise %50 oranında azaltırken daha hızlı çıkarım hızlarına ulaşır.

Bu özellikler hakkında daha fazla ayrıntı için YOLOv7 Genel Bakış bölümüne bakın.

Yorumlar