YOLOv7: Eğitilebilir Bag-of-Freebies
Temmuz 2022'de yayınlanan YOLOv7, yayınlandığı dönemde gerçek zamanlı nesne tespiti alanında önemli bir ilerlemeydi. GPU V100 üzerinde %56,8 AP elde ederek tanıtıldığında yeni kıyaslamalar belirledi. YOLOv7, hız ve doğruluk açısından YOLOR, YOLOX, Scaled-YOLOv4 ve YOLOv5 gibi güncel nesne tespit modellerinden daha iyi performans gösterdi. Model, başka hiçbir veri kümesi veya önceden eğitilmiş ağırlık kullanılmadan sıfırdan MS COCO veri kümesi üzerinde eğitilmiştir. YOLOv7 için kaynak kodu GitHub'da mevcuttur. YOLO11 ve YOLO26 gibi daha yeni modellerin o zamandan beri gelişmiş verimlilikle daha yüksek doğruluk elde ettiğini unutma.

SOTA nesne tespit modellerinin karşılaştırması
YOLO karşılaştırma tablosundaki sonuçlardan, önerilen yöntemin kapsamlı bir şekilde en iyi hız-doğruluk dengesine sahip olduğunu görüyoruz. YOLOv7-tiny-SiLU ile YOLOv5-N (r6.1) modelini karşılaştırırsak, yöntemimiz 127 fps daha hızlı ve AP üzerinde %10,7 daha doğru sonuç veriyor. Ayrıca, YOLOv7 161 fps kare hızında %51,4 AP değerine sahipken, aynı AP'ye sahip PPYOLOE-L yalnızca 78 fps kare hızına sahip. Parametre kullanımı açısından YOLOv7, PPYOLOE-L'den %41 daha düşük.
114 fps çıkarım hızı olan YOLOv7-X'i, 99 fps çıkarım hızı olan YOLOv5-L (r6.1) ile karşılaştırırsak, YOLOv7-X AP'yi %3,9 oranında artırabiliyor. YOLOv7-X, benzer ölçekteki YOLOv5-X (r6.1) ile karşılaştırıldığında, YOLOv7-X'in çıkarım hızı 31 fps daha hızlıdır. Ayrıca, parametre miktarı ve hesaplama açısından YOLOv7-X, YOLOv5-X (r6.1)'e kıyasla parametreleri %22 ve hesaplamayı %8 oranında azaltırken AP'yi %2,2 artırıyor (Kaynak).
| Model | Parametre (M) | FLOPs (G) | Boyut (piksel) | FPS | APtest / val 50-95 | APtest 50 | APtest 75 | APtest S | APtest M | APtest L |
|---|---|---|---|---|---|---|---|---|---|---|
| YOLOX-S | 9.0 | 26.8 | 640 | 102 | 40.5% / 40.5% | - | - | - | - | - |
| YOLOX-M | 25.3 | 73.8 | 640 | 81 | 47.2% / 46.9% | - | - | - | - | - |
| YOLOX-L | 54.2 | 155.6 | 640 | 69 | 50.1% / 49.7% | - | - | - | - | - |
| YOLOX-X | 99.1 | 281.9 | 640 | 58 | 51.5% / 51.1% | - | - | - | - | - |
| PPYOLOE-S | 7.9 | 17.4 | 640 | 208 | 43.1% / 42.7% | 60.5% | 46.6% | 23.2% | 46.4% | 56.9% |
| PPYOLOE-M | 23.4 | 49.9 | 640 | 123 | 48.9% / 48.6% | 66.5% | 53.0% | 28.6% | 52.9% | 63.8% |
| PPYOLOE-L | 52.2 | 110.1 | 640 | 78 | 51.4% / 50.9% | 68.9% | 55.6% | 31.4% | 55.3% | 66.1% |
| PPYOLOE-X | 98.4 | 206.6 | 640 | 45 | 52.2% / 51.9% | 69.9% | 56.5% | 33.3% | 56.3% | 66.4% |
| YOLOv5-N (r6.1) | 1.9 | 4.5 | 640 | 159 | - / 28.0% | - | - | - | - | - |
| YOLOv5-S (r6.1) | 7.2 | 16.5 | 640 | 156 | - / 37.4% | - | - | - | - | - |
| YOLOv5-M (r6.1) | 21.2 | 49.0 | 640 | 122 | - / 45.4% | - | - | - | - | - |
| YOLOv5-L (r6.1) | 46.5 | 109.1 | 640 | 99 | - / 49.0% | - | - | - | - | - |
| YOLOv5-X (r6.1) | 86.7 | 205.7 | 640 | 83 | - / 50.7% | - | - | - | - | - |
| YOLOR-CSP | 52.9 | 120.4 | 640 | 106 | 51.1% / 50.8% | 69.6% | 55.7% | 31.7% | 55.3% | 64.7% |
| YOLOR-CSP-X | 96.9 | 226.8 | 640 | 87 | 53.0% / 52.7% | 71.4% | 57.9% | 33.7% | 57.1% | 66.8% |
| YOLOv7-tiny-SiLU | 6.2 | 13.8 | 640 | 286 | 38.7% / 38.7% | 56.7% | 41.7% | 18.8% | 42.4% | 51.9% |
| YOLOv7 | 36.9 | 104.7 | 640 | 161 | 51.4% / 51.2% | 69.7% | 55.9% | 31.8% | 55.5% | 65.0% |
| YOLOv7-X | 71.3 | 189.9 | 640 | 114 | 53.1% / 52.9% | 71.2% | 57.8% | 33.8% | 57.1% | 67.4% |
| YOLOv5-N6 (r6.1) | 3.2 | 18.4 | 1280 | 123 | - / 36.0% | - | - | - | - | - |
| YOLOv5-S6 (r6.1) | 12.6 | 67.2 | 1280 | 122 | - / 44.8% | - | - | - | - | - |
| YOLOv5-M6 (r6.1) | 35.7 | 200.0 | 1280 | 90 | - / 51.3% | - | - | - | - | - |
| YOLOv5-L6 (r6.1) | 76.8 | 445.6 | 1280 | 63 | - / 53.7% | - | - | - | - | - |
| YOLOv5-X6 (r6.1) | 140.7 | 839.2 | 1280 | 38 | - / 55.0% | - | - | - | - | - |
| YOLOR-P6 | 37.2 | 325.6 | 1280 | 76 | 53.9% / 53.5% | 71.4% | 58.9% | 36.1% | 57.7% | 65.6% |
| YOLOR-W6 | 79.8 | 453.2 | 1280 | 66 | 55.2% / 54.8% | 72.7% | 60.5% | 37.7% | 59.1% | 67.1% |
| YOLOR-E6 | 115.8 | 683.2 | 1280 | 45 | 55.8% / 55.7% | 73.4% | 61.1% | 38.4% | 59.7% | 67.7% |
| YOLOR-D6 | 151.7 | 935.6 | 1280 | 34 | %56.5 / %56.1 | %74.1 | %61.9 | %38.9 | %60.4 | %68.7 |
| YOLOv7-W6 | 70.4 | 360.0 | 1280 | 84 | %54.9 / %54.6 | %72.6 | %60.1 | %37.3 | %58.7 | 67.1% |
| YOLOv7-E6 | 97.2 | 515.2 | 1280 | 56 | %56.0 / %55.9 | %73.5 | %61.2 | %38.0 | %59.9 | %68.4 |
| YOLOv7-D6 | 154.7 | 806.8 | 1280 | 44 | %56.6 / %56.3 | %74.0 | %61.8 | %38.8 | %60.1 | %69.5 |
| YOLOv7-E6E | 151.7 | 843.2 | 1280 | 36 | %56.8 / %56.8 | %74.4 | %62.1 | %39.3 | %60.5 | %69.0 |
Genel Bakış
Real-time object detection is an important component in many computer vision systems, including multi-object tracking, autonomous driving, robotics, and medical image analysis. In recent years, real-time object detection development has focused on designing efficient architectures and improving the inference speed of various CPUs, GPUs, and neural processing units (NPUs). YOLOv7 supports both mobile GPU and GPU devices, from the edge to the cloud.
Mimari optimizasyona odaklanan geleneksel gerçek zamanlı nesne dedektörlerinin aksine YOLOv7, eğitim sürecinin optimizasyonuna odaklanmayı getirir. Buna, çıkarım maliyetini artırmadan nesne tespiti doğruluğunu artırmak için tasarlanmış modüller ve optimizasyon yöntemleri dahildir; bu kavram "eğitilebilir bedava hediyeler çantası" (trainable bag-of-freebies) olarak bilinir.
Temel Özellikler
YOLOv7 birkaç temel özellik sunar:
-
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.
-
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, kaba-dan-inceye lider kılavuzlu etiket atama adlı yeni bir etiket atama yöntemi sunar.
-
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.
-
Verimlilik: YOLOv7 tarafından önerilen yöntem, en gelişmiş gerçek zamanlı nesne dedektörünün parametrelerini yaklaşık %40 ve hesaplamasını %50 oranında etkili bir şekilde azaltabilir ve 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 ve çıkarımı, Ultralytics Python paketi tarafından desteklenmez. Ancak, aşağıda gösterildiği gibi yukarı yönlü YOLOv7 deposunda eğitilmiş bir YOLOv7 kontrol noktasını, ONNX veya TensorRT'ye aktararak Ultralytics'e getirebilirsin.
ONNX Dışa Aktarma
YOLOv7 ONNX modelini Ultralytics ile kullanmak için:
-
(İsteğe bağlı) Gerekli bağımlılıkların otomatik olarak yüklenmesi için Ultralytics'i kur ve bir ONNX modelini dışa aktar:
pip install ultralytics yolo export model=yolo26n.pt format=onnx -
YOLOv7 deposundaki dışa aktarıcıyı kullanarak istediğin YOLOv7 modelini dışa 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 -
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") -
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 Aktarma
-
ONNX Dışa Aktarma bölümündeki 1-2 numaralı adımları izle.
-
TensorRTPython paketini yükle:pip install tensorrt -
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) -
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:
@article{wang2022yolov7,
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},
journal={arXiv preprint arXiv:2207.02696},
year={2022}
}Orijinal YOLOv7 makalesi arXiv üzerinde bulunabilir. Yazarlar çalışmalarını herkese açık hale getirmişlerdir ve kod tabanına GitHub üzerinden erişilebilir. Alanı ilerletme ve çalışmalarını daha geniş bir topluluğun erişimine sunma çabalarını takdir ediyoruz.
SSS
YOLOv7 nedir ve neden gerçek zamanlı nesne tespiti alanında bir dönüm noktası olarak kabul edilir?
Temmuz 2022'de yayınlanan YOLOv7, yayınlandığı dönemde mükemmel hız ve doğruluk elde eden önemli bir gerçek zamanlı nesne tespiti modeliydi. Parametre kullanımı ve çıkarım hızı açısından YOLOX, YOLOv5 ve PPYOLOE gibi çağdaş modelleri geride bıraktı. YOLOv7'nin ayırt edici özellikleri, çıkarım maliyetlerini artırmadan performansını optimize eden model yeniden parametrelendirmesi ve dinamik etiket atamasıdır. Mimarisi ve diğer son teknoloji nesne dedektörleriyle karşılaştırma metrikleri hakkında daha fazla teknik detay için YOLOv7 makalesine bakabilirsin.
YOLOv7, YOLOv4 ve YOLOv5 gibi önceki YOLO modellerine göre nasıl bir gelişme sağlar?
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 birçok yenilik 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'e kıyasla doğruluğu %2,2 artırır ve parametreleri %22 azaltır. Ayrıntılı karşılaştırmalar SOTA nesne dedektörleri ile YOLOv7 karşılaştırması performans tablosunda bulunabilir.
YOLOv7'yi Ultralytics araçları ve platformları ile kullanabilir miyim?
Şu an itibarıyla Ultralytics sadece YOLOv7 ONNX ve TensorRT çıkarımını desteklemektedir. YOLOv7'nin dışa aktarılmış ONNX ve TensorRT versiyonunu Ultralytics ile çalıştırmak için Kullanım Örnekleri bölümüne göz at.
Veri setimi kullanarak nasıl özel bir YOLOv7 modeli eğitebilirim?
Özel bir YOLOv7 modeli kurmak ve eğitmek için şu adımları izle:
-
YOLOv7 deposunu kopyala:
git clone https://github.com/WongKinYiu/yolov7 -
Kopyalanan dizine git ve bağımlılıkları yükle:
cd yolov7 pip install -r requirements.txt -
Veri setini hazırla ve model parametrelerini depoda sağlanan kullanım talimatlarına göre yapılandır. Daha fazla rehberlik için en güncel bilgiler ve güncellemeler için YOLOv7 GitHub deposunu ziyaret et.
-
Eğitimden sonra, modeli Kullanım Örnekleri bölümünde gösterildiği gibi Ultralytics'te kullanmak üzere ONNX veya TensorRT formatına dışa aktarabilirsin.
YOLOv7'de sunulan temel özellikler ve optimizasyonlar nelerdir?
YOLOv7, gerçek zamanlı nesne tespitinde devrim yaratan birçok temel özellik 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 kaba-dan-inceye lider kılavuzlu bir yöntem kullanır ve doğruluğu artırır.
- 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 son teknoloji modellere kıyasla parametre sayısını %40 ve hesaplamayı %50 oranında azaltırken daha hızlı çıkarım hızlarına ulaşır.
Bu özellikler hakkında daha fazla bilgi için YOLOv7 Genel Bakış bölümüne bak.