torchaudio.transforms.MelSpectrogram 으로 멜 스펙트로그램 생성시 STFT과정에서 FFT를 사용함
이러한 STFT를 Short-Time Discrete Cosine Transform, 즉 DCT를 사용한 변환으로 바꾸어 스펙트로그램을 생성하고 멜스케일을 적용하여 멜 스펙트로 그램을 생성하도록 수정하고자함 (DCT는 실수 연산으로 복소연산보다 1/2배의 연산량 이점이 있음)
아래 코드는 STFT에 FFT 대신 DCT를 사용한 Spectrogram 생성 코드임
import librosa
import scipy
import numpy as np
def sdct(signal, frame_length, frame_step, window="hamming"):
"""Compute Short-Time Discrete Cosine Transform of `signal`.
No padding is applied to the signals.
Parameters
----------
signal : Time-domain input signal of shape `(n_samples,)`.
frame_length : Window length and DCT frame length in samples.
frame_step : Number of samples between adjacent DCT columns.
window : Window specification passed to ``librosa.filters.get_window``.
Default: "hamming". Window to use for DCT.
Returns
-------
dct : Real-valued F-T domain DCT matrix of shape `(frame_length, n_frames)`
"""
framed = librosa.util.frame(x=signal, frame_length=frame_length, hop_length=frame_step)
if window is not None:
window = librosa.filters.get_window(window, frame_length, fftbins=True).astype(
signal.dtype
)
framed = framed * window[:, np.newaxis]
return scipy.fft.dct(framed, norm="ortho", axis=-2)
def spectrogram_dct(waveform: torch.Tensor,
n_fft: int,
hop_length: int,
power: Optional[float] = 2.0) -> torch.Tensor:
# pack batch
shape = waveform.size()
waveform = waveform.reshape(-1, shape[-1])
# dct_spec = sdct_torch(waveform, frame_length=n_fft, frame_step=hop_length)
spec_f = sdct(waveform.numpy(), frame_length=n_fft, frame_step=hop_length)
# unpack batch
spec_f = torch.from_numpy(spec_f).reshape(shape[:-1] + spec_f.shape[-2:])
if power is not None:
if power == 1.0:
return spec_f.abs()
return spec_f.abs().pow(power)
class DCTSpectrogram(Module):
def __init__(self,
sample_rate: int = 44100,
n_fft: int = 4096,
hop_length: int = 1024,
power: Optional[float] = 2.0
) -> None:
super().__init__()
self.sample_rate = sample_rate
self.n_fft = n_fft
self.hop_length = hop_length
self.power = power
def forward(self, waveform: Tensor) -> Tensor:
# Calculate DCT spectrogram
dct_spectrogram = spectrogram_dct(waveform, self.n_fft, self.hop_length, self.power)
return dct_spectrogram
4., 위 코드로부터 생성된 Spectrogram으로 Mel scale을 적용하여 멜 스펙트로그램을 생성하는 DCTMelspectrogram 이라는 클래스를 작성하려면 어떻게 해야할까요
아래 답변은 Anthropic의 Claude-2 모델로 자동 생성한 것으로, 정확하지 않을 수 있습니다.
잘못된 답변을 보셨다면 댓글로 첨삭 지도 부탁드립니다.
오준님 안녕하세요.
제가 질문하신 melspectrogram 생성 문제에 대한 답변드리겠습니다.
먼저 질문하신 내용을 정리하면, torchaudio의 MelSpectrogram에서 STFT 과정에 FFT 대신 DCT를 사용하여 Spectrogram을 생성한 후, 이를 기반으로 MelSpectrogram을 생성하는 DCTMelSpectrogram 클래스를 구현하고자 한다는 것입니다.
아래 답변은 OpenAI의 GPT-4-Turbo 모델로 자동 생성한 것으로, 정확하지 않을 수 있습니다.
잘못된 답변을 보셨다면 댓글로 첨삭 지도 부탁드립니다.
안녕하세요! 멜 스펙트로그램 생성 시 FFT 대신 DCT를 사용하여 음성 처리를 하고자 하는 문제에 대해 질문해주셨군요. 질문을 잘 이해했습니다. 여러분이 원하는 것은 기존의 FFT 기반 STFT 대신 DCT를 사용하여 스펙트로그램을 생성한 후, 이를 멜 스케일로 변환하는 DCTMelspectrogram 클래스를 구현하는 것으로 보입니다.
이 문제를 해결하기 위해, 먼저 DCT 기반 스펙트로그램을 생성하는 과정을 구현하셨고, 이제 이 스펙트로그램에 멜 스케일을 적용하여 멜 스펙트로그램을 생성하는 클래스를 작성하고자 합니다. 멜 스케일 변환을 위해서는 멜 필터 뱅크를 생성하고, 이를 DCT 스펙트로그램에 적용해야 합니다. PyTorch와 torchaudio 라이브러리를 활용하여 이를 구현할 수 있습니다.
아래는 DCTMelspectrogram 클래스의 예시 구현입니다. 이 구현에서는 torchaudio의 mel_scale 모듈을 사용하여 멜 필터 뱅크를 생성하고, 이를 DCT 스펙트로그램에 적용합니다.
import torch
import torchaudio
from torch import Tensor, nn
from typing import Optional
class DCTMelspectrogram(nn.Module):
def __init__(self,
sample_rate: int = 44100,
n_fft: int = 4096,
hop_length: int = 1024,
n_mels: int = 128, # 멜 필터 뱅크의 수
power: Optional[float] = 2.0
) -> None:
super().__init__()
self.dct_spectrogram = DCTSpectrogram(sample_rate, n_fft, hop_length, power)
self.mel_scale = torchaudio.transforms.MelScale(n_mels=n_mels,
sample_rate=sample_rate,
n_stft=(n_fft // 2) + 1)
def forward(self, waveform: Tensor) -> Tensor:
# DCT 스펙트로그램 계산
dct_spec = self.dct_spectrogram(waveform)
# 멜 스케일 적용
mel_spec = self.mel_scale(dct_spec)
return mel_spec
위 코드에서 DCTSpectrogram 클래스는 질문에서 제공된 DCT 기반 스펙트로그램 생성 클래스입니다. DCTMelspectrogram 클래스는 이 DCTSpectrogram을 사용하여 DCT 스펙트로그램을 계산한 후, torchaudio.transforms.MelScale을 사용하여 멜 스케일로 변환합니다. n_mels 파라미터는 생성할 멜 필터 뱅크의 수를 지정하며, 이를 통해 멜 스펙트로그램의 해상도를 조절할 수 있습니다.
이 예시 구현을 통해 원하는 DCT 기반 멜 스펙트로그램 변환을 수행할 수 있습니다. 추가적으로, PyTorch와 torchaudio의 공식 문서를 참고하시면 더 많은 정보를 얻을 수 있습니다:
아래 답변은 OpenAI의 GPT-4 모델로 자동 생성한 것으로, 정확하지 않을 수 있습니다.
잘못된 답변을 보셨다면 댓글로 첨삭 지도 부탁드립니다.
안녕하세요, ojun.kwon님! 멜 스펙트로그램 생성 시 FFT 대신 DCT를 사용하여 음성 처리를 하고자 하는 문제에 대해 질문해주셨군요. 질문을 잘 이해했습니다. 여러분이 원하는 것은 기존의 STFT 과정에서 FFT 대신 DCT를 사용하여 스펙트로그램을 생성하고, 이를 멜 스케일로 변환하여 멜 스펙트로그램을 생성하는 클래스 DCTMelspectrogram을 작성하는 것으로 보입니다. 이 과정에서 실수 연산의 이점을 활용하고자 하시는군요.
이 문제를 해결하기 위해, 먼저 DCT를 사용하여 스펙트로그램을 생성하는 과정을 구현하셨고, 이제 해당 스펙트로그램에 멜 스케일을 적용하는 과정을 추가해야 합니다. PyTorch와 torchaudio 라이브러리를 활용하여 이를 구현할 수 있습니다. 아래는 DCTMelspectrogram 클래스를 작성하는 방법에 대한 예시 코드입니다.
import torch
import torchaudio
import numpy as np
from torch.nn import Module
from typing import Optional
# 여기에 이전에 정의한 sdct 및 spectrogram_dct 함수를 포함시킵니다.
class DCTMelspectrogram(Module):
def __init__(self,
sample_rate: int = 44100,
n_fft: int = 4096,
hop_length: int = 1024,
n_mels: int = 128, # 멜 필터뱅크의 개수
power: Optional[float] = 2.0
) -> None:
super().__init__()
self.sample_rate = sample_rate
self.n_fft = n_fft
self.hop_length = hop_length
self.n_mels = n_mels
self.power = power
# 멜 스케일 변환을 위한 멜 필터뱅크 생성
self.mel_filter = torchaudio.transforms.MelScale(n_mels=n_mels,
sample_rate=sample_rate,
n_stft=(n_fft // 2) + 1)
def forward(self, waveform: torch.Tensor) -> torch.Tensor:
# DCT 스펙트로그램 계산
dct_spectrogram = spectrogram_dct(waveform, self.n_fft, self.hop_length, self.power)
# 멜 스케일 적용
mel_spectrogram = self.mel_filter(dct_spectrogram)
return mel_spectrogram
위 코드에서 DCTMelspectrogram 클래스는 DCT를 사용하여 스펙트로그램을 생성한 후, torchaudio의 MelScale을 사용하여 멜 스케일로 변환합니다. MelScale은 주어진 스펙트로그램에 멜 필터뱅크를 적용하여 멜 스펙트로그램을 생성합니다. 이 클래스를 사용하면 원하는 멜 스펙트로그램을 얻을 수 있습니다.
이 예시 코드는 기본적인 구현을 보여주며, 실제 사용 시에는 파라미터를 조정하거나 추가적인 전처리 및 후처리 과정이 필요할 수 있습니다.
더 자세한 정보와 PyTorch 및 torchaudio의 사용법에 대해서는 공식 문서를 참고하시기 바랍니다: