웨이블릿: 높은 음은 짧은 윈도우, 낮은 음은 긴 윈도우
윈도우 하나로는 2 Hz 차이와 1 ms 충격을 함께 볼 수 없어서, 기계 진단 문제에서는 스펙트로그램을 두 장 쓰자는 답이 나왔다. 그런데 두 고장을 다시 보면, 가르기 어려웠던 2 Hz 차이는 낮은 주파수(50 Hz)에 있었고 짧은 충격은 높은 주파수에 퍼져 있었다. 50 Hz 물결은 한 번 출렁이는 데 20 ms 가 걸리니 1 ms 윈도우 안에서는 출렁임조차 보이지 않는다. 반대로 2000 Hz 물결은 0.5 ms 마다 출렁이므로 짧은 윈도우에도 몇 번은 들어간다. 낮은 음에는 긴 윈도우, 높은 음에는 짧은 윈도우를 대면 한 장으로 둘 다 볼 수 있지 않을까?
역사: 계단 함수에서 석유 탐사까지
물결 대신 짧은 조각으로 신호를 적는 생각은 푸리에 급수가 막힌 곳에서 시작되었다. 1873년 뒤부아레몽(Paul du Bois-Reymond)이 이어진 함수인데도 푸리에 급수가 어느 점에서 수렴하지 않는 예를 만든 뒤, 수학자들은 이어진 함수라면 언제나 수렴하는 다른 직교 함수 묶음이 있는지 물었다. 괴팅겐에서 힐베르트(David Hilbert)에게 배우던 헝가리의 하르(Alfréd Haar)는 1909년 학위 논문과 1910년 『수학 연보』 69권의 논문 「직교 함수계의 이론에 관하여」에서 값이 세 가지(양수, 음수, 0)뿐인 계단 함수 묶음을 만들어 답했다. 반쪽은 +, 반쪽은 −인 계단을 반씩 줄이고 옮겨 만든 이 묶음이 지금 하르 웨이블릿이라 부르는 것이다.
70년쯤 뒤 같은 생각이 석유 탐사에서 다시 나왔다. 프랑스 석유 회사 엘프 아키텐의 지구물리학자 모를레(Jean Morlet)는 땅에 진동을 보내고 지층마다 되돌아오는 메아리를 분석했다. 그는 처음에 가보르 식으로 일정한 길이의 윈도우를 쓴 분해를 썼는데, 지층에서 돌아오는 메아리는 저마다 길이가 달랐다. 그래서 윈도우의 길이를 고정하고 그 안의 물결을 바꾸는 대신, 같은 모양의 물결을 늘이고 줄이는 방법을 생각했다. 그는 이것을 「사이클–옥타브 변환」이라 불렀는데, 이 방법에 이른 때는 자료마다 1970년대 중반, 1982년 무렵으로 다르다. 마르세유의 이론물리학자 그로스만(Alex Grossmann)이 이 계산에 수학의 틀을 세웠고, 두 사람은 1984년 「일정한 모양의 제곱 적분 가능한 웨이블릿으로 하디 함수를 분해하기」를 냈다. 「작은 물결」이라는 뜻의 프랑스어 「옹들레트(ondelette)」가 영어 「웨이블릿(wavelet)」이 되었다.
그 뒤 일은 빨랐다. 1988년 도브시(Ingrid Daubechies)는 유한한 구간 밖에서는 0이면서 원하는 만큼 매끄러운 직교 웨이블릿을 만들었다. 가장 거친 첫 번째가 하르의 계단이다. 1989년 말라(Stéphane Mallat)는 「다해상도 신호 분해의 이론: 웨이블릿 표현」에서 웨이블릿 계수를 짧은 필터를 거듭 거는 피라미드 계산으로 빠르게 얻는 방법을 보였다. 2000년에 나온 그림 압축 표준 JPEG 2000 은 이 계산을 핵심으로 삼아, 손실 압축에는 도브시 계열의 9/7 필터를, 손실 없는 압축에는 5/3 필터를 쓴다.
하르: 8칸을 평균과 차이로
하르의 방법을 손으로 해 보자. 손으로 끝까지 계산할 수 있으면서 낮게 오르는 흐름과 한 칸짜리 튐이 함께 들어 있는 가장 작은 예로, 칸 8개 [4, 4, 6, 6, 6, 6, 14, 6]을 고른다. 일곱째 칸의 14가 딸깍 소리이고, 이웃한 두 칸마다 평균과, 앞 칸에서 뒤 칸을 뺀 값의 절반(차이)을 적는다.
| 단계 | 평균 | 차이 |
|---|---|---|
| 칸 8개 → 4쌍 | 4, 6, 6, 10 | 0, 0, 0, 4 |
| 평균 4개 → 2쌍 | 5, 8 | −1, −2 |
| 평균 2개 → 1쌍 | 6.5 | −1.5 |

남긴 숫자는 전체 평균 6.5, 가장 굵은 차이 −1.5, 중간 차이 −1, −2, 가장 가는 차이 0, 0, 0, 4로 모두 8개다. 「평균 + 차이」와 「평균 − 차이」로 거꾸로 풀면 원래 8칸이 그대로 돌아온다. 가장 가는 차이 넷은 칸 두 개씩만, 중간 차이 둘은 칸 네 개씩을, 가장 굵은 차이는 8칸 전체를 본다. 짧은 윈도우는 가는 변화를, 긴 윈도우는 굵은 변화를 맡는다.
딸깍 소리 하나가 어디에 남는지 보자. 14를 6으로 바꾼 신호와 비교하면 바뀌는 숫자는 8개 가운데 4개(전체 평균, 가장 굵은 차이, 중간 차이 하나, 가장 가는 차이 하나)뿐이다. 같은 두 신호를 DFT 하면 계수 8개가 모두 바뀐다. 하르의 숫자는 딸깍 소리가 「뒤쪽 절반의 뒤쪽 절반의 마지막 쌍」에 있다고 자리까지 알려 준다.
이렇게 한 가지 모양의 짧은 물결 ψ를 늘이고 줄이고 옮겨 만든 묶음에 신호를 비추어 적는 것을 웨이블릿 변환 (늘이고 옮긴 작은 물결로 적기 / wavelet transform)이라 한다. 하르의 계단도, 모를레가 쓴 가우스 윈도우를 씌운 물결도 한 가지 모양 ψ에서 나온다.
배율 s를 절반으로 줄이면 웨이블릿은 시간으로 절반 길이, 주파수로 두 배 높은 물결이 된다. 윈도우 안에 든 물결 수는 늘 같다. 시간 퍼짐과 주파수 퍼짐의 곱은 여전히 1/(4π) 아래로 내려가지 않지만, 칸의 모양이 주파수마다 바뀐다. 이 장의 모를레 웨이블릿(가우스 윈도우의 폭을 주파수에 반비례하게 잡아, 파워가 몰린 가운데 ±2σt 구간에 어느 주파수에서나 물결이 4.5개 들게 한 것)은 100 Hz 에서 시간 퍼짐 11.25 ms, 주파수 퍼짐 7.1 Hz이고, 3000 Hz 에서 0.38 ms, 212.1 Hz다. 주파수 퍼짐을 주파수로 나눈 값은 어디서나 0.071로 같다.

낮은 두 음(100 Hz, 150 Hz)에 0.5초 딸깍 소리를 얹은 소리로 두 방법을 나란히 놓아 보자. 두 음 사이(125 Hz)의 파워를 100 Hz 파워로 나눈 값과, 딸깍 소리가 가장 센 때의 1/10 넘게 보이는 시간 폭은 아래와 같다.
| 방법 | 125 Hz ÷ 100 Hz 파워 | 두 음 | 딸깍 소리의 시간 폭 |
|---|---|---|---|
| 단시간 푸리에 변환, 윈도우 25 ms | 1.080 | 한 덩어리 | 15.0 ms |
| 단시간 푸리에 변환, 윈도우 250 ms | 거의 0 | 둘로 갈라짐 | 154.0 ms |
| 모를레 웨이블릿 | 0.029 | 둘로 갈라짐 | 1.7 ms |

ML에서: 웨이블릿을 쌓은 신경망, 산란 변환
합성곱 신경망은 그림을 몇 칸 옮겨도 같은 답을 내야 하고, 조금 찌그러뜨려도 답이 크게 흔들리지 않아야 한다. 말라는 2012년 학술지에 실은 「군 불변 산란(Group invariant scattering)」에서 학습 없이 옮기기와 찌그러뜨리기에 흔들리지 않는 표현을 웨이블릿으로 짰다. 신호에 웨이블릿 변환을 걸고, 계수의 절댓값을 취하고, 그 절댓값에 다시 웨이블릿 변환을 거는 일을 몇 번 되풀이한 뒤 마지막에 평균을 낸다. 이렇게 쌓은 표현을 웨이블릿 산란 변환이라 하는데, 그 안에서 절댓값은 위상(조금만 옮겨도 크게 도는 값)을 버리고, 평균은 자리를 버린다. 브루나(Joan Bruna)와 말라는 이 표현을 「불변 산란 합성곱 신경망」이라 부르고, 학습한 필터 대신 정해진 웨이블릿을 쌓은 이 망으로 손글씨 숫자와 질감 분류에서 그때 가장 좋은 수준의 성적을 냈다고 보고했다. 합성곱 신경망의 층을 「웨이블릿 필터 → 비선형 함수 → 묶기」로 읽게 해 주는 예다.
문제 7. 8일 동안의 기온 기록
8일 동안의 낮 기온(°C)이 [12, 13, 15, 15, 16, 16, 21, 20]이다. (가) 하르의 방법으로 이웃 둘의 평균과 차이를 끝까지 구해, 숫자 8개(전체 평균 1개 + 차이 7개)로 적어라. (나) 크기가 0.5 이하인 차이를 모두 0으로 바꾸고 되살리면, 0이 아닌 숫자는 몇 개 남고 원래 기온과 가장 크게 어긋나는 곳은 몇 °C 인가?

(가) 첫 단계는 평균 12.5, 15, 16, 20.5에 차이 −0.5, 0, 0, 0.5요. 다음은 평균 13.75, 18.25에 차이 −1.25, −2.25. 마지막은 평균 16에 차이 −2.25. 그래서 [16, −2.25, −1.25, −2.25, −0.5, 0, 0, 0.5]예요.

(나)에서 0이 되는 숫자는 어느 것이에요?

가장 가는 차이 넷이 −0.5, 0, 0, 0.5라 다 지워져요. 남는 건 16, −2.25, −1.25, −2.25 넷이에요. 되살리면 [12.5, 12.5, 15, 15, 16, 16, 20.5, 20.5]이고, 원래 기온과 가장 크게 다른 곳도 0.5°C 차이예요.

이틀씩 묶은 평균만 남은 거네. 하루하루의 작은 출렁임은 버리고, 이틀 평균 12.5, 15, 16, 20.5 는 원래 기온의 이틀 평균과 똑같아.

그러면 작은 계수를 지우는 일을 DFT 계수에서 하면 어떻게 될까요? 가장 작은 계수 넷을 지우는 거예요.

DFT 계수 하나하나는 8일 전체에 걸친 물결이니까, 지우면 오차가 8일 전체로 퍼질 것 같아요. 하르는 차이 하나를 지우면 그 이틀만 어긋나는데요.

JPEG 2000 이 작은 웨이블릿 계수를 덜 정확하게 적어서 크기를 줄인다는 게 이런 거였군요. 오차가 지운 차이가 맡던 이틀에만 남으니까요.

출석부에서 「이번 주 월화는 다 출석」처럼 묶어 적고, 결석한 날만 따로 적는 거랑 같아요.
문제 8. 딸깍 소리 하나의 계수
칸 N개 가운데 한 칸만 1이고 나머지는 0인 신호가 있다. (가) N = 8, 1인 칸이 여섯째(번호 5, 0부터 셈)일 때 하르 계수 8개를 구하고, 0이 아닌 것이 몇 개인지 세어라. 같은 신호의 DFT 계수는 몇 개가 0이 아닌가? (나) N = 1024, 1인 칸이 번호 700일 때는 각각 몇 개인가? (다) N이 커질수록 두 개수는 어떻게 자라는가?

(가)는 하르로 하면 첫 단계 평균이 [0, 0, 0.5, 0], 차이가 [0, 0, −0.5, 0]이에요. 다음 단계 평균 [0, 0.25], 차이 [0, −0.25], 마지막 평균 0.125, 차이 −0.125. 그래서 [0.125, −0.125, 0, −0.25, 0, 0, −0.5, 0]이에요.

중간 차이 다시 봐. 중간 차이는 첫 단계 평균 [0, 0, 0.5, 0]에서 내야 해. 앞쌍은 (0 − 0)/2 = 0, 뒤쌍은 (0.5 − 0)/2 = 0.25야. 그러니까 [0.125, −0.125, 0, 0.25, 0, 0, −0.5, 0].

아, 첫 단계 차이 −0.5를 반으로 나눠 가져다 썼어요. 차이는 늘 앞 단계 평균에서 내는 건데요. 어쨌든 0이 아닌 건 넷이에요. DFT 는 한 칸짜리 신호라 계수 크기가 모두 1/8로 같아서 여덟 개 다 0이 아니에요.

(나)는 직접 세지 말고 규칙으로 말해 볼래요?

N = 8에서 0이 아닌 게 넷이었으니까… 단계마다 하나씩이었나? 첫 단계 −0.5, 중간 0.25, 마지막 −0.125, 그리고 평균 0.125.

왜 단계마다 딱 하나일까요?

단계마다 1인 칸을 덮는 차이가 딱 하나씩이니까요. 단계가 log₂N개, 거기에 전체 평균 하나를 더해요. 1024면 log₂1024 + 1 = 11개예요. DFT 는 1024개 모두고요.

코드로도 11개와 1024개예요.

(다)는요?

하르는 log₂N + 1로 아주 천천히, DFT 는 N으로 자라요. 순간 하나는 웨이블릿에서는 계수 몇 개에 모이고 푸리에에서는 전부에 퍼져요. 반대로 끝없이 울리는 사인 물결 하나는 푸리에에서 계수 하나(와 그 켤레)에 모이고요. 어느 기저가 좋은지는 신호가 어떻게 생겼느냐에 달렸네요.

문제 7(8일 기온 기록)에서 차이 하나를 지우면 그 이틀만 어긋났던 것과 같은 이유네요. 하르의 계수는 저마다 맡은 칸이 정해져 있으니까, 딸깍 하나는 딸깍이 든 칸을 맡은 계수만 건드려요.
문제 9. 한 칸 밀어도 흔들리지 않는 특징
심전도 같은 신호 256칸(느린 물결 둘 + 100번 칸 근처의 짧은 떨림 + 작은 노이즈)을 분류 모델에 넣기 전에, ① 하르 차이 계수 255개를 그대로 쓰는 특징과 ② 단계마다 차이 계수의 제곱합을 내어 숫자 8개로 쓰는 특징을 비교한다. 신호를 1칸, 2칸, 8칸 밀었을 때 특징 벡터가 얼마나 바뀌는지 「바뀐 길이 ÷ 원래 길이」로 재면 ①은 1.329, 0.839, 1.475이고 ②는 0.336, 0.243, 0.194다. (가) ①은 왜 한 칸 밀기에 이렇게 크게 바뀌는가? (나) ②는 무엇을 버려서 덜 바뀌는가? (다) ②만 쓰면 잃는 것은?

(가)는 하르가 이웃 둘씩 묶는데, 한 칸 밀면 쌍이 다르게 묶여서 차이 값이 완전히 달라지니까요. 0이던 차이가 크게 바뀌고, 큰 차이가 0이 되고.

원래 길이보다 바뀐 길이가 더 큰 1.329면, 거의 다른 신호로 본 거나 마찬가지네.

(나)는요? 제곱합은 무엇을 모르고 무엇을 아나요?

단계 하나의 제곱합은 그 굵기의 변화가 얼마나 센지만 알고, 그게 어느 칸에 있었는지는 몰라요. 자리를 버려서 덜 바뀌어요.

그런데 0.336이면 꽤 큰데요. 자리를 다 버렸으면 0이어야 하지 않아요?

한 칸 밀었을 때 가장 가는 단계의 쌍 묶음이 어떻게 되는지 떠올려 봐요.

아, 떨림이 쌍의 경계를 넘어가면 가는 단계에서 잡히던 제곱합 일부가 굵은 단계로 옮겨 가요. 8칸 밀기는 가는 세 단계의 쌍 경계와 맞아떨어져서 0.194로 더 작고요.

(다)는 자리를 버렸으니까, 떨림이 앞에 있는 심전도와 뒤에 있는 심전도를 못 가르겠네요. 그게 병의 신호라면 곤란하고요.

그래서 산란 변환은 평균 내기 전에 절댓값을 거쳐 한 번 더 웨이블릿을 거는 거구나. 버린 자리 정보 가운데 「떨림끼리 얼마나 떨어져 있나」 같은 건 다음 층에서 다시 잡게요.

합성곱 신경망에서 풀링으로 자리를 뭉개면 고양이가 사진 어디에 있든 고양이로 읽지만, 눈이 코 위에 있는지 아래에 있는지까지 뭉개면 안 되는 거랑 같아요.