ML Learning Hub
الصوتمتوسط

تعلم الآلة للصوت والكلام

من الموجات الخام إلى ميزات MFCC — كيف تستمع الآلات وتفهم الكلام

من الصوت الخام إلى ميزات MFCC — أطياف STFT وMel filterbanks وشبكات CNN للصوت وخسارة CTC وSpecAugment وWhisper للتعرف على الكلام.

40 min
8 مخططات
8 المفاهيم المغطاة

المتطلبات الأساسية

CNN Architectures
NLP Text Classification

المفاهيم المغطاة

STFTMel SpectrogramMFCCAudio CNNCTC LossSpecAugmentWhisperASR

الصيغ الرئيسية

تحويل فورييه القصير المدى

حساب المحتوى الترددي داخل نافذة متزلجة — ينتج المطياف

مقياس ميل

تعيين التردد الخطي على مقياس إدراكي — البشر يسمعون النغمة بشكل لوغاريتمي خاصة عند الترددات العالية

MFCC

تحويل جيب تمام منفصل لطاقات بنك فلتر ميل اللوغاريتمي — ميزات صوتية مضغوطة وغير مرتبطة

خسارة CTC

التصنيف الزمني الاتصالي — يتيح تدريباً بدون محاذاة بين إطارات الإدخال ورموز الإخراج

محاكاة تفاعلية

Loading visualization…
🎯

لماذا تعلم الآلة الصوتي أصعب من تعلم الصور

motivation

يطرح الصوت تحديات فريدة: (1) البنية الزمنية — المعنى يعتمد على الترتيب والتوقيت لا المحتوى فقط. (2) الطول المتغير — يمكن أن يكون الكلام 0.1 ثانية أو 60 ثانية؛ حشو الصوت يغير الصمت المدرك. (3) اللاثبات — الخصائص الإحصائية تتغير مع الوقت (النغمة، السرعة، اللهجة). (4) التباين غير ذي الصلة — نفس المحتوى بصوت أسرع أو لهجة مختلفة أو ضجيج خلفية يجب أن ينتج نفس المخرج. (5) لا بنية مكانية مباشرة — عينات الصوت الخام سلاسل زمنية أحادية الأبعاد بـ16,000-44,100 هرتز. يحوّل تحويل المطياف الصوت إلى تمثيل ثنائي الأبعاد يشبه الصورة يمكن لشبكات CNN معالجته.

تُحوّل Siri وGoogle Assistant وAlexa وWhisper جميعاً الكلام إلى مطياف (أو بنوك فلتر ميل متعلّمة) قبل تطبيق الشبكات العصبية — الموجات الخام نادراً ما تُغذّى مباشرةً.

💡

خط أنابيب معالجة الصوت

intuition

**الموجة الخام:** x(t) — سلسلة زمنية أحادية الأبعاد لقيم ضغط الصوت بـ16 كيلوهرتز. **المطياف:** طبّق التحويل الفورييه القصير المدى (STFT) مع نافذة متزلجة (~25ms، خطوة ~10ms) → مصفوفة المحتوى الترددي عبر الزمن. المناطق المضيئة = الترددات الموجودة. **مطياف ميل:** طبّق بنك فلتر مثلثي (مقياس ميل) لتقليص محور الترددات إلى 80-128 نطاقاً ميلياً — يتوافق مع الإدراك السمعي البشري. **MFCC:** طبّق log + تحويل جيب تمام منفصل (DCT) لإزالة الترابط بين طاقات بنك الفلتر → 13-40 معامل مضغوط لكل إطار. التعلم العميق الحديث غالباً يتجاوز MFCC ويستخدم مطياف log-mel مباشرةً.

مقطع مدته 1 ثانية بـ16 كيلوهرتز = 16,000 عينة خام. بعد STFT بنوافذ 25ms/خطوة 10ms = ~100 إطار × 80 نطاق ميل = 8,000 قيمة. ضغط 50% مع الاحتفاظ بكل المحتوى الإدراكي.

⚙️

خط أنابيب التعرف على الكلام

algorithm
1

المعالجة المسبقة: إعادة أخذ العينات إلى 16 كيلوهرتز، تطبيع السعة، الحشو/القص إلى طول ثابت.

2

مطياف Log-Mel: تطبيق STFT (نافذة=25ms، خطوة=10ms، n_fft=400)، تطبيق 80 بنكاً لفلترة ميل، أخذ اللوغاريتم.

3

المشفّر: Conv ثنائية الأبعاد ذات خطوة → مشفّر Transformer مع تضمينات موضعية مطلقة — يُشفّر السياق الصوتي.

4

المفكّك: مفكّك Transformer تلقائي الانحدار مُعلَّق على مخرج المشفّر. يُدرَّب بالإجبار التعليمي على النصوص المنقولة.

5

خسارة CTC أو الإنتروبيا المتقاطعة بين تسلسل الرموز المتنبأ والنص الحقيقي.

6

الاستدلال: بحث الشعاع (عرض 5) يفك تشفير أرجح تسلسل رموز. إعادة تسجيل اختيارية بنموذج لغوي.

7

ما بعد المعالجة: تطبيق استعادة علامات الترقيم، تطبيع النص العكسي (تحويل 'ثلاثة دولارات' → '3$').

</>

ميزات الصوت مع librosa + OpenAI Whisper

code
python71 lines
import librosa
import numpy as np
import matplotlib.pyplot as plt

class="tok-comment"># ── class="tok-num">1. Load audio ─────────────────────────────────────────────────────────────
y, sr = librosa.load(class="tok-str">"speech.wav", sr=class="tok-num">16000)   class="tok-comment"># resample to 16kHz
print(fclass="tok-str">"Duration: {len(y)/sr:.2f}s, Sample rate: {sr}Hz")

class="tok-comment"># ── class="tok-num">2. Waveform to spectrogram ────────────────────────────────────────────────
D = librosa.stft(y, n_fft=class="tok-num">400, hop_length=class="tok-num">160, win_length=class="tok-num">400)
spectrogram = np.abs(D)**class="tok-num">2               class="tok-comment"># power spectrogram (magnitude²)
S_db = librosa.power_to_db(spectrogram, ref=np.max)  class="tok-comment"># decibel scale

class="tok-comment"># ── class="tok-num">3. Mel spectrogram ────────────────────────────────────────────────────────
S_mel = librosa.feature.melspectrogram(
    y=y, sr=sr,
    n_fft=class="tok-num">400,
    hop_length=class="tok-num">160,        class="tok-comment"># 10ms stride at 16kHz
    win_length=class="tok-num">400,        class="tok-comment"># 25ms window at 16kHz
    n_mels=class="tok-num">80,             class="tok-comment"># class="tok-num">80 Mel bins (Whisper standard)
    fmin=class="tok-num">50, fmax=class="tok-num">8000,    class="tok-comment"># filter between 50Hz and 8kHz
)
log_mel = librosa.power_to_db(S_mel, ref=np.max)
print(fclass="tok-str">"Log-mel shape: {log_mel.shape}")   class="tok-comment"># (class="tok-num">80, T)

class="tok-comment"># ── class="tok-num">4. MFCC ──────────────────────────────────────────────────────────────────
mfcc = librosa.feature.mfcc(y=y, sr=sr, n_mfcc=class="tok-num">13, n_mels=class="tok-num">80)
mfcc_delta  = librosa.feature.delta(mfcc)    class="tok-comment"># velocity: change over time
mfcc_delta2 = librosa.feature.delta(mfcc, order=class="tok-num">2)  class="tok-comment"># acceleration

features = np.vstack([mfcc, mfcc_delta, mfcc_delta2])  class="tok-comment"># class="tok-num">39-dim feature vector
print(fclass="tok-str">"MFCC + deltas shape: {features.shape}")  class="tok-comment"># (class="tok-num">39, T)

class="tok-comment"># ── class="tok-num">5. Audio classification with CNN ─────────────────────────────────────────
import torch, torch.nn as nn

class AudioCNN(nn.Module):
    def __init__(self, n_classes: int):
        super().__init__()
        self.conv = nn.Sequential(
            nn.Conv2d(class="tok-num">1, class="tok-num">32, kernel_size=class="tok-num">3, padding=class="tok-num">1), nn.ReLU(),
            nn.MaxPool2d(class="tok-num">2),
            nn.Conv2d(class="tok-num">32, class="tok-num">64, kernel_size=class="tok-num">3, padding=class="tok-num">1), nn.ReLU(),
            nn.MaxPool2d(class="tok-num">2),
            nn.Conv2d(class="tok-num">64, class="tok-num">128, kernel_size=class="tok-num">3, padding=class="tok-num">1), nn.ReLU(),
            nn.AdaptiveAvgPool2d((class="tok-num">4, class="tok-num">4)),    class="tok-comment"># global average pool to fixed size
        )
        self.fc = nn.Sequential(
            nn.Linear(class="tok-num">128*class="tok-num">4*class="tok-num">4, class="tok-num">256), nn.ReLU(), nn.Dropout(class="tok-num">0.4),
            nn.Linear(class="tok-num">256, n_classes),
        )
    def forward(self, x):
        class="tok-comment"># x: (B, class="tok-num">1, n_mels, T) — log-mel as single-channel class="tok-str">"image"
        return self.fc(self.conv(x).flatten(class="tok-num">1))

model = AudioCNN(n_classes=class="tok-num">10)   class="tok-comment"># e.g., UrbanSound8K: class="tok-num">10 sound classes
x = torch.randn(class="tok-num">8, class="tok-num">1, class="tok-num">80, class="tok-num">128)  class="tok-comment"># batch of class="tok-num">8 audio clips, class="tok-num">80 mels, class="tok-num">128 frames
print(model(x).shape)            class="tok-comment"># (class="tok-num">8, class="tok-num">10)

class="tok-comment"># ── class="tok-num">6. OpenAI Whisper (speech-to-text) ───────────────────────────────────────
class="tok-comment"># pip install openai-whisper
import whisper
model_w = whisper.load_model(class="tok-str">"base")          class="tok-comment"># 74M params
result  = model_w.transcribe(class="tok-str">"speech.wav")
print(result[class="tok-str">"text"])                          class="tok-comment"># full transcript
print(result[class="tok-str">"language"])                      class="tok-comment"># detected language

class="tok-comment"># Timestamps for each word
result_ts = model_w.transcribe(class="tok-str">"speech.wav", word_timestamps=True)
for seg in result_ts[class="tok-str">"segments"]:
    print(fclass="tok-str">"[{seg['start']:.2f}s → {seg['end']:.2f}s] {seg['text']}")
⚠️

زيادة البيانات حيوية للصوت

pitfall

تُفرط نماذج الصوت في التخصيص بسهولة لأن متحدثاً واحداً يمكن أن يبدو مختلفاً تماماً عبر ظروف التسجيل. التعزيزات الرئيسية: (1) **SpecAugment** (Google, 2019) — إخفاء نطاقات ترددية وخطوات زمنية عشوائياً في مطياف log-mel. بسيط لكن فعّال للغاية — مستخدم في Whisper. (2) **تمديد الوقت** — تغيير الإيقاع دون تغيير النغمة. (3) **تحويل النغمة** — تغيير النغمة دون تغيير الإيقاع. (4) **خلط ضجيج الخلفية** — إضافة ضجيج الأصوات والموسيقى والمرور بمستويات SNR متنوعة. (5) **تلافي استجابة الغرفة النبضية (RIR)** — محاكاة بيئات صوتية مختلفة. بدون تعزيز يفشل النموذج المدرَّب على كلام ذو جودة استوديو فشلاً تاماً على المكالمات الهاتفية.

أدّى SpecAugment وحده إلى تحسين معدل خطأ الكلمات (WER) لنموذج LAS بنسبة 13.9% نسبياً على LibriSpeech — ربما أفضل تقنية تعزيز منفردة في تاريخ التعرف التلقائي على الكلام.

?اختبار المعرفة

يتم حفظ التقدم في متصفحك — لا حاجة لحساب.

تحتاج مهندس ذكاء اصطناعي أو عالم بيانات؟

أبني نماذج تعلم آلي مخصصة، ووكلاء ذكاء اصطناعي، ورؤية حاسوب، وأتمتة — من الفكرة إلى الإنتاج.