Audio Autio Tagging (음향 이벤트 인식)은 오디오 신호에서 발생하는 이벤트 종류를 찾는 문제이다. 아기의 웃음이나 기타의 소리가 동시에 있는 소리는 독특해서 즉시 인식됩니다. 하지만 전기 톱 소리와 믹서기 소리처럼 유사한 소리가 동시에 포함된 오디오는 해당 소리들을 인식하기 어렵다. 따라서 특정 오디오에 대해서 해당 오디오가 포함하는 여러 이벤트들을 tagging할 수 있는 Multi-Label Classification이 가능한 Audio Auto Tagging System이 필요하다.
이미지 출처: https://www.kaggle.com/c/freesound-audio-tagging-2019
보통 Audio Autio Tagging을 평가할 때는 Average Precision, Rank-Average Precision과 같이 IR(Information Retrieval)에서 사용되는 metric이 많이 사용됩니다. (딥러닝 모델들을 활용해 Multi-Label Classification을 진행하면, 각 레이블에 대한 점수가 확률벡터로 나오게 될텐데, 실제 1인 Label에 대해서 얼만큼 높은 Rank로 모델이 예측하였는가가 결국 모델이 잘 예측했냐를 평가할 수 있기 때문에 IR쪽에서 사용되는 metric이 자주 사용되는 것 같네요)
Freesound Audio Auto Tagging 2019에서는 LRAP(Label-Weighted-Label-Ranking-Average-Precision)을 활용해 모델의 성능을 평가했습니다. LRAP는 Label=1인 값에 대해서만 Rank Precision을 계산합니다. ()
참고: How to interpret: Label Ranking Average Precision Score
def _one_sample_positive_class_precisions(scores, truth):
"""단일 샘플에 대한 각 실제 클래스의 정밀도를 계산합니다.
Args:
scores: np.array of (num_classes,) giving the individual classifier scores.
truth: np.array of (num_classes,) bools indicating which classes are true.
Returns:
pos_class_indices: np.array of indices of the true classes for this sample.
pos_class_precisions: np.array of precisions corresponding to each of those
classes.
"""
num_classes = scores.shape[0]
pos_class_indices = np.flatnonzero(truth > 0)
if not len(pos_class_indices):
return pos_class_indices, np.zeros(0)
retrieved_classes = np.argsort(scores)[::-1]
class_rankings = np.zeros(num_classes, dtype=np.int)
class_rankings[retrieved_classes] = range(num_classes)
retrieved_class_true = np.zeros(num_classes, dtype=np.bool)
retrieved_class_true[class_rankings[pos_class_indices]] = True
retrieved_cumulative_hits = np.cumsum(retrieved_class_true)
precision_at_hits = (
retrieved_cumulative_hits[class_rankings[pos_class_indices]] /
(1 + class_rankings[pos_class_indices].astype(np.float)))
return pos_class_indices, precision_at_hits
def calculate_per_class_lwlrap(truth, scores):
"""Calculate label-weighted label-ranking average precision.
Arguments:
truth: np.array of (num_samples, num_classes) giving boolean ground-truth
of presence of that class in that sample.
scores: np.array of (num_samples, num_classes) giving the classifier-under-
test's real-valued score for each class for each sample.
Returns:
per_class_lwlrap: np.array of (num_classes,) giving the lwlrap for each
class.
weight_per_class: np.array of (num_classes,) giving the prior of each
class within the truth labels. Then the overall unbalanced lwlrap is
simply np.sum(per_class_lwlrap * weight_per_class)
"""
assert truth.shape == scores.shape
num_samples, num_classes = scores.shape
precisions_for_samples_by_classes = np.zeros((num_samples, num_classes))
for sample_num in range(num_samples):
pos_class_indices, precision_at_hits = (
_one_sample_positive_class_precisions(scores[sample_num, :],
truth[sample_num, :]))
precisions_for_samples_by_classes[sample_num, pos_class_indices] = (
precision_at_hits)
labels_per_class = np.sum(truth > 0, axis=0)
weight_per_class = labels_per_class / float(np.sum(labels_per_class))
per_class_lwlrap = (np.sum(precisions_for_samples_by_classes, axis=0) /
np.maximum(1, labels_per_class))
return per_class_lwlrap, weight_per_class
Wave Form 형태의 오디오를 Feature Extraction을 통해 모델의 Input으로 들어갈 수 있게 만들어 주고 (Mel Spectogram) 우리의 가정으로 만들어진 모델(CNN, RNN)을 통해 Feature Extraction을 진행해준다. 이후 Feature Space에서 Classifier를 학습해주면 된다.
모델이 동일한 Time Sequence를 처리하도록 Train Data를 Chunk로 나누어 주고 Label을 복사하면 된다.
Mel-Power Spectogram
음성 인식이란 사람이 말하는 음성 언어를 컴퓨터가 해석해 그 내용을 문자 데이터로 전환하는 처리를 말한다. STT라고도 한다. 키보드 대신 문자를 입력하는 방식으로 주목을 받고 있다.
출처 : https://ko.wikipedia.org/wiki/%EC%9D%8C%EC%84%B1_%EC%9D%B8%EC%8B%9D
이미지 참조 : http://proceedings.mlr.press/v48/amodei16.pdf
일반적인 Speech Recongition에서 우리는 데이터셋으로 오디오 클립과, Transcript를 받게 됩니다. 하지만 우리는 어떤 단어의 Character가 Audio와 Alignment가 맞는지 알수 없죠 (2초 동안 조용하다가 Hello를 말하거나 바로 Hello를 말하거나 둘다 Transcript은 Hello다). 이러한 Alignment 없이, 어떤 Audio와 Text 사이의 규칙을 정의하기 힘듭니다. 또한 사람들의 언어사용을 하는것은 다양하기 떄문에 단일한 Rule로 그들을 정의하기는 쉽지 않습니다.
이미지 참조 : https://distill.pub/2017/ctc
우리가 input과 output사이의 정확한 Alignment가 labeling되어있는 데이터셋이 필요하지는 않습니다. 그러나 주어진 input에 대해서 output의 확률값은 필요하죠. CTC는 둘 사이의 가능한 모든 alignment의 가능성을 합산하여 작용합니다. (CTC works by summing over the probability of all possible alignments between the two). 이 말은 즉, Input도 output의 가능한 Align을 모두 뽑아서 Marginalize하자! 라는 뜻입니다.
Hello가 등장할 수 있는 모든 Path(Time Sequence)안에서 모델이 H,E,L,L,O를 예측하도록 하자!!
모든 Time Step(25ms)에 대해서 labeling을 할 수 없다!
아래의 Notation을 활용하겠습니다.
이미지 참조 : https://distill.pub/2017/ctc
CTC Rule
1. selp-loop : 자기 자신을 반복합니다.
2. left-to-right : non-blank 레이블을 순방향으로 하나씩 전이합니다. 역방향은 허용하지 않습니다. non-blank를 두 개 이상 건너뛰는 것 역시 허용이 안 됩니다.
3. blank 관련 : blank에서 non-blank, non-blank에서 blank로의 전이를 허용합니다.
이미지 참조 : https://distill.pub/2017/ctc
언어 조음 규칙상 절대로 발음될 수 없는 일부 경로들을 제거해 컴팩트하게 다시 그리면
이미지 참조 : https://distill.pub/2017/ctc
CTC 기법에서는 각 상태가 조건부 독립(conditional independence)라고 가정한다. 즉 time-step t의 output은 이전/이후 time-step의 상태가 어떻든 그 값이 변하지 않는다고 가정한다.
특정 Path의 등장 확률
가능한 모든 Path의 등장 확률
이제 일 때 Path의 등장확률을 구해보자
전방 확률은 1:t 시점에 걸쳐 레이블 시퀀스가 1:s 가 나타날 확률
(3번째 time-step에서 e가 등장할 때, time-step 1:3까지 가능한 모든 Path의 경로인 1:e가 등장할 확률은?)
이미지 참조 : https://distill.pub/2017/ctc
Forward Probability
Dynamic Programming
Case 01 :
Case 02 :
Forward Flow
Forward Computation
후방 확률은 t:T 시점에 걸쳐 레이블 시퀀스가 s:|l|일 확률
(6번째 time-step에서 이 등장할 때, time-step t:T까지 가능한 모든 Path의 경로인 :|l|가 등장할 확률은?)
이미지 참조 : https://distill.pub/2017/ctc
Backward Probability
Dynamic Programming
Backward Computation
특정 시점, 특정 상태를 지나는 경로에 대한 등장 확률을 구해보겠습니다. 이는 앞서 구한 전방확률과 후방확률로 간단히 계산할 수 있습니다. t=3 시점에 상태가 h(s=2)일 때 모든 경로에 대한 확률은?
Forward Path Probability
Backward Path Probability
Complete Path Probability Calculation
Complete Path Probability는 Forward Path Probability와 Backward Path Probability의 곱으로 표현할 수 있다.
시점(time)을 고정해 놓고 상태(state)에 대해 모두 합을 취하면 우도가 됩니다.
(t=3 을 기준으로 우도를 구한다고 하면 파란색으로 칠한 다섯 칸에 해당하는 Complete Path 확률을 모두 더한 값이 됩니다)
Likelihood Computation
우리는 우도, 즉 p(l|x) 를 최대화하는 모델 파라메터를 찾고자 합니다. 이를 위해서는 우도에 대한 그래디언트(gradient)를 구해야 합니다. 이 그래디언트를 모델 전체 학습 파라메터에 역전파(backpropagation)하는 것이 CTC 기법을 적용한 모델의 학습(train)이 되겠습니다. 우도 계산은 보통 로그 우도(log-likelihood)로 수행하는데요. t 번째 시점 k 번째 상태(음소)에 대한 로그 우도의 그래디언트는 아래와 같습니다. ln(x) 를 x 로 미분하면 1/x 이고 우도에 로그를 취한 것을 합성 함수라고 이해하면 체인룰(chain)에 의해 우변처럼 정리할 수 있습니다.
Example
참고 ㅣ Connectionist Temporal Classification, ratsgo님의 Speech Book
러시아 과학자 블라디미르 리벤슈테인(Vladimir Levenshtein)가 고안한 알고리즘입니다. 편집 거리(Edit Distance) 라는 이름으로도 불립니다. Levenshtein Distance는 두 개의 문자열 A, B가 주어졌을 때 두 문자열이 얼마나 유사한 지를 알아낼 수 있는 알고리즘입니다. 그러니까, 문자열 A가 문자열 B와 같아지기 위해서는 몇 번의 연산을 진행해야 하는 지 계산할 수 있습니다.
여기서의 연산이란, 삽입(Insertion), 삭제(Deletion), 대체(Replacement)를 말합니다.
Example01
A : Delegate, B : Delete
A > 'g'삭제 > 'a'삭제 > B
Levenshtein distance=2
Example02
A : Process, B : Professor
A > 'c'를'f'로 대체 > 'o'삽입 > 'r'삽입 > B
Levenshtein distance=3
참고 ㅣ Levenshtein distance
이미지 참조 : https://jybaek.tistory.com/793
Listener는 피라미드 형식으로 구성된 bidirectional LSTM(BLSTM) 인코더이며 입력 시퀀스 x로부터 특징을 뽑아냅니다. Speller는 attention-based 디코더에서 h와 s로부터 컨텍스트 벡터 c를 생성하고 이를 기반으로 Grapheme 캐릭터 y를 뽑아냅니다. 이런 과정에 <\sos>와 <\eos>를 특별한 토큰으로 사용하는데 각각 special start-of-sentence, end-of-sentence를 나타냅니다.
작성자 : 16기 장준원
References
출처의 검색일은 모두 2021.10.30.-2021.10.31이다.
[15기 안민준]
1. CTC의 엡실론 토큰이 음성 공백을 채워주기 위한 의도라고 강의에서 설명되었습니다. 혹시 음성 인식 중 '띄어쓰기' 등을 인식하고자 하는 시도가 있었을지, 그리고 있었다면 이 경우엔 엡실론 토큰을 사용했을지 궁금합니다.
2. LAS 의 인코더는 피라미드 형식으로 인코딩 된다고 되었는데, 이 경우 음소가 붙어 있는 등 인접한 음 끼리의 정보가 약간 소실되는 문제가 없는지 궁금합니다.
[15기 황보진경]
Audio Auto Tagging이란 오디오 신호에 존재하는 다양한 이벤트들을 detect하는 multi-label classification task이다. 이 때 사용하는 metric이 LRAP이다. rank 정보를 이용하여 확률을 계산한다.
모든 타임스텝에 대해 라벨링을 할 수 없기 때문에 alignment가 필요한 seq-to-seq task에 사용할 수 있는 Loss이다.
위에서 구한 확률을 이용하여 시간을 고정하고 나올 수 있는 token들의 complete path에 해당하는 확률을 모두 더하면 Likelihood를 계산할 수 있다.
Edit distance라고도 불리며, 두개의 문자열이 같아지기 위해서 몇 번의 연산(삽입, 삭제, 대체)을 수행해야 하는지를 계산한다.
[15기 조효원]
1. self-loop : 자기 자신을 반복합니다.
2. left-to-right : non-blank 레이블을 순방향으로 하나씩 전이합니다. 역방향은 허용하지 않습니다. non-blank를 두 개 이상 건너뛰는 것 역시 허용이 안 됩니다.
3. blank 관련 : blank에서 non-blank, non-blank에서 blank로의 전이를 허용합니다.
해당 rule들로 구성된 all-path 중 특정 path의 등장확률은 Forward와 Backward Computation의 곱 으로 구한다. 는 t시점에 특정 레이블 k가 등장하는 path의 확률, backward는 뒤에 나올 수 있는 path의 확률을 의미한다. 이를 이용해 likelihood를 구할 수 있다.
[15기 이성범]
Audio Auto Tagging : 오디오 신호에서 발생하는 이벤트 종류를 찾는 Task
Speech Recognition : 사람이 말하는 음성 언어를 컴퓨터가 해석해 그 내용을 문자 데이터로 전환하는 Task
[16기 김윤혜]
1. CTC의 alignment는 음성의 길이에 맞춰서 모든 time sequence에 텍스트와 Blank가 서로 독립적으로 채워지는 것이 맞나요? 그렇다면 CTC는 전부 RNN 기반의 모델을 사용하는 것인가요?
2. LAS 모델의 Listener를 피라미드 형식으로 구성하는 이유가 무엇인지 궁금합니다.