在yolov2及之后的版本中作者都用anchor boxes 取代了中心点的方法,那么如何用K-means聚类算法得到anchor boxes呢?这边给出方法及代码:
传统kmeans聚类算法
kmeans算法算是一个比较经典的算法,主要是通过选取k个聚类中心,利用求各点距离的方法来进行聚类,迭代更新聚类中心。
算法步骤:
1.初始化K个簇中心;
2.使用相似性度量(一般是欧氏距离),将每个样本分配给与其距离最近的簇中心;
3.计算每个簇中所有样本的均值,更新簇中心;
4.重复2、3步,直到均簇中心不再变化,或者达到了最大迭代次数。
; K-means聚类算法生成anchor boxes
先给出IOU的公式,聚类anchor boxes的欧式距离改为iou。
步骤
对box进行K-means的步骤为:
1.随机选取K个box作为初始anchor;
2.使用IOU度量,将每个box分配给与其iou最大的anchor;
3.计算每个簇中所有box宽和高的均值,更新anchor;
4.重复2、3步,直到anchor不再变化,或者达到了最大迭代次数。
代码还是很值得看一下的:
def iou(boxes, anchors):
"""
Calculate the IOU between boxes and anchors.
:param boxes: 2-d array, shape(n, 2)
:param anchors: 2-d array, shape(k, 2)
:return: 2-d array, shape(n, k)
"""
# Calculate the intersection,
# the new dimension are added to construct shape (n, 1) and shape (1, k),
# so we can get (n, k) shape result by numpy broadcast
w_min = np.minimum(boxes[:, 0, np.newaxis], anchors[np.newaxis, :, 0])
h_min = np.minimum(boxes[:, 1, np.newaxis], anchors[np.newaxis, :, 1])
inter = w_min * h_min
# Calculate the union
box_area = boxes[:, 0] * boxes[:, 1]
anchor_area = anchors[:, 0] * anchors[:, 1]
union = box_area[:, np.newaxis] + anchor_area[np.newaxis]
return inter / (union - inter)
def fit(self, boxes):
"""
Run K-means cluster on input boxes.
:param boxes: 2-d array, shape(n, 2), form as (w, h)
:return: None
"""
# If the current number of iterations is greater than 0, then reset
if self.n_iter > 0:
self.n_iter = 0
np.random.seed(self.random_seed)
n = boxes.shape[0]
# Initialize K cluster centers (i.e., K anchors)
self.anchors_ = boxes[np.random.choice(n, self.k, replace=True)]
self.labels_ = np.zeros((n,))
while True:
self.n_iter += 1
# If the current number of iterations is greater than max number of iterations , then break
if self.n_iter > self.max_iter:
break
self.ious_ = self.iou(boxes, self.anchors_)
distances = 1 - self.ious_
cur_labels = np.argmin(distances, axis=1)
# If anchors not change any more, then break
if (cur_labels == self.labels_).all():
break
# Update K anchors
for i in range(self.k):
self.anchors_[i] = np.mean(boxes[cur_labels == i], axis=0)
self.labels_ = cur_labels
Original: https://blog.csdn.net/hgj1h/article/details/121422788
Author: Lukas88664
Title: 【代码阅读】【算法】K-means聚类算法及利用K-means聚类生成anchor boxes
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/560442/
转载文章受原作者版权保护。转载请注明原作者出处!