Magnitude Scaling Technique — SGMSE의 Amplitude Transformation

복소 STFT(cSTFT) 위에서 Diffusion을 돌릴 때, 유난히 큰 스펙트럼 피크 때문에 학습이 흔들리는 문제를 어떻게 다루는지에 대한 짧은 정리.

SGMSE 논문(Richter, Welker, Lemercier, Lay, Gerkmann, Speech Enhancement and Dereverberation with Diffusion-based Generative Models, IEEE/ACM TASLP 2023)에서 처음 사용한 기법이다.

논문에서는 Amplitude Transformation이라는 단어로 표현한다.

  • STFT에서 만들어지는 Complex Coefficient를 그대로 사용하되,
  • Phase는 유지하고, Magnitude를 Power-Law로 압축해 전체 Scale을 줄이자.
Image Description

같은 신호의 |c|(왼쪽)와 β|c|^α(가운데). 크게 울리는 배음 몇 개가 화면을 독차지하던 것이, 압축 뒤에는 조용한 마찰음 덩어리와 희미한 상승음까지 보인다. 오른쪽은 α에 따른 압축 곡선.

Introduction

SGMSE의 Task: Speech Enhancement/Dereverberation을 cSTFT 도메인에서 수행.

  • Pred: Clean Speech의 Real/Imaginary Spectrogram
    • 왜? Magnitude-only Domain에서는 Diffusion Process가 어색해진다.
    • Magnitude는 음수가 될 수 없음 → Gaussian Noise를 더하면 음수값의 Amplitude가 나옴.

Amplitude Transformation

cSTFT Coefficient는 다음과 같이 정의된다:

\[c=|c|e^{i\angle c}\]


이때, \(|c|\)는 Magnitude, \(\angle c\)는 Phase다.

SGMSE는 위의 Coefficient를 다음과 같이 변환한다.

\[\tilde{c}=\beta |c|^{\alpha}e^{i\angle c}\]
  • \(\alpha \in (0,1]\) : Magnitude Compression Exponent
  • \(\beta > 0\) : Scale Factor

위를 자세히 보면, Phase, 그리고 Complex Direction은 전혀 바뀌지 않았고, Magnitude에만 Scaling이 가해졌다.

논문이 실험적으로 고른 값은 \(\alpha=0.5\), \(\beta=0.15\)다. 숫자로 감을 잡아보면: 어떤 빈의 크기가 100이고 다른 빈이 1이라면 원래는 100배 차이지만, \(\alpha=0.5\)를 거치면 \(0.15\times10=1.5\)\(0.15\times1=0.15\), 즉 10배 차이로 줄어든다. 큰 놈은 많이, 작은 놈은 조금 눌리는 것이 power-law 압축의 성질이다. 논문의 표현을 빌리면, α는 “에너지가 낮은 주파수 성분(예: 무성음의 마찰음)을 끌어올리는” 역할이고, β는 전체 크기를 diffusion 노이즈 스케일에 맞추는 정규화 역할이다.

Inverse Amplitude Transformation

위의 Representation은 역변환도 간단하다.

\[c=\left(\frac{|\tilde{c}|}{\beta}\right)^{\frac{1}{\alpha}}e^{i\angle \tilde{c}}\]

주의할 점 하나: 역변환은 \(1/\alpha\) 제곱이라 압축된 도메인에서의 작은 오차가 원래 도메인에서는 증폭된다. \(\alpha\)를 너무 작게 잡으면 큰 성분의 오차가 커지는 이유다. 0.5는 그 사이의 타협점.

import numpy as np

def compress(c, alpha=0.5, beta=0.15):        # c: complex STFT (F, T)
    return beta * np.abs(c) ** alpha * np.exp(1j * np.angle(c))

def decompress(c_tilde, alpha=0.5, beta=0.15):
    return (np.abs(c_tilde) / beta) ** (1 / alpha) * np.exp(1j * np.angle(c_tilde))

효과

  1. 너무 큰 Spectral Peak가 지배적이지 않게 만들 수 있다.
  2. Low-Energy의 Speech 성분이 부각되어 숨소리 같은 소리가 잘 보존된다.
  3. 원래 Diffusion의 Noise Scale에서 어긋나지 않는다.
  4. Extreme Magnitude가 덜 나와서 학습이 안정적이다.
  5. Perceptual Relevance가 증가한다. (결과물이 더 그럴싸해진다.)

참고 자료