Saturday, March 3, 2018

논문 리뷰 - SINGING VOICE DETECTION WITH DEEP RECURRENT NEURAL NETWORKS (ICASSP 2015)



2015년에 나온 논문으로 음악에서 음성이 있는지를 찾는 singing voice detection 관련 논문입니다. [링크]

지난번에 소개한 ismir 논문과 같은 방식으로 프레임별로 보컬이 있는지를 탐지하는 문제입니다. 리뷰를 부탁받은지라 가끔씩 태클을 걸면서 리뷰하겠습니다. 2015년이면 MIR에서 딥러닝 논문이 서서히 나오기 시작할때죠. 전반적으로 실험 설계와 결과는 괜찮은데 결과 분석, 토의가 매우 부족한 논문입니다. 근데 원래 초반에 나온 논문이 다 좀 그랬습니다.

초록

요약: Bi-LSTM으로 보컬 유무를 찾는다.
태클: 
"The BLSTM-RNN contains several hidden layers, so it is able to extract a simple representation fitted to our task from low-level features"

그런데,
- "Bi-LSTM에 은닉층이 여러개 있기때문에"인지는 알수 없구요, 
- "simple representation"이라고 했는데 뭐가 어떻게, 왜 simple이라는건지 설명 못했을것같구요. 
그래서 저라면 이렇게 바꿀것 같네요.
"The stacked hidden layers of Bi-LSTM learns representations to solve the given task"

그런데 이렇게 바꾸고난뒤엔 이 문장을 그냥 지울것같습니다. 하나마나한 말이라..

1. Introduction and previous work

요약: 기존에는 MFCC, PLP, LFPC등을 이용했다. Lehner에 의하면 MFCC 구할때 파라미터를 최적화하는게 성능에 중요하더라. [10]에 의하면 비브라토(주기적인 주파수의 변화, frequency modulation)과 트레몰로(시간에 따른 amplitude의 변화, amplitude modulation)가 중요한 특징이라고 하는군요.
[5]는 엄청 많은 low-level feature를 사용했다고 합니다. [7]에서는 바이올린, 플룻, 기타같이 혼동하기 쉬운 악기와 목소리를 잘 구별하는 특징값을 골라서 false positive를 줄였군요.

2. RNN and LSTM

RNN과 LSTM소개입니다. 요약은 생략합니다.

3. System overview


그림 3입니다. 데이터 전처리를 간단히 코드로 나타내면 다음과 같습니다. 아... 이부분 설명을 좀 더 명확하게 쓰면 좋을텐데, 좀 아쉽군요. 그러니까...
 - HPSS 1, HPSS 2의 역할이 명확하지 않고
 - 각종 변수가 [ms] 단위로만 나와있는데 실제로 n_win이 몇개의 샘플인지, n_freq이 몇개인지도 명시를 해야하고
 - 저 그림에서 double stage HPSS를 더 자세히 그렸어야하고
 - 왜 보컬 성분이 enhance되(ㄴ다고 생각하)는지 안써놨고
등등의 문제가 있습니다.


# PREPARE TRAINING DATA
src, sr = load('file.wav', sr=16000)
# First HPSS
src_p_1, src_h_1 = HPSS_ONO(src, n_win=4096) # returns percussive/harmonic parts each
# Second HPSS
src_p_2, src_h_2 = HPSS_ONO(src_p_1, n_win=512)


def compute_mel_feature(src):
    SRC = np.abs(STFT(src, n_win=512))
    mel_bank_matrix = freq_to_mel(freq=16000, n_freq=n_mels=40) # size: (257, 40)
    SRC_mel = mel_bank_matrix.transpose() * SRC   # matrix multiplication 
    SRC_mel = 10 * log10(SRC_mel)  # decibel scaling
    # Assume there're X_h_mean, X_h_std, X_p_mean, X_p_std from the training data,
    # which are in a shape of (40, )
    mean, std = load_suitable_stats() # for each SRC_mel_{p_1, p_2, h_1, h_2}
    return (SRC_mel - mean) / std  # normalisation per mel band

SRC_MEL_P_2 = compute_mel_feature(src_p_2)
SRC_MEL_H_2 = compute_mel_feature(src_h_2)


설명을 보니 src_p_2, src_h_2가 결과가 잘 나와서 이걸 쓰기로 했습니다. 결과적으로 각 프레임마다 80차원의 벡터(40개의 mel 밴드 x 2)가 나옵니다.
이제 여기에 Bi-LSTM을 적용해야죠. 그런데 엄청 중요한 파라미터가 설명이 안되어있네요. Bi-LSTM의 time step이 명시가 안되었습니다. 이건 치명적인 문제인데요, 왜냐면 이 논문에서 LSTM을 쓰는 이유는 우리가 구하고자하는 p_vocal, 즉 각 프레임별 보컬 성분이 존재할 확률이 주변 맥락(context), 즉 주변 프레임에 영향을 받는다는 (합당한) 가정을 한 결과이기 때문입니다. 주변 frame을 대체 몇개나 봐야하는지가 중요하겠죠. 아마 섹션 4.2에서 트랙을 7초씩 썼다고 나오는데서 힌트를 찾아야할것같군요. 그러면 대략 512-STFT에 hop이 256이므로 7/(256/16000)=218.75개쯤 프레임을 쓴것같네요. 흠.. 이정도면 굉장히 긴 time-step이죠.


# MODEL
inp = Input(shape=(218, 80))
x = LSTM(80, bidirectional=True, return_sequence=True)(inp)
x = LSTM(30, bidirectional=True, return_sequence=True)(x)
# LSTM이 더 많으나 생략
output = Dense(1, activation="sigmoid", per_time_step=True)(x)  # shape: (218, )

model = Model(input=inp, output=output)

4. Results

..잘 나왔습니다.


제 분석

  • 제안한 방법은 다소 복잡하고 특이한 오디오 신호 전처리와 여러 층의 LSTM으로 구성되어있어서 성능 증가가 무엇때문인지 알기가 어렵다는 단점이 있네요.
    • 제가 추정하기로는 둘다 굉장히 중요할듯합니다. 일단 전처리에서 HPSS가 성능이 괜찮은 편이구요, 
    • Recurrent layer역시 중요한 역할을 했을텐데 그 이유는 [아래]에 있습니다.
  • (특히) 첫번째 레이어에서 ConvLSTM이 아니라 LSTM을 썼기 때문에 모델에 frequency invariance가 없다는 단점이 있습니다. 이래서 나중에 나온 Convnet이 더 좋은 성능을 보인것으로 생각됩니다.
  • 특징 추출 단계에 더 가까운 입력쪽, 초반 레이어가 하는일이 정확히 뭘까요? 일단 첫번재 레이어에 dense connection이 되어있고 Convolutional layer 아니고.. 각 프레임마다 dense connection이 있기때문에 결과적으로 한번에 여러 프레임을 보지 못합니다. 따라서 앞에서 언급한 비브라토나 트레몰로를 찾아낼 수 없는 구조입니다. 그럼 뭘찾은것일지는..저도 모릅니다.
    • [아래] 다만 이런 한계를 생각하면 결국 recurrence가 중요한 역할을 했을것같아요. 특히나 그림 4에 잘 나와있듯이, 보컬 성분 유무라는게 매 프레임마다 계속 바뀔리는 없고, 연속한 여러 프레임에 같은 groundtruth가 적용되는 경우가 많습니다. 
    • 그림4의 hidden layer 시각화 결과를 보죠. 사실, hidden layer 2만 봐도 이미 보컬 유무에 따라 hidden vector 값이 굉장히 다르거든요. 같은 이유로..

    • 같은 이유로, 여기 보시면 레이어가 늘어나면서 최고 성능은 좋아지고있지만 전체적으로 엄청난 차이가 아니죠? 따라서 depth를 늘리면서 증가한 비선형성이나 network capacity의 증가보다는 recurrent connection, 즉 주변 프레임의 결과를 합치는 것이 훨씬 중요한 역할을 한걸로 해석할수 있습니다. 이걸 정확히 알아내려면 각 프레임별로 작동하는, 즉 LSTM이 아닌 일반적인 deep feed-forward network를 같은 depth, width로 만들어서 실험을 돌려보면 되겠죠. 
  • 언급한 내용을 논문에 전부 요구하는건 어렵겠지만 하나도 실험 내지 언급이 되지않은것은 조금 안타깝네요. 그런데 이 논문이 아마 이 문제에 처음으로 LSTM을 쓴 논문이라 그럴거에요. 제 ismir 2016 논문도 지금 읽어보면 별 분석이나 통찰력따위 없을테니.. 아무튼, 당시 상황은 그렇고, 결과적으로 여전히 많은 의문이 남아있는 문제라고 할수있습니다.
여기까지입니다.


1 comment: