상세 컨텐츠

본문 제목

심심해서 해보는 딥러닝을 이용한 악기 소리 분류

프로그래밍

by ∫2tdt=t²+c 2019. 12. 2. 21:52

본문

음악을 듣다보면 참 신비로운 소리들이 많습니다. 피아노 소리처럼 익숙한 음색도 있지만, 스틸 드럼처럼 낯선듯 익숙한듯 뭔지 모를 음색들도 많지요. 종종 듣다보면 그거 참 신기한 음색인데 어떤 악기인지는 감도 안 잡힐때가 있습니다. 이것 참 지식인에 음악을 올려서 무슨 악기냐고 물어볼 수도 없고, 궁금함에서만 멈춰야한 적이 있었는데요, 딥러닝으로 핫한 시대에 맞춰 소리에 따라 악기를 분류해주는 모델을 만들어보면 좋겠다는 생각이 들었습니다. 이 포스팅은 그 기나긴 대장정의 첫 걸음입니다.

 

학습 데이터 만들기

딥 러닝 모델을 만드는 건 어렵지 않습니다. 데이터만 충분히 있다면요. 문제는 악기별로 음색을 분류해서 녹음해놓은 데이터셋을 찾아보기 어렵다는 것입니다. 단, 실제 악기를 녹음해놓은 데이터셋은 많지 않지만, 가짜 악기(virtual instrument, 가상 악기)는 널려 있습니다. 작곡이 컴퓨터의 영역으로 들어오면서 소프트웨어를 통해 악기의 소리를 합성하고자 하는 노력이 계속 있었는데, 이 노력 덕분에 오늘날 수많은 가상 악기 소프트웨어와 MIDI 시퀀서들이 탄생하게 되었습니다. 그래서 악기 하나 없이 컴퓨터만을 통해 음악을 만드는 것이 가능한 세상이지요.

따라서 가상 악기의 도움을 받아 악기별 음색 데이터셋을 만들기로 했습니다. 일반 MIDI표준에는 총 128개의 악기가 등록되어 있고, MIDI를 재생하는 프로그램들은 Soundfont라는 음색 데이터 포맷을 이용해 전자신호에서 128가지 악기 소리를 합성해냅니다. 따라서 이들을 최대한 활용하면 되겠습니다. 오픈 소스 MIDI 편집 프로그램인 MuseScore에서 이용가능한 soundfont 파일을 구했구요, Soundfont를 해석하여 소리로 재생하기 위해서 FluidSynth라는 오픈소스 라이브러리를 이용했습니다. 기나긴 삽질 후의 산출물만 정리해서 공유드릴게요.

다음은 FluidSynth를 이용해 128종류의 악기 + 46개의 타악기 소리를 생성하는 코드입니다.

위 코드를 돌리면 output.wav라는 파일이 생성될 겁니다. (생성된 output.wav 파일을 공유해드리고 싶으나 용량이 큰 관계로 Google drive 링크로 대체합니다) 그 파일에는 2초 간격으로 128종 악기별로 50개의 음이 저장되어 있고, 46개의 타악기 소리가 들어가 있을 겁니다. 이렇게 소리를 생성했으면 이를 처리하여 딥러닝 모델에 넣기 적합한 형태로 변형해봅시다.

wave파일에서 볼 수 있는 파동의 형태. 소리 분석에 적합하지 않음
ConstantQ 변환을 이용해서 변환된 피아노 소리. 2차원 이미지처럼 변환되었으므로 CNN모델을 적용할 수 있다.

 

wav는 매 순간의 음압을 측정하여 그 수치를 저장한 형태이기 때문에 그 자체로 음악을 분석하기에 적합하지 않습니다. 왜냐면 우리는 음의 높이와 세기를 듣는것이지 순간의 음압을 듣는게 아니기 때문입니다. 이 때문에 푸리에 변환과 같은 변환 기법을 이용하여 시간 축의 데이터를 주파수 축의 데이터로 바꿔줘야할 필요가 있습니다. 단, 푸리에 변환 대신 푸리에 변환의 사촌쯤 되는 Constant-Q 변환을 사용할 겁니다. 이 변환은 주파수 축이 로그 단위로 변환되고, 각 주파수에 따라 해상도가 다양하게 처리되기 때문에(저주파는 저해상도, 고주파는 고해상도) 음악을 처리하는 데에 푸리에 변환보다 유리하다고 알려져 있습니다. 저는 파이썬 librosa의 cqt 구현을 이용해 wav 파일을 주파수 대역으로 변환하였습니다.

 

모델 만들기

CQT를 스펙토그램으로 그리면 X축은 시간, Y축은 주파수 대역이 됩니다. 즉, 모든 악기 소리는 2차원의 그림으로 표현될 수 있는 거지요. 따라서 이미지 분석에 널리 쓰이는 CNN 모델을 악기 소리 분류에도 써보기로 결정했습니다.

3x3 크기의 필터를 2층을 쌓고, 마지막은 3x24 필터를 쌓았습니다. 마지막에서 주파수 대역 길이를 24로 길게 잡은건 다양한 배음 정보를 잡는게 악기 분류에 도움이 될거라고 판단했습니다. 시간 정보보다는 주파수 대역 정보가 중요할 테니깐요. 그리고 최종적으로 fully connected 레이어를 통과시켜서 128개의 악기 및 46개의 타악기 소리에 대해 분류하도록 했습니다. 아주 단순한 모형입니다.

 

훈련~!

그럼 바로 training을 시작해봅시다.

전체 데이터를 불러와 랜덤으로 섞고 90%는 훈련 데이터, 10%는 평가 데이터로 사용했습니다.

평가하기~!

matplotlib를 이용해서 결과를 시각화해봅시다. GM 0~127번까지의 악기에 46종의 퍼커션 소리 이름을 gm.list.txt 파일에 담아두었는데요, 위 코드를 실행하려면 해당 파일이 필요합니다. 별건 아니지만 첨부해드리니 필요하다면 다운 받아 쓰시면 되겠습니다.

gm.list.txt
0.00MB

결과

테스트셋에 대한 정확도는 98.9%가 나왔습니다. 예상보다 훨씬 높네요! 모델에겐 너무 쉬운 문제였을지도 모릅니다. 틀린 사례에 대해서만 Confusion Matrix를 그려서 오류 분석을 해보았습니다. X축이 실제 라벨, Y축이 예측된 라벨입니다. Acoustic Grand Piano와 Bright Acoustic Piano를 헷갈렸고, Tenor Sax와 Baritone Sax를 헷갈렸네요. 헷갈린 목록을 정리해보면 다음과 같습니다.

CNN모델 피셜 헷갈리는 악기 소리 묶음

(Acoustic Grand Piano, Bright Acoustic Piano)

(Tenor Sax, Baritone Sax)

(Woodblock, Low Wood Block)

그리고 애매하면 다 Tuba라고 분류했습니다...

또한 타악기 쪽에서 오류가 발생했는데 이는 데이터가 너무 적고, 타악기 소리 특성한 배음보다는 노이즈 비슷한 소리가 많이 잡히기 때문인걸로 보입니다. 좀더 현실 악기에 가까운 데이터를 구해 보충할 수 있다면 좋겠군요. 생각보다 성능이 잘 나오는걸 보니 과제를 좀 더 어렵게해서 악기 종류와 음 높이를 함께 맞추도록 해보는것도 좋을 거 같습니다.

태그

관련글 더보기

댓글 영역

  • 프로필 사진
    2020.04.03 21:37
    안녕하세요
    관련 앱을 제작해보고 싶어서 메세지 남깁니다.

    외주로 앱 제작도 하시나요?
    01039131231
  • 프로필 사진
    2020.04.16 00:26
    뭐하시는 분인지 여쭤봐도 돼나요? 포스팅하신 거 읽어보는데 게임 뚝딱 만드는 것도 그렇고 맘만 먹으면 이것저것 다 짜시는 능력자시네요....주인장님처럼 코딩 실력 키우는 팁이나 공부법좀 알려주세요ㅠ,ㅠ
    • 프로필 사진
      2020.04.16 22:24 신고
      그냥 IT기업에서 개발하고 있는 사람입니다. 사실 요즘에는 인터넷에 어지간한 내용은 다 찾아볼 수 있게 나오기 때문에 잘 모르는것들 있으면 찾아가보면서 개발할 수 있습니다. 개발 실력은 역시 많이 해보는게 제일 중요한거 같아요.
  • 프로필 사진
    2020.07.07 11:07
    죄송합니다만. output.wav 파일을 제공해주실수 있나요? 코드를 이용하여 생성하려고 하니까 잘 안되네요.
    • 프로필 사진
      2020.07.07 21:03 신고
      용량이 커서 공유가 쉽지 않네요. 구글 드라이브 링크로 올려드립니다.

      https://drive.google.com/file/d/1my0VG8XBD6nJQkRj30m-1zHUaMk4IXml/view?usp=sharing
    • 프로필 사진
      2020.08.30 01:49
      선생님, 유용한 자료 감사드립니다. 개인적으로 파이토치를 공부중인데, 댓글에 공유해주신 output.wav 파일을 내려받아서 사용해도 될까요??
    • 프로필 사진
      2020.08.30 14:52 신고
      네 사용하셔도 됩니다
  • 프로필 사진
    2020.07.27 22:10
    헐 상용화 하실 생각은 없나요? 이런게 꼭 필요해서 찾아보다 진짜 해보신 분이 있어서 놀랐습니다. 노래에 나오는 사운드 소스(악기)가 무엇인지 몰라서 항상 한참 헤매는데 꼭 사용하게 될 수 있으면 좋겠습니다.
  • 프로필 사진
    2020.09.17 13:12
    좋은 글 너무 감사합니다.

    질문이 하나 있는데, 저기서, 특정 악기에 해당하는 각각의 음원을 핸들링하는것은 또 별개의문제인가요?

  • 프로필 사진
    2020.11.11 17:38
    안녕하세요. 공대 어린이 공린이입니다! 올려주신 글은 잘 봤습니다. 저희는 현재 음성인식과 관련된 프로젝트를 진행해보려고 하고 있는데요! 약간은 다르지만 저희가 진행하고 있는 것은 '아기 울음소리를 인식하는 장치'입니다. 그런데 데이터를 충분히 줬음에도 불구하고 과대적합이 일어나는건지 학습된 데이터가 아닌 새로운 데이터를 넣어주면 이 데이터가 아기울음소리이더라도 아기울음소리로 인지하지 못해요! 찾아보니 과대적합은 특징이 너무 많아서 분산이 커질 때? 일어난다고 하는데 이를 해결하려면 어떻게 해야할지 여쭤볼 수 있을까요?
    아 그리고 저희가 분류에 이용하는건 SVC(Support Vector Machine)입니다!
    • 프로필 사진
      2020.11.12 18:17 신고
      음성 데이터에서 자질을 어떻게 추출했는지가 중요할 거 같습니다. 모델 구성을 어떤식으로 하셨는지 잘 알지 못해서 구체적인 답은 못 드리지만, 현재 음성 데이터에서 자질을 추출하는 방식이 SVM이 학습하기에 적합한지 검토해보셔야할듯합니다.
    • 프로필 사진
      2020.11.16 13:56
      헉 이제 봤네요. 일단은 계속 원인을 찾아보고있긴 한데 플젝 주제를 바꿀 생각도 하고있네요ㅋㅋㅋㅋㅠㅠ 감사합니다 앞으로도 좋은 글 많이 올려주세요!!
  • 프로필 사진
    2021.03.21 19:44
    안녕하세요 선생님
    혹시 여러 악기가 동시에 섞여 나오는 음악 같은 경우에는 어떤 방식을 추천해주실수 있을까요...?
    • 프로필 사진
      2021.03.21 20:37 신고
      사실 저도 이 쪽이 전공이 아니라서 정확하게 답변드리지 못하는 점 양해바랍니다.
      multiple instrument transcription 정도의 키워드로 찾아보시면 아마 관련 연구들 찾아보실 수 있으실 거에요.
    • 프로필 사진
      2021.03.25 15:42
      답변감사합니다!
  • 프로필 사진
    2021.05.25 04:20
    안녕하세요 제가 요즘 인공지능을 공부하면서 일단 따라해보고 있는데
    해당 confusion matrix를 어떻게 출력하신지 알고싶어서 댓글 남겼습니다
    혹시 실례가 되지 않는다면 소스를 공유 해주실 수 있을까요?
  • 프로필 사진
    2021.05.27 16:59
    안녕하세요. 항상 좋은 소스 올려주셔서 많은 도움을 받고 있습니다.
    confusion matrix 를 출력해보려구 하는데 ㅠㅠ 어렵네요.
    소스를 공유 해주실 수 있을까요? 감사합니다.
  • 프로필 사진
    2021.07.25 10:41
    안녕하세요! 많은 도움 되었습니다.
    혹시 실시간으로 소리 인식하여 소리를 분류하려고 하는데, 실시간으로 소리인식하는 부분이 어렵네요ㅠㅜ
    소스 공유해주실 수 있으실까요?
    • 프로필 사진
      2021.07.25 15:06 신고
      그건 장치나 OS에 따라 크게 달라질것 같아서요~ 찾아보니 PyAudio라는 패키지가 있는데 이걸 사용해보시는건 어떨까요
  • 프로필 사진
    2022.01.16 02:50
    비밀댓글입니다
  • 프로필 사진
    2022.01.16 02:53
    비밀댓글입니다
  • 프로필 사진
    2022.04.02 12:45
    좋은 글 감사합니다 개발에 도움이 많이 되었네요

    허나 선생님이 하신 방법으로 데이터셋을 직접 만들고 싶어 일단 musecsore와 fluidsynth를 이용해 선생님의 예제를 똑같이 따라해보니

    output.wav 는 출력 되는데 선생님 파일(3.2GB)과 크기(제꺼는 2.1GB)도 다르고 무엇보다 재생이 되지 않습니다.

    미디어 프로그램을 다른것으로 해도 안되고 파일 확장명이 틀렸거나 파일이 충돌되었습니다(We can't open output.wav. This may be because the file type is unsupported, the file extension is incorrect, or the file is corrupt.) 라는 오류 창만 뜨는데 혹시 선생님께서 개발 과정과 달리 윗글에서는 생략한 정보가 있는지 여쭤봅니다.
    • 프로필 사진
      2022.04.02 13:03 신고
      wav 파일 생성이 제대로 안 된거 같은데요, fluidsynth 쪽 문제일 것 같네요. 혹시 별도로 오류가 발생하는 부분은 없는지 확인이 필요해보여요.
    • 프로필 사진
      2022.04.02 15:30
      적용 시키는건 해냈는데

      windows / visual studio에서 디버깅 돌리면
      "fluidsynth: warning: Sound font version is 3.1 but fluidsynth was compiled without support for (v3.x)"
      가 뜨면서 fluidsynth가 작동을 안하네요
  • 프로필 사진
    2022.04.03 21:24
    좋은 글 감사합니다 덕분에 배우고 있습니다.

    혹시 추가로 C언어에서 #include <fluidsynth.h> 오픈소스 라이브러리 적용하는 방법이나

    파이썬에서 import librosa 적용하는 방법에 대해 알려주실 수 있나요?

    이 부분에서 막힙니다.
  • 프로필 사진
    2022.04.04 12:00
    비밀댓글입니다
  • 프로필 사진
    2022.04.11 14:08
    데이터 셋 만드는 곳에서 며칠 째 헤매고 있는데 fluidsynth 관련 글 포스팅 할 계획은 없으신가요?
  • 프로필 사진
    2022.06.16 21:19
    tf.placeholder가 pycharm 내의 tensorflow에서 에러를 띄우길래 뭔가 했더니
    2.0버전이 되면서 placeholder가 안되더군요
    다운그레이드해서 해보니 다른기능에 빨간줄이 떠서 버전을 어떻게 사용하셨는지 궁금합니다

    결국엔 keras 배워서 하나하나 다 변환해서 했습니다
    epoch수가 낮아서 그런지 저는 정확도가 높지 않네요
    계속 블로그 들락거릴때마다 심심해서.... 해보는.....?....
    전혀 안쉬웠다구요!!!ㅠㅠ