기계 학습(Machine Learning, 머신 러닝)은 즐겁다! Part 6

Jongdae Lim
15 min readMay 26, 2017

--

딥러닝(Deep Learning)을 이용한 음성 인식(Speech Recognition)

음성 인식은 이미 우리 생활속에 깊숙히 들어와 있습니다. 휴대 전화, 게임 콘솔 및 스마트 시계에 이미 음성인식이 포함되어 있습니다. 심지어 우리집을 자동화하고 있습니다. 50달러만 있으면 Amazon Echo Dot을 구입할 수 있습니다. 이 마술 상자로 피자를 주문하거나 날씨 정보를 확인하거나 심지어 쓰레기 봉투를 구입할 수도 있습니다. 그냥 큰 소리로 말하기만 하면 됩니다:

Alexa, 라지 피자 하나 주문해줘!

이 Echo Dot가 이번 연말 휴가철에 얼마나 인기가 있었던지 아마존이 재고를 유지하기도 힘들어 보입니다.

음성 인식은 지난 수십년 간 우리 주위에 있어 왔습니다. 그런데, 갑자기 요즘 대세가 된 이유는 무엇일까요? 그 이유는 딥러닝(deep learning)이 마침내 세심하게 통제된 환경 밖에서도 음성 인식을 사용할 수 있을 정도로 정확하게 만들었기 때문입니다.

Andrew Ng는 음성 인식이 95 %에서 99 %로 정확해져서 우리가 컴퓨터와 상호 작용하는 주된 방법이 될 것이라고 이미 오래전에 예측했습니다 . 여기서 중요한 것은 이 4 %의 정확도 격차가 짜증나게 신뢰가 안가는 것과 믿을 수 없을 정도로 유용한 것의 차이라는 것입니다. 딥러닝 덕분에 드디어 이 높은 수준에 도달했습니다.

딥러닝을 음성 인식에 어떻게 활용하는지 알아보겠습니다!

기계 학습이라고 만능은 아닙니다

신경망 기계 번역이 어떻게 동작하는지 알고 있다면, 당신은 어쩌면 단순하게 음성 녹음을 신경망에 공급(feed)하고 텍스트를 생성하도록 훈련시킬 수 있다고 생각할지도 모릅니다.

이렇게 바로 된다면 딥러닝을 활용한 음성 인식에 있어 이것이 성배가 되겠지만, 아직까지는 이런 수준에 이르지 못했습니다 (적어도 이글을 쓰고 있는 시점에는 아닙니다만, 몇 년 후에는 분명히 가능해질 것입니다).

문제는 말하는 속도가 다양하다는 것입니다. 어떤 사람은 “hello!”라고 말할 수도 있고 다른 사람은 “heeeelllllllllllllloooo!”라고 매우 느리게 말할 수도 있는데, 그렇게 되면 훨씬 더 많은 데이터의 훨씬 긴 음성 파일이 만들어 집니다. 이 두 개의 음성 파일은 “hello!”라는 동일한 텍스트로 인식되어야합니다. 다양한 길이의 오디오 파일을 고정 길이의 텍스트로 자동 정열하는 것은 사실 매우 어렵습니다.

이 문제를 해결하기 위해서, 우리는 심층 신경망(deep neural network)과 함께 특별한 기법과 추가 처리를 사용해야 합니다. 어떻게 동작하는지 살펴 보겠습니다!

소리를 비트로 바꾸기

음성 인식의 첫 번째 단계는 명확합니다 — 우리는 컴퓨터에 음파(sound waves)를 공급(feed)해야 합니다.

Part 3에서, 이미지를 숫자 배열로 만들어서 이미지 인식을 위한 신경망에 직접 공급하는 방법에 대해 알아봤습니다:

이미지는 각 픽셀의 강도(intensity)를 인코딩한 숫자 배열일 뿐입니다.

그러나 소리는 파동(waves)으로 전달됩니다. 어떻게 음파(sound waves)를 숫자로 바꿀 수 있을까요? 제가 “Hello”라고 말하는 다음의 음성 파일을 사용해 보겠습니다:

제가 말한 “Hello”의 파형(waveform)

음파는 1차원 입니다. 시간의 흐름속 매 순간마다 음파의 높이를 기준으로 한 단일 값을 가집니다. 음파의 아주 작은 부분을 확대해서 살펴 보겠습니다:

이 음파를 숫자로 표현하기 위해서는, 파동의 높이를 등간격의 좌표값으로 저장하면 됩니다:

음파 샘플링(표본 추출, sampling) 하기

이러한 과정을 샘플링(sampling)이라고합니다. 초당 수천번을 읽어들여서 그 시점에서의 음파 높이를 숫자로 저장합니다. 이러한 방법은 압축되지 않은 .wav 오디오 파일과 기본적으로 동일합니다.

“CD 품질”의 오디오는 44.1khz (초당 44,100번 읽기)로 샘플링됩니다. 그러나 음성 인식에서는 16khz (초당 16,000번 추출)의 샘플링 속도로도 인간의 음성 주파수 범위를 커버하기에 충분합니다.

우리의 “Hello” 음파를 초당 16,000번 샘플링해 보겠습니다. 다음은 처음 100개의 샘플입니다:

각 숫자는 1/16000 초 간격에 대한 음파의 진폭(amplitude)을 나타냅니다.

디지털 샘플링에 관해 알아야 할 것

샘플링은 데이터의 일부만을 추출하기 때문에 원래의 음파에 대한 대략적인 근사치를 만드는 것이라고 생각할 수 있습니다. 우리가 읽어드린 데이터는 원본과 차이가 있기 때문에 데이터 유실이 발생합니다. 그렇죠?

디지털 샘플링으로 원래의 아날로그 음파를 완벽하게 재현할 수 있을까요? 그림에서 보는 것과 같은 차이는 어떻게 해결해야 할까요?

하지만, Nyquist 정리 덕분에, 기록하고자하는 가장 높은 주파수의 최소 두 배 빠르게 샘플을 추출한다면, 간격이 생긴 샘플로부터 원래의 음파를 수학적으로 완벽하게 재구성해 사용할 수 있습니다.

이 내용을 언급하는 이유는, 거의 모든 사람들이 높은 샘플링 속도가 언제나 더 좋은 품질을 만들어 낸다는 잘못된 생각을 갖고 있기 때문입니다. 그렇지 않습니다.

샘플링 된 음성 데이터 전처리(pre-processing) 하기

이제 각 숫자가 초당 1/16,000 간격에 대한 음파의 진폭을 나타내는 일련의 숫자들이 있습니다.

이 숫자들을 신경망에 바로 제공(feed)할 수 있습니다. 하지만, 이러한 샘플을 직접 처리해서 음성 패턴(speech patterns)을 인식하는 것은 어렵습니다. 대신에 몇 가지 오디오 데이터에 대한 사전 처리를 수행함으로써 문제를 좀더 쉽게 해결할 수 있습니다.

샘플링한 오디오를 20 밀리 초 길이로 잘라 그룹으로 만드는 것부터 시작하겠습니다. 다음은 오디오의 처음 20 밀리초 (즉, 최초 320 개의 샘플) 입니다:

이 숫자들을 간단한 선 그래프로 그려보면, 이 20 밀리 초 동안의 원래 음파에 대한 대략적인 근사값을 확인할 수 있습니다:

이 레코딩은 단지 1/50 초 길이입니다. 그러나 이 짧은 레코딩 조차도 음성의 서로 다른 주파수가 복잡하게 뒤섞인 것입니다. 여기에는 낮은 음역, 중간 음역들이 있고 심지어 높은 음역도 몇 군데 나타납니다. 하지만 이러한 다양한 주파수가 혼합되어 복잡한 인간 언어의 음성을 구성합니다.

신경망이 이 데이터를 좀더 쉽게 처리할 수 있도록, 복잡한 음파를 구성 요소들로 분리하려고 합니다. 가장 낮은 음역, 그 다음 낮은 음역, 이런식으로 분리할 것입니다. 그런 다음 각 주파수 대역별(낮은 주파수에서 높은 주파수까지)로 분포된 에너지를 합산해서, 이 오디오 정보에 대한 일종의 지문(fingerprint)을 만듭니다.

누군가 피아노로 C 장조 화음을 연주하는 것을 녹음했다고 상상해보십시오. 이 소리는 도, 미, 솔 이 세가지 음들이 함께 섞여져 하나의 복잡한 소리로 만들어진 것입니다. 우리는 이 복잡한 소리를 개별 음으로 분해해서 도, 미, 솔이라는 것을 알아내고자 합니다. 우리가 하고자 하는 것이 바로 정확히 동일한 아이디어입니다.

푸리에 변환 (Fourier transform)이라고하는 수학 연산을 사용하면 이를 수행할 수 있습니다. 이 연산은 복잡한 음파를 이를 구성하는 단순한 음파로 분해합니다. 이러한 개별적인 음파로 분해된 후에는, 각각의 음파에 얼마나 많은 에너지가 포함되어 있는지를 합산합니다.

최종 결과는 저음(즉, 베이스 음)부터 고음까지 각각의 주파수 범위가 얼마나 중요한지에 대한 점수입니다. 아래의 각 숫자는 20 밀리초의 오디오 클립에서 각 50hz 대역별로 얼마나 많은 에너지가 있었는지 나타냅니다:

목록의 각 숫자는 50hz 주파수 대역별로 얼마나 많은 에너지가 있었는지 나타냅니다

이를 차트로 그리면 훨씬 더 쉽게 이해할 수 있습니다:

오디오의 20 밀리초 조각마다 이 과정을 반복하면, 음향 스펙트럼(spectrogram)이 만들어 집니다.(왼쪽에서 오른쪽으로의 각 열은 하나의 20ms 조각입니다):

“hello” 음성에 대한 전체 음향 스펙트럼(spectrogram)

음향 스펙트럼은 오디오 데이터에서 음정과 여러 음역대 패턴을 실제로 수 있어서 아주 멋집니다. 신경망은 원래의 소리보다는 이런 종류의 데이터로부터 좀더 쉽게 패턴을 찾을 수 있습니다. 이 때문에 우리가 신경망에 실제로 제공하는 것이 바로 이러한 데이터 표현입니다.

짧은 소리로부터 특징 인식하기

이제 오디오를 처리하기 쉬운 포맷으로 만들었고, 딥신경망(deep neural network)에 이를 제공(feed)할 것입니다. 신경망에 입력되는 데이터는 20 밀리초 단위의 오디오 조각입니다. 각각의 작은 오디오 조각마다 현재 발음되는 소리에 해당하는 문자가 무엇인지 찾게 될 것입니다.

우리는 순환 신경망(recurrent neural network) — 즉, 향후 예측에 영향을 미치는 메모리를 가지고 있는 신경망을 사용할 것입니다. 그 이유는 예측하는 각 글자가 이 후 예측할 다음 글자에 대한 가능성에 영향을 주어야하기 때문입니다. 예를 들어, 앞서 “HEL”이라고 말했다면, “Hello”라는 단어를 끝내기 위해 “LO”라고 말할 가능성이 높습니다. “XYZ”와 같이 발음하기 어려운 것을 뒤이어 말할 가능성은 훨씬 적습니다. 따라서 앞선 예측을 기억하면 신경망이 더 정확한 예측을 할 수 있습니다

신경망을 통해 전체 오디오 클립을 (한 번에 조각씩) 모두 수행하면, 각 오디오 조각 별로 해당 조각에서 들리는 가장 가능성이 높은 문자가 매핑되게 됩니다. 다음은 내가 “Hello”라고 말하는 음성의 매핑 결과입니다:

우리의 신경망은 내가 말했을 가능성이 높은 것이 “HHHEE_LL_LLLOOO”라고 예측하고 있습니다. 그러나 또한 내가 “HHHUU_LL_LLLOOO”또는 “AAAUU_LL_LLLOOO”라고 말할 가능성도 있다고 생각합니다.

이 결과를 정제하기 위해 수행 할 몇 가지 단계가 있습니다. 먼저, 반복되는 모든 문자를 하나의 문자로 대체합니다:

  • HHHEE_LL_LLLOOO becomes HE_L_LO
  • HHHUU_LL_LLLOOO becomes HU_L_LO
  • AAAUU_LL_LLLOOO becomes AU_L_LO

그리고 모든 공백을 제거합니다:

  • HE_L_LO becomes HELLO
  • HU_L_LO becomes HULLO
  • AU_L_LO becomes AULLO

이제 “Hello”, “Hullo” 그리고 “Aullo”의 세가지 가능한 단어(필사, transcription)가 만들어졌습니다. 이 세가지 단어를 큰소리로 말하면 모두 “Hello”와 비슷하게 들립니다. 신경망이 한 번에 한 문자만을 예측하기 때문에, 이와 같이 소리나는데로 받아 적은 필사(transcription)를 만들어 냅니다. 예를 들어 “He would not go”라고 말하면, “He wud net go”와 같은 필사도 가능성이 있다고 할 것입니다.

이를 해결할 방법은 이러한 발음 기반의 예측과 글로 쓰여진 텍스트(서적, 뉴스 기사 등)의 대규모 데이터베이스를 기반으로 하는 가능성 점수를 결합하는 것입니다. 현실이 될 가능성이 가장 적은 필사들은 버리고 가장 현실적인 것으로 보이는 필사를 취합니다.

“Hello”, “Hullo” 그리고 “Aullo”와 같은 필사 중에서, 당연히 “Hello”가 (원래의 오디오 기반 교육 데이터 뿐만아니라) 텍스트 데이터베이스에 훨씬 더 자주 나타나므로 아마도 맞을 것입니다. 따라서 우리는 다른 것들 대신에 “Hello”를 최종 전사로 선택할 것입니다. 끝!

잠시만요!

“그런데 누군가가 정말로 ‘Hullo’라고 한다면? 당연히 이것이 맞는 것이고 ‘Hello’ 가 아마도 잘못된 필사이다”라고 생각할 지도 모릅니다.

“Hullo! Who dis?”

물론 누군가가 실제로 “Hello”대신에 “Hullo”라고 말한 것일 수 있습니다. 그러나 미국식 영어로 훈련된 이러한 음성 인식 시스템은 기본적으로 절대 “훌루 (Hullo)”를 필사로 제시하지 않습니다. “Hello”와 비교해서 이 단어는 강능성이 거의 없는 것이기 때문에 신경망은 당신이 아무리 ‘U” 소리를 강조하더라도 언제나 “Hello”라고 말한다고 생각할 것입니다.

한번 시도해 보세요! 당신의 휴대전화의 언어 설정이 American English로 세팅되어 있다면, 음성 인식이 “Hullo”를 인식하는지 시도해 보세요. 안됩니다! 계속해봐도 안됩니다! 언제나 “Hello”로 이해할 것입니다.

“Hullo”를 인식하지 못하는 것은 이해할 만한 상황이지만, 때로는 당신의 휴대전화가 제대로 말하는 말도 이해하지 못하는 짜증나는 경우들도 있습니다. 이때문에 음성 인식 모델은 이러한 특이 케이스를 고치기 위해서 항상 더 많은 데이터로 재훈련되고 있습니다.

나만의 음성 인식 시스템을 만들 수 있을까요?

기계 학습에서 가장 멋진 점 중 하나는 바로 가끔 아주 심플하다는 것입니다. 수많은 데이터를 가져와 기계 학습 알고리즘에 제공하면 마술처럼 당신의 게임용 랩톱의 비디오 카드에서 실행되는 세계적 수준의 AI 시스템을 만들 수 있습니다… 그렇죠?

어떤 경우에는 맞는 얘기입니다만, 음성인식에는 해당되지 않습니다. 음성을 인식하는 것은 어려운 문제입니다. 나쁜 품질의 마이크, 배경 잡음, 잔향(reverb)과 반향(echo), 다양한 말투(accent) 등과 같은 거의 무한한 문제를 극복해야 합니다. 이러한 모든 문제는 신경망이 처리 할 수 있도록 훈련 데이터에 포함되어 있어야만 합니다.

또 다른 예가 있습니다: 큰 방에서 이야기 할 때, 당신은 소음때문에 무의식적으로 소리를 높인다는 것을 알고 있습니까? 인간은 어떻게 하더라도 이해하는 데 아무런 문제가 없지만, 이 특수한 경우를 처리하기 위해 신경망은 훈련이 필요합니다. 따라서 소음 때문에 고함을 지르는 사람들의 훈련 데이터가 필요합니다.

Siri, Google Now! 또는 Alexa의 수준으로 동작하는 음성 인식 시스템을 구축하려면 수백명의 사람을 고용해서 녹음을 해야만 얻을 수 있는 데이터보다 훨씬 많은 훈련 데이터가 필요합니다. 그리고 사용자들은 저품질의 음성 인식 시스템을 이해해 주지 않기 때문에, 이 문제를 간과해서는 안됩니다. 아무도 80% 수준으로 동작하는 음성 인식 시스템을 원하지 않습니다.

Google이나 Amazon과 같은 회사들은 실생활에서 녹음된 수십억 시간 분량의 음성 오디오가 바로 황금과 같습니다. 이것이 바로 세계적인 수준의 음성 인식 시스템과 당신의 취미로 만든 시스템을 구분짓는 단 하나의 가장 큰 차이입니다. 모든 휴대폰에 무료로 설치된 Google Now!Siri 또는 추가비용이 없이 $50에 팔고 있는 Alexa는 당신이 이를 가능한 한 많이 사용하도록 유도하고 있습니다. 이들 시스템 중 하나에 당신이 말하는 모든 것은 영원히 기록되고 향후 음성 인식 알고리즘의 향후 버전의 훈련 데이터로 사용됩니다. 정말 이렇게 돌아가고 있습니다!

못 믿으시겠다구요? Google Now!가 설치된 Android 휴대폰이 있다면, 여기를 클릭해서 당신이 직접 말한 모든 멍청한 것들에 대한 실제 녹음 내용을 들어보십시오:

Alexa 앱을 통해 Amazon에 저장된 동일한 것들을 확인할 수 있습니다. Apple은 안타깝게도 Siri 음성 데이터에 접근하는 것을 허용하지 않습니다.

따라서 당신이 스타업 아이디어를 고민하고 있다면, Google과 경쟁할 나만의 음성 인식 시스템을 개발하는 것은 절대 추천하지 않습니다. 대신에, 사람들이 몇 시간 동안 말하는것을 녹음해서 제공하도록 하는 방법을 찾아보십시오. 이 데이터가 당신의 제품이 될 수 있습니다.

좀 더 배울수 있는 곳

  • 여기서 (대략적으로) 설명된 가변 길이 오디오(variable-length audio)를 처리하기 위한 알고리즘을 Connectionist Temporal Classification 또는 CTC라고 합니다. 2006년도 원본 논문을 읽어 볼 수 있습니다.
  • Baidu의 Adam Coates는 Bay Area Deep Learning School에서 음성 인식을 위한 딥러닝에 대해 멋진 프레젠테이션을 했습니다. YouTube에서 이 비디오를 볼 수 있습니다 (그의 말은 3:51:00에 시작됩니다). 강추합니다.

이 글이 마음에 들었다면, 제 Machine Learning is Fun! 이메일 리스트에 가입하는 것도 좋습니다! 새롭고 멋진 소식이있을 때만 이메일을 보내 드리겠습니다. 제가 이런 종류의 추가 글을 올릴때가 언제인지 알 수 있는 가장 좋은 방법입니다.

Twitter의 @ageitgey인 저를 팔로우하거나, 직접 이메일을 보내거나 또는 linkedin에서 저를 찾을 수도 있습니다. 기계 학습으로 제가 당신이나 당신의 팀을 도울 수 있다면 언제든 연락 주십시오.

*역자주: 번역글과 관련해 의견 주시려면, 저에게 직접 이메일을 보내시거나 LinkedIn에서 저를 찾으셔도 됩니다.

--

--

Jongdae Lim

I’m a Java guy, working at Microsoft as a principal software engineering manager in CSE(Commercial Software Engineering).