Anchor-Based与Anchor-Free在YOLOv8中的代码
时间: 2025-06-26 09:04:27 浏览: 15
在目标检测领域中,`Anchor-Based` 和 `Anchor-Free` 是两种不同的设计思路。下面我会基于 YOLOv8 的特点为你简单介绍这两种方法的区别及其在代码中的体现。
### Anchor-Based vs Anchor-Free
#### 1. **Anchor-Based**
- 在传统的YOLO版本(如YOLOv1-v5),模型会预先设定一组固定大小的锚框 (anchors) 来预测物体的位置、尺寸等信息。
- 锚框的数量以及宽高比例通常需要通过聚类算法提前计算好,并作为超参数输入到网络结构中。
**优点**:
- 更容易捕捉不同形状的目标物;
**缺点**:
- 增加了训练复杂度;需要人为调整anchor设置。
#### 2. **Anchor-Free**
- 相较于传统的方式,YOLOv7开始逐步减少对预设锚点依赖,在最新版YOLOv8已经完全摒弃了该机制。它直接回归每个像素位置为中心所对应的边界框坐标值,无需再维护额外的一套 anchors 参数列表。
**优点**:
- 模型更轻量化,推理速度更快; 同时简化配置流程减少了人工干预成本;
**缺点**:
- 对小物件识别可能存在一定挑战.
---
### YOLOv8 中的具体实现差异:
尽管官方并未公开所有源码细节给公众查阅学习,但从现有资料来看我们可以总结出一些关键之处:
- **去除了 anchor 配置项**: 如果对比早期版本的config文件内容可以看到不再存在关于"anchors"字段描述部分.
```python
# 示例来自旧版本 yolov5 config.yaml 文件片段(包含 anchors)
nc: 80 # number of classes
depth_multiple: 0.33 # model depth multiple
width_multiple: 0.50 # layer channel multiple
...
anchors:
- [10,13, 16,30, 33,23] # P3/8
- [30,61, 62,45, 59,119] # P4/16
- [116,90, 156,198, 373,326] # P5/32
```
而新版yolov8则彻底移除上述定义形式。
- **采用中心偏移策略替代 Anchors**: 新框架转而利用网格单元格内的相对距离表示法来定位真实box位置。例如,对于任一候选区域而言我们仅需记录四个数值即可完成标注任务:x_offset,y_offset,w,h 分别代表相对于当前cell左上角顶点横向纵向位移量及宽度高度缩放系数。
以下是伪代码示例展示如何生成Ground Truth Labels过程的一部分操作步骤:
```python
def generate_ground_truth(labels, output_size):
"""
将原始标签转换成适配模型输出层维度的形式
Args:
labels(List[List]): shape=(n,[class,x_center,y_center,width,height])
normalized coordinates within range[0~1]
output_size(int): feature map resolution e.g., if input image size=640*640 and downsample ratio = 8 then this param equals to 80
Returns:
gt_tensor(torch.Tensor): shape=[output_size,output_size,(num_classes+5)]
where last dim means [conf,class0,...,classN,dx,dy,dw,dh]
"""
num_classes = len(classes_dict)-1
batch_size=len(labels)
strides = [8, 16, 32]
for i in range(batch_size):
targets = torch.zeros((len(strides), output_size // min(stride), output_size // max(stride)), dtype=torch.float32).to(device)
cls_labels, x_centrals, y_centers, ws, hs = [],[],[],[],[]
# 解析单张图片内所有的bounding box info
for lb in labels[i]:
clss_id, xc, yc , w, h =lb
stride_level=int(np.floor(math.log(output_size /max(w,h))))
grid_x,grid_y=int(xc*(output_size//strides[stride_level])),int(yc *(output_size//strides[stride_level]))
dx=x-(xc *output_size %stride )
dy=y -(yc *output_size%stride )
dw=w*output_size
dh=h*output_size
target_grid.append([dx,dy,dw,dh])
targets=stride_levels].append()
return gt_tensor
```
以上仅为示意性质并不能完整运行,请参考 Ultralytics 官方文档获取权威指导说明!
阅读全文
相关推荐


















