В цикле for языка Python не могу получить ожидаемое значение счетчика

Проект по распознаванию спикера с помощью модуля resemblyzer. Структура папок такова: есть директория speakers, в которой лежат папки spk1, spk2 и т.д. В каждой из папок - по нескольку записей отдельных спикеров (одна папка - один говорящий). В ходе обработки сделал словарь, в котором ключи - те самые директории spk1, spk2 и проч., а их значения - эмбединги (представления) записей спикеров.

Далее я хочу сравнить попарно записи каждого спикера, чтобы посчитать метрику accuracy (как часто система ошибается). На этом первом этапе приводимого ниже скрипта делаю следующее: создаю попарные комбинации с тем, чтобы перебрать все возможные сочетания записей всякого говорящего внутри "его" папки.

Второй этап - поместить эмбединги записей в матрицы подобия и сравнить их посредством косинусного сходства.

В финале (третий этап) считаем accuracy. Видим: перебрали 46 комбинаций, но почему-то получили 0 совпадений. Хотя если распечатать матрицы подобия, очевидно, что совпадения наличествуют. Что не так в цикле for?

Ранее схожая проблема возникала, когда ту же задачу я решал с помощью библиотеки speechbrain. Тогда ошибка счета была связана с тензорным типом данных, генерирующим логические ответы True либо False. Здесь, как мне представляется, иной случай.

Код:

!pip install resemblyzer
! pip install umap
import numpy as np
from itertools import combinations

num_true=0
num_total=0

# 1 этап - ради сравнения перебираем значения словаря (т.е. эмбединги записей спикеров) и создаем список всех возможных комбинаций:
# (спикер 1 запись 1 - спикер 1 запись 2), (спикер 1 запись 1 - спикер 1 запись 3) и т.д.
for elems in speaker_wavs.values():   
  # print(elems[0])
  tuples = list(combinations(elems, 2)) # получаем перебор всех комбинаций
 
  # 2 этап - создаем эмбединги записей
  for single in tuples:         # идем по каждой комбинации в списке
      # функция .embed_utterance() создает эмбединги голосов 
      embeds = (np.array( [encoder.embed_utterance(single[0]) ] ), np.array([encoder.embed_utterance(single[1]) ] ) )
      num_total+=1

      # Вычислим матрицу подобия. Сходство двух эмбедингов - это просто их точечное произведение, 
      # потому что метрикой сходства является косинусное сходство, а эмбединги уже нормированы по L2.
      # Короткая версия:
      utt_sim_matrix = np.inner(embeds[0], embeds[1])    # Внутреннее произведение двух массивов. 
      # print('Матрица_1', utt_sim_matrix) # распечатать, если надо наглядно сравнить эмбединги
    
      # Длинная, подробная версия:
      utt_sim_matrix2 = np.zeros( (len(embeds[0]), len(embeds[1]) ) )
      for i in range(len(embeds[0])):
        for j in range(len(embeds[1])):
        # Обозначение @ эквивалентно np.dot(embedds_a[i], embedds_b[i])
          utt_sim_matrix2[i, j] = embeds[0][i] @ embeds[1][j]
          # print('Матрица_2', utt_sim_matrix2)  # распечатать, если надо наглядно сравнить эмбединги

          # Возвращает True, если два массива равны по элементам в пределах допуска       
          if np.allclose(utt_sim_matrix, utt_sim_matrix2) == 'True':
            num_true+=1

# print(num_true)   # сейчас получаем 0
# print(num_total)  # сейчас получаем 46

# Этап 3 - считаем метрику accuracy:
if num_total !=0:
  accuracy = num_true/num_total
  print(accuracy)
else:
  print('На ноль делить нельзя')

Ответы (1 шт):

Автор решения: Эникейщик

numpy.allclose() возвращает или True или False, поэтому надо сравнивать не со строкой, а с этими значениями. Да и на самом деле даже сравнивать не требуется, потому что достаточно и

if np.allclose(utt_sim_matrix, utt_sim_matrix2): # т.к. тут или True или False, то и сравнивать не нужно
        num_true+=1
→ Ссылка