YOLOv7: Eğitilebilir Ücretsizler Paketi#
Temmuz 2022'de yayımlanan YOLOv7, yayımlandığı dönemde gerçek zamanlı nesne algılamada önemli bir ilerleme sağladı. GPU V100 üzerinde %56,8 AP elde ederek tanıtıldığında yeni ölçütler belirledi. YOLOv7, hız ve doğruluk açısından YOLOR, YOLOX, Scaled-YOLOv4 ve YOLOv5 gibi dönemin nesne algılama modellerini geride bıraktı. Model, başka hiçbir veri kümesi veya önceden eğitilmiş ağırlık kullanılmadan MS COCO veri kümesi üzerinde sıfırdan eğitilir. YOLOv7 kaynak kodu GitHub'da kullanılabilir. YOLO11 ve YOLO26 gibi daha yeni modellerin o zamandan beri daha yüksek doğruluğa ve daha iyi verimliliğe ulaştığını unutma.

SOTA nesne algılama modellerinin karşılaştırması#
YOLO karşılaştırma tablosundaki sonuçlardan, önerilen yöntemin kapsamlı olarak en iyi hız-doğruluk dengesine sahip olduğunu biliyoruz. YOLOv7-tiny-SiLU'yu YOLOv5-N (r6.1) ile karşılaştırırsak yöntemimiz 127 fps daha hızlıdır ve AP açısından %10,7 daha doğrudur. Ayrıca YOLOv7, 161 fps kare hızında %51,4 AP elde ederken aynı AP değerine sahip PPYOLOE-L yalnızca 78 fps kare hızına ulaşır. Parametre kullanımı açısından YOLOv7, PPYOLOE-L'den %41 daha az parametre kullanır.
YOLOv7-X'i 114 fps çıkarım hızıyla, 99 fps çıkarım hızına sahip YOLOv5-L (r6.1) ile karşılaştırırsak YOLOv7-X AP'yi %3,9 artırabilir. 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 yüksektir. Ayrıca parametre ve hesaplama miktarı açısından YOLOv7-X, YOLOv5-X (r6.1) ile karşılaştırıldığında parametreleri %22 ve hesaplamayı %8 azaltırken AP'yi %2,2 artırır (Kaynak).
| Model | Parametreler (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ış#
Gerçek zamanlı nesne algılama; çoklu-nesne takibi, otonom sürüş, robotik ve tıbbi görüntü analizi dahil olmak üzere birçok bilgisayarlı görü sisteminin önemli bir bileşenidir. Son yıllarda gerçek zamanlı nesne algılama geliştirme çalışmaları, verimli mimariler tasarlamaya ve çeşitli CPU, GPU ve sinirsel işlem birimlerinin (NPUs) çıkarım hızını artırmaya odaklanmıştır. YOLOv7, uçtan buluta kadar hem mobil GPU hem de GPU cihazlarını destekler.
Mimari optimizasyona odaklanan geleneksel gerçek zamanlı nesne algılama modellerinin aksine YOLOv7, eğitim sürecinin optimizasyonuna odaklanır. Buna, çıkarım maliyetini artırmadan nesne algılama doğruluğunu iyileştirmek için tasarlanmış modüller ve optimizasyon yöntemleri dahildir; bu kavram "eğitilebilir ücretsizler paketi" olarak bilinir.
Temel Özellikler#
YOLOv7 çeşitli temel özellikler sunar:
-
Modelin Yeniden Parametrelendirilmesi: YOLOv7, gradyan yayılım yolu kavramıyla farklı ağlardaki katmanlara uygulanabilen planlı, yeniden parametrelendirilmiş bir model önerir.
-
Dinamik Etiket Atama: Birden çok çıktı katmanına sahip modelin eğitimi yeni bir sorun ortaya çıkarır: "Farklı dalların çıktıları için dinamik hedefler nasıl atanır?" YOLOv7 bu sorunu çözmek için, kabadan inceye öncül yönlendirmeli etiket atama adı verilen yeni bir etiket atama yöntemi sunar.
-
Genişletilmiş ve Bileşik Ölçekleme: YOLOv7, parametreleri ve hesaplamayı etkili biçimde kullanabilen gerçek zamanlı nesne algılama modeli için "genişletme" ve "bileşik ölçekleme" yöntemlerini önerir.
-
Verimlilik: YOLOv7'nin önerdiği yöntem, son teknoloji gerçek zamanlı nesne algılama modellerinin parametrelerini yaklaşık %40, hesaplama miktarını ise %50 oranında etkili biçimde azaltabilir; ayrıca daha hızlı çıkarım ve daha yüksek algılama doğruluğu sağlar.
Kullanım Örnekleri#
Ultralytics, yolov7.pt önceden eğitilmiş ağırlıklarını veya ultralytics/cfg/models/v7/ YAML dosyalarını yayımlamaz 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, upstream YOLOv7 deposunda eğitilmiş bir YOLOv7 checkpoint'ini ONNX veya TensorRT'e aktararak Ultralytics'e getirebilirsin.
ONNX Dışa Aktarma#
YOLOv7 ONNX modelini Ultralytics ile kullanmak için:
-
(İsteğe bağlı) Ultralytics'i yükle ve gerekli bağımlılıkların otomatik olarak yüklenmesi için bir ONNX modeli dışa aktar:
pip install ultralytics yolo export model=yolo26n.pt format=onnx -
İstediğin YOLOv7 modelini YOLOv7 deposundaki dışa aktarıcıyı kullanarak 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ştirilen ONNX modelini yükleyebilir ve Ultralytics'te normal ş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. adımları izle.
-
TensorRTPython paketini yükle:pip install tensorrt -
Değiştirilen ONNX modelini TensorRT motoruna dönüştürmek için aşağıdaki betiği çalıştır:
from ultralytics.utils.export import onnx2engine onnx2engine("yolov7-ultralytics.onnx", quantize=16) -
Modeli Ultralytics'te yükle ve çalıştır:
from ultralytics import ASSETS, YOLO model = YOLO("yolov7-ultralytics.engine", task="detect") results = model(ASSETS / "bus.jpg")
Atıflar ve Teşekkürler#
Gerçek zamanlı nesne algılama alanına yaptıkları önemli katkılardan dolayı YOLOv7 yazarlarını anmak isteriz:
@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}
}Resmî YOLOv7 makalesi CVF 2023 Open Access kapsamında yayımlandı ve arXiv üzerinde bir ön baskısı bulunuyor. Yazarlar çalışmalarını herkese açık hâle getirdi ve kod tabanına GitHub üzerinden erişilebilir. Alanı ilerletme ve çalışmalarını daha geniş topluluğun erişimine sunma çabalarını takdir ediyoruz.
SSS#
Temmuz 2022'de yayımlanan YOLOv7, yayımlandığı dönemde mükemmel hız ve doğruluk elde eden önemli bir gerçek zamanlı nesne algılama modeliydi. Parametre kullanımı ve çı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 modelin yeniden parametrelendirilmesi ve dinamik etiket atama bulunur. Mimarisi ve diğer SOTA nesne algılama modelleriyle karşılaştırma ölçütleri hakkında daha fazla teknik ayrıntı için YOLOv7 makalesine bakabilirsin.
YOLOv7, eğitim sürecini geliştiren ve çıkarım doğruluğunu artıran modelin yeniden parametrelendirilmesi ve dinamik etiket atama 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'e kıyasla doğruluğu %2,2 artırır ve parametreleri %22 azaltır. Ayrıntılı karşılaştırmaları YOLOv7'nin SOTA nesne algılama modelleriyle karşılaştırması performans tablosunda bulabilirsin.
Şu anda Ultralytics yalnızca YOLOv7 ONNX ve TensorRT çıkarımını destekliyor. YOLOv7'nin ONNX ve TensorRT'e aktarılmış sürümünü Ultralytics ile çalıştırmak için Kullanım Örnekleri bölümüne bak.
Özel bir YOLOv7 modeli yüklemek ve eğitmek için şu adımları izle:
-
YOLOv7 deposunu klonla:
git clone https://github.com/WongKinYiu/yolov7 -
Klonlanan dizine git ve bağımlılıkları yükle:
cd yolov7 pip install -r requirements.txt -
Veri kümeni 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 bilgi ve güncellemeleri YOLOv7 GitHub deposunda bulabilirsin.
-
Eğitimden sonra modeli, Kullanım Örnekleri bölümünde gösterildiği gibi Ultralytics'te kullanmak üzere ONNX veya TensorRT'e aktarabilirsin.
-
YOLOv7, gerçek zamanlı nesne algılamada devrim yaratan çeşitli temel özellikler sunar:
- Modelin Yeniden Parametrelendirilmesi: Gradyan yayılım yollarını optimize ederek modelin performansını artırır.
- Dinamik Etiket Atama: Farklı dallardaki çıktılara dinamik hedefler atamak için kabadan inceye öncül yönlendirmeli 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 üzere parametreleri ve hesaplamayı verimli biçimde kullanır.
- Verimlilik: Daha hızlı çıkarım hızlarına ulaşırken diğer SOTA modellerle karşılaştırıldığında parametre sayısını %40, hesaplama miktarını %50 azaltır.
Bu özellikler hakkında daha fazla ayrıntı için YOLOv7 Genel Bakış bölümüne bak.