keras: как объединить прогнозы на уровне кадров с прогнозами на уровне песен - PullRequest
0 голосов
/ 20 декабря 2018

Я делаю классификацию жанров песен.Для каждой песни я нарезал их на маленькие кадры (5 с), чтобы сгенерировать спектрограмму в качестве входных функций для нейронной сети, и каждый кадр имеет ассоциированную метку жанра песни.

Данные выглядят следующим образом:

   name         label   feature
   ....
   song_i_frame1 label   feature_vector_frame1
   song_i_frame2 label   feature_vector_frame2
   ...
   song_i_framek label   feature_vector_framek
   ...

Я могу получить точность прогноза для каждого кадра из Keras без проблем.Но в настоящее время я не знаю, как агрегировать результаты прогнозирования от уровня кадра до уровня песни с большинством голосов, поскольку данные, поступающие в модель when keras, теряют свои имена.

Как я могу сохранить именакаждой метки (например, song_i_frame1) в выходных данных keras, чтобы сформировать совокупный прогноз для песни посредством голосования большинством.Или есть ли другие способы агрегирования в прогнозирование на уровне песен ???

Я погуглил, но не могу найти ответ на этот вопрос и был бы признателен за любую информацию.

1 Ответ

0 голосов
/ 20 марта 2019

В наборе данных может быть названа каждая метка (например: 'rock').Чтобы использовать это с нейронной сетью, это должно быть преобразовано в целое число (например: 2), а затем в горячее кодирование (например: [0,0,1]).Так что 'rock' == 2 == [0,0,1].Ваши выходные прогнозы будут в этой форме с горячим кодированием.[0.1, 0.1, 0.9] означает, что класс 2 был предсказан, [0.9, 0.1, 0.1] означает класс 0 и т. Д. Чтобы сделать это обратимым образом, используйте sklearn.preprocessing.LabelBinarizer .

Существует несколько способов объединения прогнозирования кадров в общее прогнозирование.Наиболее распространенными являются в порядке возрастания сложности:

  • Голосование большинством.
  • Среднее / среднее голосование.

Ниже приведен пример.

import numpy
from sklearn.preprocessing import LabelBinarizer

labels = [ 'rock', 'jazz', 'blues', 'metal' ] 

binarizer = LabelBinarizer()
y = binarizer.fit_transform(labels)

print('labels\n', '\n'.join(labels))
print('y\n', y)

# Outputs from frame-based classifier. 
# input would be all the frames in one song
# frame_predictions = model.predict(frames)
frame_predictions = numpy.array([
    [ 0.5, 0.2, 0.3, 0.9 ],
    [ 0.9, 0.2, 0.3, 0.3 ],
    [ 0.5, 0.2, 0.3, 0.7 ],
    [ 0.1, 0.2, 0.3, 0.5 ],
    [ 0.9, 0.2, 0.3, 0.4 ],
])

def vote_majority(p):
    voted = numpy.bincount(numpy.argmax(p, axis=1))
    normalized = voted / p.shape[0]
    return normalized

def vote_average(p):
    return numpy.mean(p, axis=0)

maj = vote_majority(frame_predictions)
mean = vote_average(frame_predictions)

genre_maj = binarizer.inverse_transform(numpy.array([maj]))
genre_mean = binarizer.inverse_transform(numpy.array([mean]))
print('majority voting', maj, genre_maj)
print('mean voting', mean, genre_mean)

Вывод

labels:
 rock
 jazz
 blues
 metal
y:
 [[0 0 0 1]
 [0 1 0 0]
 [1 0 0 0]
 [0 0 1 0]]
majority voting: [0.4 0.  0.  0.6] ['rock']
mean voting: [0.58 0.2  0.3  0.56] ['blues']

Можно также проводить голосование с помощью классификатора, обученного прогнозированию по кадрам, хотя это не так часто делается и усложняется, когда длина ввода изменяется.

Другой альтернативой является использование множественного изучения экземпляров с GlobalAveragePooling над классификациями на основе кадров для одновременного обучения целым песням.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...