Я тренирую сеть yolo, чтобы выявлять футбольный мяч, узнавать больше и лучше понимать эту архитектуру Я могу обнаружить мяч в большинстве случаев. Моя проблема здесь в том, что сгенерированный прямоугольник слишком большой, покрывая гораздо больше пикселей, чем реальный шар.
Я знаю, что якоря параметров влияют на будущие коробки. Я экспериментировал с несколькими значениями конфигурации, а также пробовал код для генерации якорей. Якоря, генерируемые кодом, слишком малы, и часто мы даже не видим поле, только заголовок. Я также думал, что это не лучший подход к решению проблемы одного класса, потому что мы используем k-средства для генерации этих якорей. Когда я пытался изменить значения, область покрытия была совершенно неправильной, но поле было действительно маленьким, охватывая меньше, чем исходные якоря.
Вот мой код для генерации якорей. Я удалил некоторые методы, чтобы сделать код более чистым.
def __init__(self, dir_images, dir_labels, width = 416, height = 416, anchors = 9):
# dir_images: Directory that contains all images that will be used or
# already has used to training the neural network
# Example: /home/enacom/Desktop/darknet_football_resized_images/
#dir_labels: Directory that contains all labels that will be used or]
# already has used to training the neural network
# Example: /home/enacom/Desktop/BBoxLabelTool/Images/labels6/
# anchors: the number of anchor that you desire
# default value is 9 on yoloV3, but you can add more if want detect more objects
self.dir_images = dir_images
self.dir_labels = dir_labels
self.grid_w = width/32
self.grid_h = height/32
self.anchors = anchors
self.annotation_dims = []
file_list = os.listdir(self.dir_images)
boxes = self.__read_labels()
for file in file_list:
actual_dir = self.dir_images + file
try:
image = cv2.imread(actual_dir)
width, height = image.shape[:2]
cell_w = width / self.grid_w
cell_h = height / self.grid_h
box = boxes[file.replace("jpg", "txt")]
relative_w = (float(box[0][2]) - float(box[0][0])) # / cell_w
relatice_h = (float(box[0][3]) - float(box[0][1])) # / cell_h
self.annotation_dims.append(tuple(map(float, (relative_w,relatice_h))))
except AttributeError:
print("Failure when reading image")
self.annotation_dims = np.array(self.annotation_dims)
print(self.annotation_dims / 32)
def IOU(self, ann, centroids):
w, h = ann
similarities = []
for centroid in centroids:
c_w, c_h = centroid
if c_w >= w and c_h >= h:
similarity = w * h / (c_w * c_h)
elif c_w >= w and c_h <= h:
similarity = w * c_h / (w * h + (c_w - w) * c_h)
elif c_w <= w and c_h >= h:
similarity = c_w * h / (w * h + c_w * (c_h - h))
else: # means both w,h are bigger than c_w and c_h respectively
similarity = (c_w * c_h) / (w * h)
similarities.append(similarity) # will become (k,) shape
return np.array(similarities)
def run_kmeans(self):
ann_num = self.annotation_dims.shape[0]
iterations = 0
prev_assignments = np.ones(ann_num) * (-1)
iteration = 0
old_distances = np.zeros((ann_num, self.anchors))
indices = [random.randrange(self.annotation_dims.shape[0]) for i in range(self.anchors)]
centroids = self.annotation_dims[indices]
anchor_dim = self.annotation_dims.shape[1]
while True:
distances = []
iteration += 1
for i in range(ann_num):
d = 1 - self.IOU(self.annotation_dims[i], centroids)
distances.append(d)
distances = np.array(distances) # distances.shape = (ann_num, anchor_num)
print("iteration {}: dists = {}".format(iteration, np.sum(np.abs(old_distances - distances))))
# assign samples to centroids
assignments = np.argmin(distances, axis=1)
if (assignments == prev_assignments).all():
return centroids
# calculate new centroids
centroid_sums = np.zeros((self.anchors, anchor_dim), np.float)
for i in range(ann_num):
centroid_sums[assignments[i]] += self.annotation_dims[i]
for j in range(self.anchors):
centroids[j] = centroid_sums[j] / (np.sum(assignments == j) + 1e-6)
prev_assignments = assignments.copy()
old_distances = distances.copy()
a = AnchorGenerator("/home/myDir/Desktop/BBoxLabelTool/Images/5_images_clean/",
"/home/myDir/Desktop/BBoxLabelTool/Labels/005/",
anchors = 9)
centroids = a.run_kmeans()
a.print_anchors(centroids)
Результат с оригинальными якорями: https://imgur.com/a/5OhiTfl
Результат с созданными моими якорями: https://imgur.com/a/YCW2aam
В случае созданного вручную якоря, это близко, чтобы быть правым, но я не знаю, как сделать это более точно. Это якоря, которые я использовал, которые генерируют этот результат.
anchors = 3,1, 7,4 5,5, 12,12, 15,15, 16,16, 18,17