저번 포스팅에서는 음성합성 기술들에 대해서 간단하게 알아보고 프로젝트에서 사용할 기술을 정했다.

 

앞에서 정한 '딥러닝 기반 음성합성'에서 '딥러닝'은 'end-to-end learning' 이라고도 한다. 여기서 'end-to-end'에 대해

간단히 알아보자.

 

 

 

 

End-to-End

end-to-end (e2e)는 문자 그대로 '끝에서 끝'이다.

무슨 말이냐면 e2e방식은 입력에서 출력까지 신경망으로 한 번에 처리한다는 소리이다.

즉, 데이터의 특징을 추출하거나 알고리즘을 이용하여 데이터를 분석하거나 하는 중간과정이 필요가 없는 방식이라는 것이다.

 

 

e2e 그림

 

 

그림과 같이 신경망 하나로 학습을 처리하는 방식이다.

이 방식의 장점은 input값만 넣으면 바로 output값이 나온다는 점이다. 그리고 직접 데이터의 특징을 추출하거나 할 필요가 없다. 

하지만 단점이 있는데, 단점으로는 (input, output) 데이터가 많이 필요하다는 점과, 어떤 상황에서는 직접 학습 구조를 설계해서 학습시키는 게 더 효율적일 수도 있다는 점 등이 있다. 

앞에서 이야기 했던대로 가능하면 언어학적 지식이 크게 필요하지 않은 방법을 선택하고 싶었기에, e2e방식은 지금 상황에 맞는 방식인 것 같다.

 

 

 

 

음성합성에서의 End-to-End

end-to-end 방식을 사용하여 음성합성을 하는 경우는 위의 과정과 약간 다르다. 

최근의 음성합성의 구조를 보면, text에서 바로 speech로 넘어가기보다는, text -> mel-spectrogram -> speech 이런 식으로 구성되어있다.

text -> mel-spectrogram의 부분은 acoustic model이, mel-spectrogram -> speech의 부분은 vocoder model이 담당한다.

 

 

음성합성에서의 end-to-end

 

 

 

 

mel-spectrogram

mel-spectrogram에 대해서 간단히 짚고 가보자.

spectrogram은 소리나 파동을 시각화하여 파악하기 위한 도구로, 파형과 스펙트럼의 특징이 조합되어있다.

 

 

출처 : https://en.wikipedia.org/wiki/Spectrogram

 

 

x축은 시간, y축은 진동수, 색은 진폭을 나타낸다.

 

일반적으로 spectrogram을 만드는 과정은 wav -> STFT -> spectrogram이다.

그런데 중간에 STFT과정은 왜 있는 거고 왜 필요한 것일까?

 

처음 내가 생각했을 때도 wav파일에는 시간, 진폭, 주파수 정보가 다 있는데 왜 중간 과정이 있는 걸까?라고 생각을 했다.

그런데 잘 생각해보자. spectrogram에서는 시간축의 한 지점에 대해 각각의 주파수가 가지는 진폭이 전부 표현이 되어있다. 이상하지 않은가? 원래 wav파일의 waveform을 보면 한 시간축에서 진폭 하나만 표현되어 있는데 이걸 가지고 spectrogram을 어떻게 표현했을까?

답은 푸리에 변환에 있다. 지금은 간단하게만 설명하겠다.

푸리에 변환을 사용하면 wav파일에서의 waveform을 고유주파수를 가지는 주기 함수로 각각 분해가 가능하다. 

그리고 여기서 구한 주기 함수들로 각각의 주파수에 대한 진폭을 구할 수 있다.

그런데 문제가 있다. 푸리에 변환은 시간이 고려되지 않는다!!

실제로 푸리에 변환을 통해서 어떤 주기함수들로 이루어져 있는지는 확인이 가능하지만, 어느 시간에 어떤진동수가 얼마만큼의 진폭을 가지는지는 알 수가 없다. 이를 해결하기 위해 나온기술이 STFT(short time fourier transform)이다. STFT는 wavform을 짧은 시간간격으로 쪼갠 다음, 각각의 조각에서 푸리에 변환을 사용하는것이다. 이렇게 하면 어느시간에 어느 진동수가 얼마만큼의 진폭을 가지는지 알 수 있다!

 

따라서 STFT는 시간이 고려되지 않는 푸리에 변환을 보안하기 위해 나온 기술로, 시간축을 구현하기 위해 사용된다라고 생각하면 될 것이다.

 

(최대한 간략하게 설명하기 위해 노력했는데... 너무 난잡해진 기분이다. 나중에 시간이 되면 푸리에 변환과 STFT에 대해 자세히 글을 써보자. )

 

그림 spectrogram은 뭔지 알겠다. 그런데 앞에 mel이 붙어있는 건 왜일까?

 

우선 mel scale에 대하여 알아보자. 사람은 소리를 정비례하게(?) 인식하지 않는다. 

무슨 말이냐면 사람은 낮은 주파수에서의 변화를 더 크게 인식한다는 것이다.

(18000HZ->20000Hz의 변화보다 2000HZ->4000HZ의 변화를 더 크게 인식한다. 달팽이관의 구조 때문이다.)

따라서 사람이 인식하는 정도를 고려하여 주파수값을 바꿔주는 것을 mel scale이라고 한다.

 

 

출처 : https://en.wikipedia.org/wiki/Mel_scale

 

 

그래프를 보면 위에서 언급한 대로 낮은 Hertz값에서의 기울기가 더 큰 것이 확인된다. 

낮은 Hertz에서의 변화가 사람에게 더 크게 인식된다는 것이 반영되었다는 것을 알 수 있다.

 

 

출처 : https://en.wikipedia.org/wiki/Mel_scale

 

 

다음의 식은 Hertz값을 mel값으로 바꿔주는 함수이다. (위의 그래프에 대한 식)

만약 mel값을 Hertz값으로 바꿔주고 싶으면 위의 함수의 역함수에 mel값을 집어넣으면 된다. 

(수학 시간에 배웠던 x = f^-1 (y)를 써먹었다!)

 

정리해보면 mel-spectrogram은 mel-scale이 반영된 spectrogram정도로 생각하면 되겠다.

 

이건 내가 데이터 수집한 데이터 중 한 wav파일을 spectrogram으로 나타낸 것이다.

(코드는 librosa 공식 홈페이지 참조)

spectrogram

 

import librosa
import matplotlib.pyplot as plt
import numpy as np
import librosa.display
audio_path = 'path+name.wav' #wav파일의 위치와 파일명
y, sr = librosa.load(audio_path)
D = librosa.stft(y)  # STFT of y
S_db = librosa.amplitude_to_db(np.abs(D), ref=np.max)
plt.figure()
librosa.display.specshow(S_db)
plt.colorbar()
plt.show()

 

 

(이번에는 end-to-end에 대해 간략히 알아보고 끝내려고 했는데 글을 쓰다 보니 mel-spectrogram에 푸리에 변환까지 막 섞이게 되었다.. )

다음은  어떤 acousticacoustic model과 어떤 vocoder model가 있는지 알아보자.