Thursday, February 15, 2018

논문 리뷰 - Learning to pinpoint singing voice from weakly labelled examples (ismir 2016)




오늘 볼 논문은 ISMIR 2016에서 best oral presentation을 받은 논문입니다. (링크)

여러 번 참고할일이 있었던지라 정리 목적으로 올립니다. 이 논문의 저자는 오스트리아에서 음악쪽으로 딥러닝 연구를 쭉 해온 Jan Schluter입니다. 최근에 박사 졸업을 했죠. Lasagne 개발에도 적극적으로 참여한 사람입니다.

이 논문은 연구와 엔지니어링이 반반 섞여있는 재밌는 논문입니다. 그리고 각 모듈을 소개한 섹션 3을 Ingredients, 이를 조합한 알고리즘을 섹션 4 Recipe라고 이름을 붙였네요. 

문제 정의

전형적인 weakly labelled learning중 하나죠. 음악은 대체로 트랙 전체로 라벨링이 많이 됩니다. 예를 들어 특정 곡에 보컬 유무를 퉁으로 라벨링하는거죠. 그리고 이렇게 라벨링된 데이터를 이용해 프레임마다 보컬 유무를 찾는것이 주어진 문제입니다.

방법으로는 Saliency map과 knowledge distillation (논문에서는 multiple-instance learning이라고 표기)을 사용했고 기본적으로 컨브넷을 사용합니다.

3. 재료

3.1 보컬 탐지용 컨브넷

오디오: 22050 Hz로 다운샘플링한 뒤에..

X = abs(STFT(X, n_fft=1024))
X' = log(1+X)

를 하고 추가적으로 전체 주파수 대역 중 저주파수(8kHz까지, 총 372 주파수 빈)만 이용합니다. 보컬 에너지가 분포하는 대역을 고려한 전처리입니다.

컨브넷 구조를 봅시다. 참, 튜플은 (time, frequency)순서입니다. 그리고 모든 컨브넷은 바운더리에서 'valid'로 설정되어있습니다. Batch normalization이 모든 레이어에 적용되고 액티베이션은 LReLU(alpha=0.01)을 사용했습니다. 

conv1 = Conv2d(64, 3, 3)(input) // 입력은 372 주파수 빈
conv2 = Conv2d(128, 3, 3)(conv1)
mp1 = MP2D(3, 3)(conv2)
conv3 = Conv2d(128, 3, 3)(mp1)
conv4 = Conv2d(64, 3, 3)(conv3) // 주파수축이 118개가 됨
conv5 = Conv2d(128, 3, 115)(conv4) // 주파수 축이 4개가 됨
mp2 = MP2D(1, 4)(conv5) // 주파수 축이 1개가 됨
dense1 = Dense(256)(mp2)
dense2 = Dense(64)(dense1)
output = Dense(1, activation='sigmoid')(dense2) // 출력


conv1, conv2의 결과로 (5, 5)크기의 보컬 패턴을 탐지합니다. 그리고 conv3, conv4가 이를 조합하죠. conv5는 최종적으로 주파수축에서 쭉 모으는 역할을 합니다. 사실 여기서 바로 conv2d(128, 3, 118)을 해서 주파수축 길이를 1로 만들어줘도 결과는 비슷할것같지만, 여기에서는 그렇게안하고 max-pooling을 한번 더 했습니다.

학습과정에서는 pitch-shifting, time-stretching을 적용해 데이터를 키웠습니다. 그리고 모델의 시간축 크기는 1.6초밖에 안됩니다 (115프레임). 그런데 사용한 데이터는 30초길이입니다. 따라서.. (다음섹션!)

3.2 Multiple-instance learning

전체 음원(30초)의 라벨을, 랜덤으로 선택한 1.6초에 그대로 적용하고 이를 이용해 학습합니다.

비슷한 방법으로 위의 코드를 거의 그대로 사용하지만, 입력을 1.6초가 아니라 30초 전체를 받고 모델 막바지에 시간축으로 길게 max-pooling을 하는 방법도 있겠죠. prediction 관점에서 보면 그게 맞습니다. 30초중에 어느 구간이건 보컬이 존재하면 activation이 크게 일어날테고, 따라서 보컬이 존재한다고 판단하면 되니까요. 그렇지만 max-pooling 레이어는 backprop에서 따져보면 가장 입력이 크게 들어온 곳으로만 gradient가 흘러가는데 이렇게하면
 - 데이터 및 연산 관점에서 비효율적입니다: 왜냐하면 forward pass에서는 30초 구간을 전부 이용하지만 backward pass에서는 1.6초의 정보만 이용하기 때문입니다.
 - 오버피팅이 일어날수 있습니다. 본문에는 조금 대충 적어놓았는데, 일단 데이터 활용 관점에서 비효율적이므로 오버피팅에 취약하겠죠. 최악의 경우 각 곡마다 계속 같은 1.6초 구간을 사용하게 되면 전체 트레이닝 데이터가 (* 1.6/30)으로 줄어드니까요.

본문엔 없지만, 장점은 없을까요? 보컬이라는게 30초에서 일부만 나타나게 마련인데, 이렇게 하면 학습에서 자연스럽게 보컬이 존재하는 구간을 선택하는 장점이 있을것같습니다. 다만 30초에서 1.6초는 너무 짧으니 만일 prediction rate이 1/1.6초 라면 3.2초나 4.8초를 입력으로 사용하는식의 방법은 어떨까싶네요.

3번째 문단이 중요한 내용인데.. 이제 논문이 조금 산만하게 쓰여진것같다는 생각이 드는군요. 일단, 1.6초짜리로 개별적인 학습을 진행하되 최종적으로 출력한 예측값 중 negative는 확신을 갖고 사용하되 (왜냐면, 30초 전체가 non-vocal이라면 그 중 어떤 1.6초를 골라도 non-vocal이니까요) positive는 (30초중 사실은 일부만 vocal일것이므로) 더 엄한 잣대를 적용해서 vocal로 판단하는거죠. 그리고 이렇게 prediction한것을 새로운 라벨로 생각하고 다시 학습을 진행하는 것 (~= knowledge distillation)입니다. 아니, 본인이 뒤에서 활용한 방법인데 이렇게 마치 참고사항처럼 말하고 지나가다니! 여러분은 이러지 않길 바랍니다.

3.3 Saliency mapping


Saliency mapping 은 입력신호 중 어떤 부분이 최종 prediction에 끼치는 영향을 표시하는 것입니다. 본문의 그림 1에서 (d)를 보면 됩니다. 즉, 보컬이 있다고 판단을 내리는데에 큰 영향을 끼친 부분을 강조해서 표시하는거죠. 약간 스포일러가 나오는데, 입력 스펙트로그램인 1-(a)와 이걸로 구한 saliency map인 그림 1-(d)를 비교해보세요. 꼬불꼬불한 선만 남죠? 학회장에서 데모로도 보여줬는데, 결국 이 보컬 디텍터는 꼬불꼬불한 선; 즉 주파수 모듈레이션, 즉 바이브레이션, 혹은 일정하지 않은 피치를 보여주는 하모니를 찾습니다.


4. RECIPE

4.1 Naive training

일단, 그동안 설명한 방식으로 컨브넷을 쭉 트레이닝하는겁니다.
그럭저럭 작동합니다.
그리고 이를 기반으로 saliency map을 그릴 수 있습니다.

4.2 Overshoot correction

일단, 그림만 보면 overshoot랑 비슷하지만 실제로 일어나는 현상이 overshoot라고 부를수있는지는 잘 모르겠습니다. 이 부분은 boundary correction이라고 부르면 이해가 쉽습니다. 섹션 제목이 위트를 집어넣으려는 과욕의 결과물이 아닌지..

- 1.6초중에 마지막 0.1초에만 보컬이 아주 조금 포함된 경우가 있겠죠.
- 또는 반대로 처음 0.05초에만 보컬이 포함된 경우도 있을거에요.

이런 애들도 전부 보컬이 존재한다고 prediction하는것을 관찰했습니다 (그림 2). Max-pooling으로 subsampling을 수행하는만큼 당연한 결과입니다. 그림 2의 (c)와 (d)를 비교해보시죠. 이 관찰 결과를 이용해 나중에 전체 시스템을 업그레이드할 예정입니다.

4.3 Self-improvement

4.1에서 사용한 컨브넷을 CNN-알파라고 부르죠. CNN-알파의 예측값은 당연히 완벽하지 않지만, 30초 전체를 1 혹은 0으로 퉁치는것보다는 세밀하므로 이를 이용하자는것입니다. 이에 대해서는 다시 한번 언급합니다. knowledge distillation을 참고하시길.



그리고 saliency map도 뭔가 사용하고싶었던거죠. 그림 2의 (f)를 보면 얘도 뭔가 정보가 있는것같잖아요. 그래서 최종적으로는 이 섹션 맨 마지막 문단을 보면..

- 그냥 학습을 한다 (CNN-알파)
- CNN-알파의 출력값을 예측하는 컨브넷을 하나 더 학습한다 (CNN-베타)
- CNN-베타의 saliency map을 예측하는 컨브넷 CNN-감마를 학습한다. 끝! 입니다.


5. 실험

일단 잘 됩니다. 그런데 5.2, 5.3에서 하는 일을 정확히 정의하지 않은게 아쉽군요. 짐작해보건데..
- temporal detection : 시간축에서 더 세밀하게 라벨링된 데이터셋(0.1초단위일거에요)을 이용해서 보컬 유무를 탐지하고 이를 평가
- spectral localization: 특정 주파수 빈의 보컬 유무를 탐지. 따라서 groundtruth를 확보하기 이해 (보컬) 음원분리에서 사용하는 데이터셋을 이용해서 평가.

5.2 Temporal detection results

CNN알파, 베타, 감마로갈수록 성능이 증가합니다.

5.3 Spectral localization results

얘는 사실 논문에 나온대로 "not an established task"입니다. 토의는 생략하겠습니다.

6. 토의

그림 3을 자세히 보시길 권합니다. 전체 시스템의 예측이 어떤식으로 진행되는지, CNN 알파-베타-감마가 어떤 진전을 보이는지 잘 보여줍니다.



그 외 코멘트

- 30초 전체를 입력으로 받고, MP대신 average-pooling으로 시간 전체를 aggregation하면 어떨지 궁금하군요.
- discussion에는 최종적인 sigmoid output에서 threshold를 0.5로 잡는게 어쩔수없는 임의의 결정이라고 써있습니다. 맞는 말이죠. 그런데 제 의견은 이걸 잘 정하는게 아니라, 입력 데이터 - 배치를 구성할 때 - positive/negative를 50:50으로 구성해서 기본적인 분포를 맞춰주는것으로 문제를 해결하고 prediction에서는  0.5를 기준으로 반올림해도 괜찮지 않나 합니다.
- 본문에는 여기에는 자세히 안써있지만 이 보컬 디텍터는 위에서 말한대로 꼬불꼬불탐지기이기때문에 기타나 관악기 소리가 들어오면 false positive문제가 생깁니다. 해결방법은 저도 모릅니다. 
- 이런식의 weakly labelled problem은 오디오에서 흔히 볼수있는 문제입니다. 음성이나 오디오 이벤트 탐지, 새소리 탐지 등.. 비슷한 경우가 많죠. 실질적으로 사용할 수 있는 다양한 팁을 제시해주는 좋은 논문입니다.

No comments:

Post a Comment