Friday, September 29, 2017

Q&A - 다성음 인식 관련





아래의 질문을 받았습니다. 

* * *

저희는 전자 피아노를 연주 했을 때 다성(polyphony)음을 인식하여 맞았는지, 틀렸는지를 분석해 주는 연구를 진행중입니다. 다성음에 관한 자료가 많지 않아 다양한 논문을 리서치 하던 중, (..중략).. 음악 인식에 관련되어 몇가지 질문이 있어 이렇게 메일을 보내게 되었습니다.
1. (첨부파일 중 magnitudeSpectrum.py)
사전에 연주한 음악 파일(첨부한 파일 중 butterfly.wav)을 fft를 사용하여 frequency와 power(dB)로 분리해 특징을 추출하여 그 결과로 첨부한 사진과 같은 그래프를 얻을 수 있었습니다.
여기서 혹시 전처리와 특징값 추출이 올바르게 되었다는 사실을 검증할 수 있는 방법이 특별히 있는지 궁금합니다.

2. 그 후 NMF(non-negative matrix factorization, 비음수 행렬 인수분해)를 사용하여 다성음 인식을 가능하다는 정보를 얻게 되어 이를 분류기로 사용하여 학습을 진행할 예정입니다. 하지만 정확한 검증과정이 없어 혹시 NMF가 분류기로 사용하기에 적절한지 궁금합니다. 혹시 해당 방법이 적절하지 않다면 적절한 분류기를 추천해 주실 수 있으신가요?
실제 이렇게 하여 다성음간 비교를 하여 일정확률 이상으로 일치여부를 판별하고자 합니다. 방향성이나 구현방법이 맞는지 조언 부탁드리고, 추가로 해주실 말씀 있으시면 의견부탁드립니다.

* * *

받은 소스코드는 아래와 같습니다.


import scipy.io.wavfile as wavfile
import numpy as np
import pylab as pl

rate, data = wavfile.read("Butterfly.wav")
t = np.arange(len(data[:,0]))*1.0/rate

#Original Signal graph
fig = pl.figure()
g1 = fig.add_subplot(221)
g1.set_title("Original signal")
g1.plot(data)


for i in range(0,180778):
  if(data[i,1]>0):
      start = i
      break
print(start)
temp = np.abs(np.fft.rfft(data[start:180778,1]))

p = [20*np.log10(x) if x>=1 else 1 for x in temp]


f = np.linspace(0, rate/2.0, len(p))

g2 = fig.add_subplot(222)
g2.set_title("FFT")

g2.plot(f, p)
# g2.xlabel("Frequency(Hz)")
# g2.ylabel("Power(dB)")

pl.show()


그럼 간단히 첨삭해볼까요?

첨삭

파트 1


import scipy.io.wavfile as wavfile
import numpy as np
import pylab as pl

rate, data = wavfile.read("Butterfly.wav")
t = np.arange(len(data[:,0]))*1.0/rate

#Original Signal graph
fig = pl.figure()
g1 = fig.add_subplot(221)
g1.set_title("Original signal")
g1.plot(data)

좋습니다.

파트 2


for i in range(0,180778):
  if(data[i,1]>0):
      start = i
      break
print(start)
temp = np.abs(np.fft.rfft(data[start:180778,1]))


음악 파일에서 앞에있는 묵음 구간을 제외하려는 코드같네요. 그런데 실제 음원은 잡음이 껴있어서 이렇게 샘플 기반으로, 기준을 0으로 잡아서 하면 잘 작동하지 않습니다. 음성의 경우에 음성이 있는 구간을 탐지하는 (Voice activity detector, VAD) 아주 중요한 문제죠. 프로젝트에서 쓸법한 간단한 방법으로는 1. 신호를 프레임으로 나누고 (예) 2. 프레임마다 평균 에너지를 구하고 3. 그걸 plot해서 4. 눈으로 보고 적당한 기준값을 정하면 됩니다.

그 뒤엔 np.fft(rfft)를 하셨는데요, 이렇게 하면 신호 전체에 대해 FFT를 수행합니다. 하지만 실제로 필요한건 짧은 프레임에 대해 계속 주파수 분석을 하는 short-time Fourier transform입니다.

마지막으로 180778은 butterfly.wav의 샘플 개수인가요? 이건 곡마다 달라질테니 변수로 지정하는편이 좋겠죠.

파트 3 


p = [20*np.log10(x) if x>=1 else 1 for x in temp]

이 부분을 보니 오디오 샘플 x가 웨이브파일에서 그대로 값을 읽어온 int로 이루어진것같군요. 일단 계산 자체는 맞습니다.

하지만 이 연산을 이렇게 수행하는것보다 x=np.array(x)로 바꾸고 p=np.log10(np.maximum(x, 1))를 하는게 좋겠죠.

그리고 p는 좋은 변수 이름은 아니네요.

파트 4



f = np.linspace(0, rate/2.0, len(p))

g2 = fig.add_subplot(222)
g2.set_title("FFT")

g2.plot(f, p)
# g2.xlabel("Frequency(Hz)")
# g2.ylabel("Power(dB)")

pl.show()


맞습니다.

조언

위의 작업을 STFT로 수행해야 시간별로 어떤 일이 일어나고있는지 알 수 있습니다.

NMF와 다성음 인식

일단 쉬운 주제는 아닙니다. 다성음 인식은 아직 풀린 문제가 아니고 기존에 논문으로 나온 인식기를 구현하는 것도 배경지식이 필요합니다.

아주 간단한 작업부터 시작하시길 권합니다 (항상 마찬가지죠). 예를 들어 '도.wav'와 '솔.wav'를 구별할 수 있게 학습이 가능한지 해보시고, 그 뒤엔 이것을 도레미파솔라시 7개 음을 구별하는걸로 확장해보고, 그런 식이죠.

그리고 NMF는 여기서 분류기가 아니라 특징값 추출기입니다. NMF를 np.abs(np.log10(STFT))에 적용한 뒤 나온 값을 다시 분류기에 넣으셔야합니다.

마지막으로 모든 작업은 기본적인 머신러닝의 룰을 따라야합니다. 제 게시물 등을 참고하셔서 오버피팅, 학습/시험셋 나누기 등을 수행하셔야합니다.

Thursday, September 14, 2017

튜토리알 논문을 하나 썼습니다.

"Music information retrieval을 위한 딥러닝"이라는 제목으로 튜토리알 논문을 하나 썼습니다. 어제 아카이브에 올라왔네요.  논문 링크 | 코드 링크
핵심만 쉽게 설명하려고 애를 많이 썼습니다. 재미있게 읽어주세요.


Sunday, August 27, 2017

저널 논문, 리뷰, 스페셜 이슈

오늘은 잡담을 좀 하고싶네요. 박사과정에서 지금 중요한 때라서요.

제가 있는 학교에서는 학교나 학과에서 박사학위에 특별히 SCI저널이라든지 하는 조건이 없습니다. 특히 컴공에서는 점점 이런 추세로 바뀌고있죠. 그렇지만 제 지도교수는 저널 논문을 나름대로 조건으로 따지는 편입니다. 예외인 경우가 무지하게 많지만요.

특히 저는 펀딩 기간보다 빨리 졸업하려고 하다보니 이런 조건을 무시하고 졸업 논문을 작성하겠다고 설득하기가 어려웠죠. 요즘 이 분야가 사람들이 학위과정 졸업이나 프로젝트 실적, 테뉴어 심사같은 이유가 아니면 굳이 저널 논문을 쓰질 않아서 저는 좋은 저널 논문이 어떤건지도 잘 모르는 상태에서 저널 논문을 썼습니다.

그런데 어쩌다보니 주제 두개를 억지로 묶은 이상한 논문이 나왔고, 스페셜 이슈라 제출일/심사종료/발간 등 날짜가 정해진 곳에 제출을 했습니다. 며칠 전, 예정보다 일주일가량 빠른 리뷰를 받았는데 불안했던 예감대로 Major revision and resubmit -- in 2 weeks 라는 결과가 나왔네요.

저널 논문은 즉시 수락/minor revision/major revision/reject 정도로 결과가 갈립니다. 바로 수락되는 경우는 거의 들어본 적이 없고, minor revision이면 리뷰어가 언급한거만 조금 고치거나 하면 수락되죠. reject은 말 그대로 이 연구는 우리 저널에선 실릴 가능성이 없다는 거구요. 제가 받은 major revision은 고칠게 많지만 리젝주긴 미안하고 약간의 희망은 있다, 는겁니다.

그런데 이게 스페셜이슈를 만나면 조금 달라집니다. 스페셜 이슈는 정해진 날짜에 논문집이 나와야하니 편집자나 리뷰어도 논문이 넘치는 상황이 아닌다음에야 가급적 희망의 불씨를 살려두고싶어하죠. 그래서 major revision이라도 잘 고치면 한번쯤 더 minor revision을 하고 수락이 된다는 시나리오가 실현되길 바라고있습니다.

Major revision이면서 2주밖에 시간을 안주는건 좀 이상한건데 이것도 스페셜이슈 발간 일정때문에 그런것으로 생각합니다.

제가 받은 리뷰는 공통적으로 동떨어진 주제 두개가 논문 하나에 있는것이 이상하다는 내용입니다. 물론 저도 인정하구요. 그래서 급하게 전체 11페이지 분량에서 3페이지를 삭제하고 남은 내용을 발전시켜보고있습니다. 2주 안에 다시 낼 수 있을것 같긴 한데, 잘 될지 모르겠네요.

여기까지입니다. 나중에 저 읽으라고 쓰는 글이지만 공개로 작성합니다. 

Wednesday, July 5, 2017

유학 준비 - 자기소개서와 연구계획서 작성법

간결하게 쓰겠습니다.
  • 자기 소개서
    • Q. 자기 소개서에 쓸 내용이 너무 없어요.
      • A. 자기 소개서에 쓸 내용을 만들었어야합니다. 공부를 했다면 그 내용을 정리해서 인터넷에 올리세요. 연구를 도운게 있다면 공저자로 이름이 들어있겠죠? 그걸 사용하세요. 뽑는사람 입장에서는 이 사람을 뽑았을 때 혹시나 깽판치거나 완전 말아먹을수도 있다는 걱정을 항상 하게됩니다. 따라서 그런 불안감을 줄여주려면 근거 없는 경험을 나열하는게 아니라 신뢰할 수 있는, 권위 있는 사람이나 소속이 연관된 뭐라도 하셔야합니다.
      • 지금까지 한게 없으면 지금부터라도 하세요. 1달이라도 의미있는걸, 그리고 문서화할 수 있고 설명이 가능한걸 뭐라도 하고 그걸 적으세요. 만일 수 개월의 시간이 있다면 분명 의미있는 활동을 할 수 있습니다. 
    • Q. 자기 소개서를 교수가 읽나요?
      • A. 읽는다고 가정하고 쓰세요. 
    • Q. 주의사항
      • A. 본인이 참여한 프로젝트나 기관을 너무 열심히 설명하지 마시고 본인이 참여한 이유, 맡은 역할, 배운 내용을 쓰세요. 즉 본인이 뭘 하셨는지를 적으셔야합니다. 자기소개서는 내 예전 직장 소개서가 아닙니다.
  • 연구계획서
    • Q. 전 아는게 없는데 연구계획서를 어떻게 쓰죠? 
      • A. 연구계획서를 쓸 수 있도록 해당 분야의 논문, 서적, 발표자료 등을 면밀히 찾아보시길 바랍니다.
    • Q. 대학원 다니는 동안 연구계획서대로 진짜 연구를 수행해야 하나요?
      • A. 아뇨, 실제로 연구하는 내용은 엄청나게 바뀔겁니다. 그렇지만 현 시점에서 최대한 노력해서 쓰셔야합니다.
    • Q. 연구계획서를 교수가 읽나요?
      • A. 읽는다고 가정하고 쓰세요.
  • 그 외
    • 자기소개서에서는 본인의 과거를 소개합니다. 어지간하면 최근 몇 년만 적으세요.
    • 연구계획서에는 본인이 미래에 - 향후 몇 년 간 - 뭘 할지 적습니다. 
    • 따라서 두 문서는 내용이 겹치거나 같은 말을 반복하지는 마세요. 그러나,
      • 과거에 나는 이런이런걸 했고, 이건 나의 어떠한 면을 보여주며, 내 관심 분야를 이렇게 공부해왔고,
      • 미래에도 이걸 계속하고 싶으며 이러이러하게 열심히 잘 할것이니 뽑아달라.
    • 로 일맥상통해야 합니다.
    • 연구계획서에 적힌 연구 내용은 당연히 지원하는 학교와 잘 맞아야합니다. 교수의 논문 목록을 찾아보시면 최근 관심분야가 나오겠죠.
    • 자기소개서나 연구계획서가 당락을 가르는지 관심갖지 마세요. 그냥 열심히 준비하세요. 교수마다 다르고, 학교마다 다르고, 기분따라 다릅니다. 남들이 어떻게 하는지, 어떻게 했는지는 전혀 중요하지 않습니다.

Wednesday, June 14, 2017

음성/음악신호+머신러닝 초심자를 위한 가이드 [4편]

음성/음악신호+머신러닝 초심자를 위한 가이드 전체 게시물은 여기를 클릭하세요.

데이터 수집

이번엔 데이터 수집을 주제로 글을 쓰겠습니다.

기존 데이터셋 사용

음악 데이터 셋은 http://www.audiocontentanalysis.org/data-sets/ 여기에 잘 정리되어있습니다.
오디오 관련 데이터셋은 좀 더 중구난방인데, 
- Urbansound8K by Justin Salamon
- AudioSet by Google, 2017 (유튜브 주소만 제공하고 직접 크롤링해야함. 어떻게? Fuel, YouTube-dl)
- DCASE audio detection by Queen Mary University of London
- Bird Audio Detection by Queen Mary University of London

이 정도가 생각나네요.

데이터 수집

살다보면 힘들고 험한 길을 가야할 때가 있죠.
freesound에서 직접 크롤링해서 뭔가 할 수 있지 않을까? 하는 희망을 한번쯤은 품어볼 필요가 있습니다.
아래 코드를 참고하세요. 주소는 여기





데이터 정리

데이터를 모으는게 다가 아니죠. 일단, 키워드로 검색을 했으니 특정 소리가 들어있는 음악 파일을 잔뜩 받았다고 해봅시다. 뭘 해야할까요?


  • Normalisation
import numpy as np
import librosa

x = librosa.core('event1.mp3', sr=None, mono=True)
x = x / np.max(np.abs(x))

  • Trimming
앞뒤에 조용한 구간이 있다면 싹둑 잘라주는편이 좋겠죠. 이건 어느정도 대애충 감으로 하는게 편할것같네요. 저라면, hann window같은걸 씌우고, 각 윈도에서 평균 에너지를 구해서 (np.mean(np.abs(windowed_source_x) ** 2)), 그 윈도 별 평균 에너지를 기준으로,아무런 음향 이벤트가 안일어나는 첫 N개의 윈도와 마지막 M개의 윈도를 날리겠습니다.

  • Augmentation
데이터가 부족하면 뻥튀기를 하고싶겠죠? 방법은 여러가지가 있습니다. 적당한 구간에서 pitch shift / time expanding을 하시면 무난할테고, 다른 잡음을 적당히 섞어주는것도 좋겠죠 (x = x + gain * noise). 이 정도만 해도 벌써 10배이상 데이터가 늘어날 것 같네요. 


  • 주의사항
음원이 매우 길다거나해서 여러 개의 학습 데이터 샘플로 쪼개서 쓰는 경우에, 같은 음원에서 나온 샘플 여러개가 training/validation/test 셋에서 섞이지 않도록 주의합시다.


이상입니다.

Monday, June 5, 2017

WWDC 2017 - Apple Music, MusicKit API

Apple Music 관련 몇 가지 뉴스가 나왔네요.
  • 애플 뮤직이 런칭한게 약 2년 전입니다. 2015년 6월 30일에 서비스를 시작했군요. 1년 반이 2016년 12월에 유료 구독이 2천만명을 넘었다고 기사가 나왔었고 오늘은 2천 7백만명이 넘었다고 발표했습니다. 업계 1위인 Spotify가 5천만명을 발표했죠. 둘 다 여전히 성장을 하고 있습니다. 
    • 참고로 Spotify는 아직까지 적자 기업이지만 음악 비즈니스 전체의 파이가 커지고 있는 것 등을 감안하면 미래가 그렇게 어둡지는 않아보입니다. 
    • 역시 사견입니다. Spotify는 광고 기반 무료 감상때문에 적자인건데, 이게 음악 시장 전체를 악화시킨다고 생각합니다.
  • MusicKit 이라는 새 API를 발표했군요. iOS 11의 신기능입니다. 이걸 쓰면 애플 뮤직 유저의 각종 정보 - 라이브러리, 개인화 추천 등에 접근이 가능하다고 하네요. 애플 뮤직은 안드로이드에서도 있으니 안드로이드용 API도 나오면 좋을텐데 딱히 언급은 없었습니다.
  • 역시 Spotify포함 기존 서비스에 많이 있는거죠. 소셜 기능을 추가했네요. '친구' 맺은 사람이 뭐 듣는지 나오고 그런거라고 하네요. 자세한 언급은 없었지만 연락처에 있는 목록 / 페북 친구 등등으로 연계해서 나올거같습니다.

국내 스트리밍 서비스도 재미있는 API를 많이 열면 좋겠습니다만, 경제적인 유인이 적으니까 안하는것이겠죠. 연구자, 종사자 및 음악을 좋아하는 사람으로서 매우 아쉬운 면입니다.

Friday, June 2, 2017

블로그를 하십시오.

독자가 컴공 대학원생이라고 가정하고 글을 쓰겠습니다. 아닌분들이 더 많겠죠? 본인의 상황에 맞는 조언인지 생각해보면서 읽으시면 되겠습니다.

블로그를 운영하면 생각보다 많은 사람들이 와서 봅니다.
그리고 연구는, 더군다나 취직은, '장사'의 속성을 지니고 있습니다.
아시다시피 그리고 컴공 분야 종사자들은 컴퓨터를 엄청 오래 합니다.

블로그에 논문을 설명해놓으면, 더 많은 사람들이 효율적으로 당신의 연구를 이해하게 됩니다. 그럼 더 많이 읽고 더 많이 인용하겠죠.
블로그의 좋은 글을 보면서 당신이 누군지 알게되고, 당신의 연구와 논문에 관심을 갖고 더 신뢰하게 됩니다.
블로그를 보면 독자는 당신의 연구 분야와 능력을 알게 되고, 더 낮은 기회비용으로 당신을 고용하려고 하겠죠.

모두 실제로 제게 일어난 일입니다. 저는 국문 블로그(여기), 영문 블로그, 깃헙 저장소 등으로 열심히 '영업'을 합니다. 지금보다 훨씬 영업할 껀덕지가 없을때부터 그랬습니다. 이건 제가 박사과정 시작하고 갔던 첫 번째 학회에서 (현재 DeepMind에서 일하는, AlphaGo와 Wavenet 논문의 저자) Sander Dieleman이 조언해준 덕분입니다. Sander도 Spotify x Convnet 게시물이 엄청난 인기를 끌어서 유명해졌고 그 결과로 딥마인드에서 면접 오퍼를 받았습니다. 저는 그런 스타급 연구자가 아니지만 현재 일하고있는 스타트업(버즈뮤직)에서도 제 블로그를 보고 연락을 줬고, 자문역으로 일하기 시작한 제이마플도 마찬가지입니다. 멜론에서도 연락이 왔었군요. 제가 런던에 있으니 더 용이한 것도 있겠지만 Mixcloud나 Kantar Media에서도 비슷한 연락을 받았습니다.

아마 제가 블로그/깃헙을 안했다면 아무 일도 일어나지 않았을 것입니다. 여러분, 블로그를 하세요. 엄청난 도움이 됩니다. 남들도 하루종일 웹서핑 하거든요.