Skip to content

필사 모드: torchaudio完全ガイド — オーディオ処理から音声認識、TTS、音楽分析まで

日本語
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.
원문 렌더가 준비되기 전까지 텍스트 가이드로 표시합니다.

はじめに

`torchaudio`はPyTorchの公式オーディオ処理ライブラリです。オーディオI/O、スペクトログラム変換、事前学習済みモデル(Wav2Vec2、HuBERT、Whisper)、そしてリアルタイムストリーミングまでサポートしています。

pip install torch torchaudio

Part 1: オーディオの基礎

オーディオの読み込みと保存

オーディオ読み込み

waveform, sample_rate = torchaudio.load("speech.wav")

print(f"Shape: {waveform.shape}") # [channels, samples]

print(f"Sample Rate: {sample_rate}") # 16000

print(f"Duration: {waveform.shape[1] / sample_rate:.2f}s")

チャンネル: モノラル(1) vs ステレオ(2)

if waveform.shape[0] == 2:

mono = waveform.mean(dim=0, keepdim=True) # ステレオ → モノラル

リサンプリング (44100Hz → 16000Hz)

resampler = torchaudio.transforms.Resample(

orig_freq=44100, new_freq=16000

)

waveform_16k = resampler(waveform)

保存

torchaudio.save("output.wav", waveform_16k, 16000)

サポートフォーマット: wav, flac, mp3, ogg, opus, sphere

バックエンド: sox, soundfile, ffmpeg

print(torchaudio.list_audio_backends())

オーディオの可視化

波形(Waveform)

fig, axes = plt.subplots(3, 1, figsize=(12, 8))

1. 時間領域(波形)

time_axis = torch.arange(0, waveform.shape[1]) / sample_rate

axes[0].plot(time_axis, waveform[0])

axes[0].set_title("Waveform")

axes[0].set_xlabel("Time (s)")

axes[0].set_ylabel("Amplitude")

2. スペクトログラム

spectrogram = torchaudio.transforms.Spectrogram(n_fft=1024)(waveform)

axes[1].imshow(

spectrogram[0].log2().numpy(),

aspect='auto', origin='lower', cmap='magma'

)

axes[1].set_title("Spectrogram")

3. Melスペクトログラム

mel_spec = torchaudio.transforms.MelSpectrogram(

sample_rate=sample_rate, n_fft=1024, n_mels=80

)(waveform)

axes[2].imshow(

mel_spec[0].log2().numpy(),

aspect='auto', origin='lower', cmap='magma'

)

axes[2].set_title("Mel Spectrogram")

plt.tight_layout()

plt.savefig("audio_analysis.png", dpi=150)

Part 2: コア変換(Transforms)

スペクトログラム系列

STFT (Short-Time Fourier Transform)

時間 → 時間+周波数領域への変換

spectrogram_transform = torchaudio.transforms.Spectrogram(

n_fft=1024, # FFTウィンドウサイズ(周波数解像度)

hop_length=256, # ウィンドウ移動間隔(時間解像度)

win_length=1024, # ウィンドウ長

power=2.0, # 2.0=パワー、1.0=振幅

)

spec = spectrogram_transform(waveform)

shape: [channels, n_freq_bins, time_frames]

n_freq_bins = n_fft // 2 + 1 = 513

n_fftとhop_lengthのトレードオフ:

n_fft ↑ → 周波数解像度 ↑、時間解像度 ↓

n_fft ↓ → 周波数解像度 ↓、時間解像度 ↑

一般的な設定:

├── 音声: n_fft=400~512, hop=160 (16kHz基準)

├── 音楽: n_fft=2048, hop=512 (44.1kHz基準)

└── 汎用: n_fft=1024, hop=256

Melスペクトログラム — なぜMelなのか?

人間の耳は低周波に敏感で、高周波には鈍感

Melスケール = 人間の聴覚を反映した周波数スケール

mel_transform = torchaudio.transforms.MelSpectrogram(

sample_rate=16000,

n_fft=1024,

hop_length=256,

n_mels=80, # Melフィルタ数(通常40~128)

f_min=0, # 最小周波数

f_max=8000, # 最大周波数(ナイキスト)

)

mel_spec = mel_transform(waveform)

shape: [1, 80, time_frames]

dBスケール変換(対数圧縮)

amplitude_to_db = torchaudio.transforms.AmplitudeToDB(stype='power', top_db=80)

mel_spec_db = amplitude_to_db(mel_spec)

Mel周波数変換公式:

mel = 2595 × log10(1 + freq / 700)

周波数 → Mel:

100 Hz → 150 mel (低周波: 密)

1000 Hz → 1000 mel

4000 Hz → 2146 mel

8000 Hz → 2840 mel (高周波: 疎)

→ 低周波は細かく、高周波はまとめて分析

→ 人間の聴覚に近い表現!

MFCC (Mel-Frequency Cepstral Coefficients)

MFCC = Melスペクトログラム + DCT(離散コサイン変換)

音声の「形状」を表す核心的な特徴量

mfcc_transform = torchaudio.transforms.MFCC(

sample_rate=16000,

n_mfcc=13, # MFCC係数の数(通常13~40)

melkwargs={

'n_fft': 1024,

'n_mels': 80,

'hop_length': 256,

}

)

mfcc = mfcc_transform(waveform)

shape: [1, 13, time_frames]

Delta(1次微分)+ Delta-Delta(2次微分)

→ 音声の変化率情報を追加

delta = torchaudio.functional.compute_deltas(mfcc)

delta_delta = torchaudio.functional.compute_deltas(delta)

最終特徴量: [MFCC, Delta, Delta-Delta]を連結

features = torch.cat([mfcc, delta, delta_delta], dim=1)

shape: [1, 39, time_frames]

どこで使われるか?

├── MFCC: 従来の音声認識(HMM-GMM)、話者認識

├── Mel Spectrogram: ディープラーニング音声認識(Wav2Vec2, Whisper)

├── Spectrogram: 音楽分析、環境音分類

└── Raw Waveform: End-to-endモデル(最新トレンド)

Part 3: オーディオAugmentation

時間マスキング(SpecAugment)

time_masking = torchaudio.transforms.TimeMasking(

time_mask_param=30 # 最大30フレームをマスキング

)

周波数マスキング(SpecAugment)

freq_masking = torchaudio.transforms.FrequencyMasking(

freq_mask_param=15 # 最大15チャンネルをマスキング

)

SpecAugment(音声認識精度が大幅に向上!)

augmented_spec = time_masking(freq_masking(mel_spec))

タイムストレッチ

time_stretch = torchaudio.transforms.TimeStretch()

stretched = time_stretch(complex_spec, overriding_rate=1.2) # 20%速く

ピッチシフト

pitch_shift = torchaudio.transforms.PitchShift(

sample_rate=16000, n_steps=4 # 4半音上げる

)

shifted = pitch_shift(waveform)

ノイズ追加

def add_noise(waveform, snr_db=10):

"""SNR dB基準でホワイトノイズを追加"""

noise = torch.randn_like(waveform)

signal_power = waveform.norm(p=2)

noise_power = noise.norm(p=2)

snr = 10 ** (snr_db / 20)

scale = signal_power / (snr * noise_power)

return waveform + scale * noise

Part 4: 事前学習済みモデル

Wav2Vec 2.0(音声認識)

from torchaudio.pipelines import WAV2VEC2_ASR_BASE_960H

パイプライン読み込み

bundle = WAV2VEC2_ASR_BASE_960H

model = bundle.get_model()

labels = bundle.get_labels() # トークンリスト

推論

waveform, sr = torchaudio.load("speech.wav")

if sr != bundle.sample_rate:

waveform = torchaudio.transforms.Resample(sr, bundle.sample_rate)(waveform)

with torch.no_grad():

emissions, _ = model(waveform)

CTCデコーディング(Greedy)

def greedy_decode(emissions, labels):

indices = torch.argmax(emissions, dim=-1)[0]

tokens = []

prev = -1

for idx in indices:

if idx != prev and idx != 0: # 0 = blank

tokens.append(labels[idx])

prev = idx

return "".join(tokens).replace("|", " ").strip()

text = greedy_decode(emissions, labels)

print(f"認識結果: {text}")

HuBERT(自己教師あり音声表現)

from torchaudio.pipelines import HUBERT_BASE

bundle = HUBERT_BASE

model = bundle.get_model()

with torch.no_grad():

features, _ = model(waveform)

features: [1, time_frames, 768]

→ 音声の意味的表現ベクトル

→ 話者認識、感情分析、音声分類に活用

Forced Alignment(字幕同期)

音声とテキストの時間的アライメント!

→ 字幕生成、歌詞同期に必須

from torchaudio.pipelines import MMS_FA # Multilingual!

bundle = MMS_FA

model = bundle.get_model()

tokenizer = bundle.get_tokenizer()

aligner = bundle.get_aligner()

transcript = "こんにちは はじめまして"

tokens = tokenizer(transcript)

with torch.no_grad():

emissions, _ = model(waveform)

token_spans = aligner(emissions[0], tokens)

各トークンの開始/終了時間をフレーム単位で返す!

for span, token in zip(token_spans, transcript):

start_time = span.start * model.hop_length / sample_rate

end_time = span.end * model.hop_length / sample_rate

print(f" '{token}': {start_time:.3f}s ~ {end_time:.3f}s")

Part 5: オーディオエフェクト

torchaudio.functional — GPU高速化オーディオ処理

音量調整

loud = F.gain(waveform, gain_db=6.0) # +6dB

quiet = F.gain(waveform, gain_db=-6.0) # -6dB

ハイパス/ローパスフィルタ

highpass = F.highpass_biquad(waveform, sample_rate, cutoff_freq=300)

lowpass = F.lowpass_biquad(waveform, sample_rate, cutoff_freq=3000)

イコライザ

eq = F.equalizer_biquad(

waveform, sample_rate,

center_freq=1000, # 1kHz付近

gain=5.0, # +5dBブースト

Q=0.707

)

リバーブ(残響)

rir, _ = torchaudio.load("room_impulse_response.wav") # RIRファイル

reverb = F.fftconvolve(waveform, rir)

フェードイン/アウト

fade = torchaudio.transforms.Fade(

fade_in_len=sample_rate, # 1秒フェードイン

fade_out_len=sample_rate * 3 # 3秒フェードアウト

)

faded = fade(waveform)

VAD (Voice Activity Detection)

vad = torchaudio.transforms.Vad(sample_rate=16000)

speech_only = vad(waveform) # 無音区間を除去

Part 6: 実践プロジェクト

環境音分類(Audio Classification)

class AudioClassifier(nn.Module):

def __init__(self, n_classes=10):

super().__init__()

self.mel = torchaudio.transforms.MelSpectrogram(

sample_rate=16000, n_fft=1024, n_mels=64

)

self.db = torchaudio.transforms.AmplitudeToDB()

Melスペクトログラムを「画像」のようにCNNに入力!

self.cnn = nn.Sequential(

nn.Conv2d(1, 32, 3, padding=1), nn.ReLU(), nn.MaxPool2d(2),

nn.Conv2d(32, 64, 3, padding=1), nn.ReLU(), nn.MaxPool2d(2),

nn.Conv2d(64, 128, 3, padding=1), nn.ReLU(),

nn.AdaptiveAvgPool2d((1, 1)),

)

self.fc = nn.Linear(128, n_classes)

def forward(self, waveform):

[B, 1, samples] → [B, 1, n_mels, time]

x = self.mel(waveform)

x = self.db(x)

x = self.cnn(x)

x = x.view(x.size(0), -1)

return self.fc(x)

Melスペクトログラム = オーディオの「画像」

→ CNN(ResNet, EfficientNet)で分類可能!

リアルタイムストリーミング処理

from torchaudio.io import StreamReader

マイク入力のリアルタイム処理

reader = StreamReader(src=":0", format="avfoundation") # macOS

reader.add_basic_audio_stream(

frames_per_chunk=16000, # 1秒単位

sample_rate=16000,

)

for (chunk,) in reader.stream():

chunk: [1, 16000]

mel = mel_transform(chunk)

with torch.no_grad():

prediction = model(mel)

print(f"検出: {labels[prediction.argmax()]}")

**Q1.** Melスケールが必要な理由は?

||人間の聴覚は低周波に敏感で高周波には鈍感。Melスケールはこれを反映し、低周波は細かく、高周波はまとめて分析。ディープラーニングモデルに人間の聴覚特性を反映する。||

**Q2.** n_fftを大きくするとどの解像度が上がり、どの解像度が下がるか?

||n_fft ↑ → 周波数解像度 ↑(細かい周波数の区別が可能)、時間解像度 ↓(時間変化の把握が困難に)。不確定性原理に類似したトレードオフ。||

**Q3.** SpecAugmentの2種類のマスキングとは?

||Time Masking: 時間軸で連続フレームを0でマスキング。Frequency Masking: 周波数軸で連続チャンネルを0でマスキング。データaugmentationとして音声認識精度を大幅に向上させる。||

**Q4.** MFCCとMel Spectrogramの違いとそれぞれの用途は?

||MFCC: Mel SpectrogramにDCTを適用して係数を抽出(13~40次元)。従来の音声認識、話者認識に使用。Mel Spectrogram: 周波数-時間の2D表現。ディープラーニングモデルに直接入力(最新トレンド)。||

**Q5.** Forced Alignmentの活用例は?

||音声とテキストの時間的アライメント。字幕生成(正確なタイミング)、歌詞同期(カラオケ)、発音評価(語学学習アプリ)。||

**Q6.** Wav2Vec 2.0のCTCデコーディングにおけるblankトークンの役割は?

||連続する同一トークンを区別し、出力のない時間区間を表現する。Greedyデコーディングではblank(index 0)と連続重複を除去して最終テキストを生成する。||

**Q7.** MelスペクトログラムをCNNに入力できる理由は?

||Melスペクトログラムは2D画像と同じ構造(周波数軸 × 時間軸)。1チャンネルのグレースケール画像として扱い、ResNet、EfficientNetなどの画像分類モデルをそのまま活用可能。||

関連シリーズ&おすすめ記事

- [torchvision完全ガイド](/blog/ai-platform/2026-03-03-torchvision-complete-guide) — 画像AI(姉妹編)

- [AI のための数学完全ガイド](/blog/ai/2026-03-03-math-for-ai-complete-guide) — フーリエ変換、確率(オーディオ理解に必須)

- [自分だけのGPTを作る](/blog/ai/2026-03-03-build-your-own-gpt-from-scratch) — Wav2Vec2の基盤であるTransformer

GitHub

- [torchaudio公式](https://github.com/pytorch/audio)

- [Whisper](https://github.com/openai/whisper) — OpenAI音声認識

- [ESPnet](https://github.com/espnet/espnet) — 総合音声処理ツールキット

クイズ

Q1: 「torchaudio完全ガイド —

オーディオ処理から音声認識、TTS、音楽分析まで」の主なトピックは何ですか?

torchaudioでオーディオ読み込み、スペクトログラム変換、Melフィルタバンク、MFCC、音声認識(Wav2Vec2/Whisper)、TTS、話者分離、ノイズ除去まで。オーディオAIのすべてをPyTorchで扱います。

オーディオの読み込みと保存 オーディオの可視化

スペクトログラム系列 Melスペクトログラム — なぜMelなのか? MFCC (Mel-Frequency Cepstral

Coefficients)

Wav2Vec 2.0(音声認識) HuBERT(自己教師あり音声表現) Forced Alignment(字幕同期)

環境音分類(Audio Classification) リアルタイムストリーミング処理 Q1. Melスケールが必要な理由は?

Q2. n_fftを大きくするとどの解像度が上がり、どの解像度が下がるか? Q3.

SpecAugmentの2種類のマスキングとは? Q4. MFCCとMel Spectrogramの違いとそれぞれの用途は? Q5.

Forced Alignmentの活用例は? Q6. Wav2Vec 2.0のCTCデコーディングにおけるblankトークンの役割は? Q7.

MelスペクトログラムをCNNに入力できる理由は?

현재 단락 (1/230)

`torchaudio`はPyTorchの公式オーディオ処理ライブラリです。オーディオI/O、スペクトログラム変換、事前学習済みモデル(Wav2Vec2、HuBERT、Whisper)、そしてリアルタ...

작성 글자: 0원문 글자: 9,361작성 단락: 0/230