TEKNİK YAZI / Yapay Zekâ Entegrasyonları

WaveNet: Ham Ses Dalgasını Örnek Örnek Üreten Model

WaveNet, ham sesi örnek örnek üreten autoregressive bir modeldir; dilated causal convolution, alıcı alan, μ-law ile 256 seviye ve Parallel WaveNet anlatılır.

WaveNet, DeepMind’dan Aäron van den Oord ve arkadaşlarının 2016’da tanıttığı, ham ses dalgasını her adımda bir örnek üreterek autoregressive biçimde modelleyen bir sinir ağıdır. PixelCNN mimarisinden türetilmiştir ve genişletilmiş nedensel konvolüsyon (dilated causal convolution) ile katman sayısını fazla artırmadan binlerce örneklik bir bağlam görür. Metinden konuşma (TTS) deneylerinde insan dinleyiciler WaveNet’i dönemin en iyi parametrik ve birleştirmeli (concatenative) sistemlerinden belirgin biçimde daha doğal buldu.

Aşağıda ham sesi modellemenin zorluğu, nedensel (causal) ve genişletilmiş (dilated) konvolüsyonla alıcı alan hesabı, kapılı aktivasyon, μ-law ile 256 seviyeli çıkış, koşullama, eğitim ile üretim arasındaki hız farkı ve WaveNet’ten sonra gelen modeller ele alınıyor.

Ham sesi modellemenin zorluğu

Ham ses yüksek zaman çözünürlüğüne sahiptir: 16 kHz örnekleme hızında bir saniyelik ses 16.000 değerden oluşur. Bir hece ya da kelime binlerce örneğe yayılır. Her değeri öncekilere bağlı üreten bir model, hem çok uzun bir bağlamı görmek hem de bu kadar adımı tek tek üretmek zorundadır.

WaveNet öncesinde TTS sistemlerinin dalga biçimi üretim aşaması iki yaklaşıma dayanıyordu:

WaveNet, vocoder parametreleri yerine ses örneklerinin kendisini modelleyerek bu son aşamanın yerini alır.

Autoregressive model

WaveNet bir ses dalgası x = (x_1, …, x_T) için ortak olasılığı koşullu olasılıkların çarpımına ayırır:

p(x) = ∏ p(x_t | x_1, ..., x_{t-1}),   t = 1, ..., T

Pratikte her tahmin, önceki örneklerin tamamına değil, ağın alıcı alanı (receptive field) içindeki örneklere bağlıdır. Aynı ayrıştırma görüntüde PixelCNN’in piksel piksel üretimine karşılık gelir; WaveNet tek boyutlu zaman ekseninde aynı fikri kullanır.

Nedensel ve genişletilmiş (dilated) konvolüsyon

Nedensel (causal) konvolüsyon, t anındaki çıktının yalnız t ve öncesindeki girdilere bağlı olmasını sağlar. Tek boyutlu sinyalde bunu sağlamanın kolay yolu girdiyi yalnız soldan doldurmaktır. Dilation olmadan çekirdek boyutu k olan L katmanın alıcı alanı L · (k − 1) + 1 örnektir. WaveNet k = 2 kullanır; 10 katmanla yalnız 11 örnek görülür.

Genişletilmiş (dilated) konvolüsyon, çekirdeği d adım aralıklı girdilere uygular. WaveNet dilation’ı her katmanda iki katına çıkarır ve bu diziyi tekrarlar: 1, 2, 4, …, 512, 1, 2, 4, …, 512, … Alıcı alan katman sayısıyla üstel büyür:

alıcı alan = 1 + (k − 1) · Σ d_i
k = 2, d = 1, 2, 4, ..., 512  →  1 + 1023 = 1024 örnek (16 kHz'de 64 ms)

Makale, böyle bir 1-512 bloğunu 1×1024 boyutlu bir konvolüsyonun daha verimli ve doğrusal olmayan bir karşılığı olarak tanımlar. Blokları üst üste koymak hem kapasiteyi hem de alıcı alanı artırır. Makalenin TTS deneylerinde alıcı alan 240 milisaniyeydi.

import torch
import torch.nn as nn
import torch.nn.functional as F


class CausalConv1d(nn.Conv1d):
    def __init__(self, in_ch, out_ch, kernel_size=2, dilation=1):
        super().__init__(in_ch, out_ch, kernel_size, dilation=dilation)
        self.left_pad = (kernel_size - 1) * dilation

    def forward(self, x):  # x: (B, C, T)
        x = F.pad(x, (self.left_pad, 0))  # yalnız sola dolgu: geleceğe bakılmaz
        return super().forward(x)  # (B, out_ch, T)


def receptive_field(dilations, kernel_size=2):
    return 1 + (kernel_size - 1) * sum(dilations)


block = [2**i for i in range(10)]  # 1, 2, 4, ..., 512
print(receptive_field(block))  # 1024
print(receptive_field(block * 3))  # 3070

Bu katmanlarda t konumundaki çıktı x_t’yi de görür. Bu yüzden eğitimde hedef bir adım kaydırılır: t konumundaki çıktı x_{t+1}’in dağılımı olarak eğitilir ve tahmin edilen değer hiçbir zaman girdide yer almaz.

Kapılı aktivasyon, artık ve atlama bağlantıları

WaveNet, Gated PixelCNN’deki kapılı aktivasyon birimini kullanır. Her katmanda genişletilmiş konvolüsyonun çıktısı iki yarıya ayrılır; biri tanh’tan (filtre), diğeri sigmoid’den (kapı) geçer:

z = tanh(W_f * x) ⊙ σ(W_g * x)

Makale, ilk deneylerde bu doğrusal olmayan fonksiyonun ses sinyallerinde ReLU’dan belirgin biçimde daha iyi çalıştığını raporlar. Katmanlar artık (residual) bağlantılarla birbirine eklenir; her katmanın atlama (skip) çıkışı toplanır ve ReLU, 1×1 konvolüsyon, ReLU, 1×1 konvolüsyon ve softmax’tan geçerek çıkış dağılımını verir. Artık ve atlama bağlantıları yakınsamayı hızlandırır ve daha derin ağların eğitilmesini sağlar.

class ResidualBlock(nn.Module):
    def __init__(self, channels, skip_channels, dilation):
        super().__init__()
        self.conv = CausalConv1d(channels, 2 * channels, 2, dilation)
        self.res = nn.Conv1d(channels, channels, 1)
        self.skip = nn.Conv1d(channels, skip_channels, 1)

    def forward(self, x):  # x: (B, C, T)
        f, g = self.conv(x).chunk(2, dim=1)  # filtre ve kapı, her biri (B, C, T)
        z = torch.tanh(f) * torch.sigmoid(g)  # kapılı aktivasyon
        return x + self.res(z), self.skip(z)  # (B, C, T) ve (B, S, T)

Çıkış: μ-law ve 256 seviye

WaveNet her adımda sürekli bir değer değil, olası değerler üzerinde kategorik bir dağılım üretir. Makale bu seçimi PixelRNN çalışmasına dayandırır: kategorik dağılım daha esnektir ve dağılımın şekli hakkında varsayım yapmadığı için keyfî dağılımları modelleyebilir.

Ham ses genellikle 16 bit tamsayı olarak saklanır; bu, her adımda 65.536 sınıflı bir softmax demektir. Problemi küçültmek için önce μ-law sıkıştırma-genişletme (companding, ITU-T G.711) dönüşümü uygulanır, ardından değerler 256 seviyeye nicemlenir:

f(x_t) = sign(x_t) · ln(1 + μ |x_t|) / ln(1 + μ),   −1 < x_t < 1,   μ = 255

Bu doğrusal olmayan nicemleme küçük genlikleri daha ince, büyük genlikleri daha kaba adımlarla temsil eder. Makaleye göre doğrusal nicemlemeden belirgin biçimde daha iyi bir geri çatım sağlar ve geri çatılan ses orijinaline çok yakın duyulur.

import numpy as np


def mu_law_encode(x, mu=255):
    # x: [-1, 1] aralığında float ses örnekleri
    y = np.sign(x) * np.log1p(mu * np.abs(x)) / np.log1p(mu)  # [-1, 1]
    return np.rint((y + 1) / 2 * mu).astype(np.int64)  # 0..255 tamsayı sınıflar


def mu_law_decode(q, mu=255):
    y = 2 * q.astype(np.float64) / mu - 1  # [-1, 1]
    return np.sign(y) * np.expm1(np.abs(y) * np.log1p(mu)) / mu

Koşullama

WaveNet, ek bir girdi h’ye koşullu dağılımı p(x | h) da modelleyebilir:

TTS deneylerinde WaveNet, metinden çıkarılan dilbilimsel özelliklere yerel olarak koşullandı. Bu özellikler fonem kimlikleri, hece vurgusu, kelimedeki hece sayısı ve hecenin öbek içindeki konumu gibi fonem, hece, kelime, öbek ve cümle düzeyinde bilgilerdir; koşul tek tek harfler değildir. Bir model türü bunlara ek olarak logaritmik temel frekans (log F0) değerlerine de koşullandı. Log F0 ve fonem sürelerini metinden tahmin eden ayrı modeller eğitildi. Yani WaveNet metin işleme ön ucunu ortadan kaldırmadı; dalga biçimi üretim aşamasının yerini aldı. Daha sonra Tacotron 2 (Shen ve ark., 2017), metinden tahmin edilen mel-spektrogramlara koşullanan bir WaveNet vocoder kullandı; TTS sistemlerinin aşamaları ayrı bir yazıda anlatılıyor.

Eğitim paralel, üretim sıralı

Eğitimde gerçek ses dalgasının bütün örnekleri bilindiği için tüm zaman adımlarının tahminleri tek ileri geçişte paralel hesaplanır (teacher forcing). Üretimde ise her yeni örnek ağa geri verilir ve bir sonraki tahmin ancak ondan sonra yapılabilir. 16 kHz’de bir saniyelik ses için 16.000 sıralı adım gerekir; orijinal WaveNet bu yüzden gerçek zamanlı ürün kullanımına uygun değildi.

İki yönde çözüm geliştirildi:

Sonuçlar

Makaledeki 5 puanlık doğallık ölçeğinde (MOS) Kuzey Amerika İngilizcesi sonuçları:

SistemMOS
LSTM-RNN tabanlı istatistiksel parametrik3,67
HMM tabanlı birleştirmeli (unit selection)3,86
WaveNet (dilbilimsel özellikler + log F0)4,21
Doğal konuşma, 8 bit μ-law4,46
Doğal konuşma, 16 bit doğrusal PCM4,55

Mandarin Çincesinde de WaveNet (4,08) iki temel sistemi (3,79 ve 3,47) geçti. TTS verisi İngilizce için 24,6, Mandarin için 34,8 saatlik profesyonel kayıttan oluşuyordu. Makale ayrıca müzik üretimi ve TIMIT veri setinde fonem tanıma deneyleri içerir.

Sınırlar

WaveNet’ten sonra

SampleRNN (Mehri ve ark., 2016) ise WaveNet’ten türemiş değildir; aynı dönemde önerilen bağımsız bir ham ses modelidir. Hiyerarşik yapısında üst katmanlar farklı zaman ölçeklerinde çalışan RNN’lerden, en alt katman ise örnek düzeyinde çalışan autoregressive bir çok katmanlı algılayıcıdan (MLP) oluşur. Google Cloud Text-to-Speech belgeleri, Ekim 2026 itibarıyla standart seslerin yanında WaveNet ile üretilen ses türünü listelemeye devam ediyor.

Sonuç

WaveNet, ham ses olasılığını doğrudan modellemenin, genişletilmiş nedensel konvolüsyonla geniş bağlam kurmanın ve kategorik çıkışla ses üretmenin uygulanabilir olduğunu gösterdi; sonraki vocoder ve ses üretim çalışmalarının çoğu bu fikirlerden etkilendi. Mimariyi anlamak autoregressive modelleri ve TTS tarihini kavramak için değerlidir. Gerçek zamanlı bir ürün için sıfırdan bir model seçiliyorsa ise paralel üretim yapan GAN, flow veya diffusion tabanlı vocoder’lar daha uygun bir başlangıçtır.

Birincil kaynaklar