Sunday, June 9, 2019

딥러닝과 오디오 데이터 전처리

이번 글에서는 딥러닝과 오디오 데이터 전처리 전반을 살펴보겠습니다. 제가 몇몇 발표 (2017-11-03 판교 혁신센터, "음악과 딥러닝의 사랑과 전쟁" (발표자료))에서 다룬적이 있는데, 이미지랑은 달리 오디오 데이터는 몇가지 특징이 있습니다.

  • 데이터 사이즈가 크다 - 상황에따라 천차만별이지만 오디오는 기본 16비트고 (이미지는 8비트 x 3, 4채널) 1초당 int16짜리 데이터가 44,100개가 있습니다.
  • 디코딩이 느리다 - 데이터가 크기 때문에 음성/음악 코덱 기술이 많이 발달했습니다. 그런데 오디오 코덱은 신호를 시작부터 끝까지 순차적으로 디코딩합니다. 그리고 연산량이 적어서 디코딩 속도가 빠를수록 좋긴 하지만, 한편으론 재생 속도보다 빠르기만 하면 일반적인 오디오 재생에는 별 문제가 없겠죠. 그러다보니 딥러닝 학습과정에선 문제가 될 수 있습니다. 즉, 디코딩 속도가 데이터 로딩의 병목이 될 수 있습니다.
  • 별도의 전처리가 필요할 수 있다 - STFT, Melspectrogram 등의 연산이 여기에 해당합니다.

그 외에, 일반적인 딥러닝 학습을 하다보면 누구나 겪게되는 상황이 있습니다.

  • 데이터가 커서 메모리에 다 안들어간다.
    • HDF? memmap?
  • 데이터를 추가하거나 데이터 전처리 파라미터를 편리하게 변경할 수 있어야한다.

이런 상황을 고려하면 해결책은 아래와 같습니다.

  • 저장 포맷
    • 디코딩이 끝난 오디오 데이터를 그대로, 파일마다 .wav (int16)나 .npy (numpy array, int16/float32/etc)로 저장
    • 예: audio_1.wav, audio_2.wav, ... audio_10000.wav
    • 장점: 로딩이 빠르다
    • 단점: mp3등 압축 코덱 대비 하드디스크 공간을 많이 차지한다. 그러나 대부분의 경우에 현실적으로 큰 문제가 아님. 하드디스크는 별로 안비싸고, 오디오 데이터셋이 보통 그렇게까지 크지 않음. 
  • 로딩 방식
    • 파이토치와 텐서플로 모두 데이터 로딩 모듈이 잘 짜여져있습니다. 각 모듈에서 데이터 인덱스(예: idx=10)를 받아서 파일을 하나 로딩하는걸 구현합니다.
    • 사용할때는 인덱스 ([1, 2, 3,.. ,10000])을 shuffle한 뒤에 순서대로 불러오면 됩니다.
    • 파이토치의 경우엔 예를들면 저는 이렇게 합니다 (소스).
    • 장점: 
      • 데이터를 쉽게 추가할 수 있음. 마찬가지로 shuffle도 다양하게 할 수 있음. (만일 hdf를 쓰면 연속된 메모리에서 불러와야 유리하므로 미리 셔플을하고 저장해야하는데 이 모든 데이터 준비 과정이 시간을 많이 잡아먹음)
      • 배치 사이즈만큼의 데이터를 불러오는 과정은 텐서플로/파이토치의 데이터 로딩이 알아서 멀티프로세싱으로 잘 수행하므로 편리하고 안정적임. 
  • 전처리
    • 가급적 대부분의 전처리를 gpu에서 수행 (stft 등)
      • 장점: 파라미터 변경이 쉬움. 나중에 모델을 배포하고 사용할때도 오디오 파일을 그대로 불러와서 진폭을 바꿔주고 (int16 --> float, [-1.0, 1.0]) 샘플링 레잇만 맞춰주면 바로 모델에 넣을 수 있어서 편리함. Dependency가 적어짐 (librosa같은 외부 라이브러리를 쓰지 않아도 되므로). 
      • 단점: gpu의 연산과 메모리를 조금 더 사용함.