# Bài 2 — Giải phẫu waveform → score

[Trước](01-CAU-HOI-BAN-DO-PAPER.md) · [Tiếp](03-ADAPTATION-TRAINING.md).

## Mục tiêu và tiền đề

Tự tính shape/unit và giải thích evidence được giữ hoặc bỏ. Cần [sampling](../lop-01-nen-tang/03-SAMPLING-ALIASING-RESAMPLING.md), [STFT](../lop-01-nen-tang/04-STFT-MAGNITUDE-POWER-PHASE.md), [mel/token](../lop-01-nen-tang/05-MEL-CEPSTRUM-CHUAN-HOA-TOKEN.md), [pooling](../lop-04-ky-thuat-detector/04-LAYER-FUSION-POOLING.md). Kiến trúc **P**: PDF §§3.1–3.2 trang 3–5/Fig. 1. Hành vi code **C**: v38, theo [crosswalk](research/pipeline-sources.md).

## 1. Ba chiếc đồng hồ

Toolkit tile/truncate waveform 16 kHz tới 64.600 samples: 64600/16000 = **4,0375 s**. Detector resample 32 kHz rồi lấy prefix 2,56 s: **81.920 samples**. Upsampling tăng số mẫu, không tạo thông tin 8–16 kHz đã mất ở đầu vào 16 kHz.

Detector trừ waveform mean, tạo log-mel 128 bands trong khoảng 20–8.000 Hz. Mean subtraction xử lý mức DC, chưa là per-band CMVN hoặc amplitude/loudness normalization. v38 truyền Hanning cho Kaldi fbank; đây là source behavior của snapshot được đọc.

Window 25 ms = 800 samples; hop 10 ms = 320 samples. Với complete-window framing, không center và `snip_edges=True`:

$$T_{valid}=1+\left\lfloor(81920-800)/320\right\rfloor=254.$$

Paper báo **pad/truncate tới 256 frames**. v38 gọi Kaldi fbank/Hanning không override `snip_edges`; 254 là **C + phép tính có điều kiện** theo default trong [torchaudio 2.1.2](https://docs.pytorch.org/audio/2.1/generated/torchaudio.compliance.kaldi.fbank.html). Chưa khóa library/version của executed run. Center/n_fft convention khác có count khác. Hai padded frames zero trong log-feature space không tự là waveform silence; ASP trong source không nhận padding mask.

## 2. Shape có trục, token có footprint

| Bước | Shape với batch b | Ý nghĩa |
|---|---|---|
| Toolkit waveform | b×64.600 | Amplitude samples, 16 kHz |
| Detector crop | b×81.920 | 32 kHz, prefix 2,56 s |
| Fbank/pad | b×1×256×128 | Time frames × mel bins |
| Patch projection | b×128×768 | Grid 32 time × 4 mel |
| 13 readouts | 13 tensors b×128×768 | 12 blocks và final LayerNorm |
| Layer fusion | b×128×768 | Weighted sum giữ token axes |
| Attentive mean/std | b×1.536 | 768 mean + 768 std |
| Classifier | b×2 | Logits `(S,B)` trong template |
| Score | b | d=z_B−z_S, high=B |

Patch (8,32) cho N=(256/8)(128/32)=128. Một phần tư mel axis chưa là một phần tư bandwidth Hz. **8 hops = 80 ms** là nominal span; first-to-last frame start cách 70 ms; union tám windows là **25+7×10=95 ms**, nếu đủ valid frames. Global attention sau block có thể kết hợp toàn crop; 95 ms chưa là receptive field toàn encoder.

Kernel interpolation 16×16 → 8×32 giữ area 256, đổi geometry. Với width 768, channel 1 và bias: 768×1×8×32+768 = **197.376 parameters**. Bicubic interpolation và regenerated sinusoidal positions chưa chứng minh features thích nghi tối ưu.

## 3. Tính head từ các phép toán

Layer logits a_l là 13 scalars; softmax tạo w_l và H_i=Σ_l w_l H_i^(l). Init zero cho w_l=1/13. Final LayerNorm thêm readout, không phải block thứ 13.

Attention: e_i=vᵀtanh(WH_i+b)+c; α_i=softmax_i(e). Pooling:

$$\mu=\sum_i\alpha_iH_i,\qquad \sigma=\sqrt{\sum_i\alpha_i(H_i-\mu)^2}.$$

v38 clamp variance tối thiểu 10⁻⁸ trước sqrt. Toy một coordinate: tokens [1,3], weights [1/4,3/4] → μ=2,5, variance=0,75, σ≈0,866025. Moments chưa giữ sequence order trực tiếp; contextualized tokens có thể đã mã hóa order, nên chưa suy detector invariant khi đảo waveform.

$$P_{ASP}=(768\cdot128+128)+(128+1)=98\,561,$$
$$P_{classifier}=2\cdot1536+(1536\cdot256+256)+(256\cdot2+2)=397\,058,$$
$$P_{back}=13+98\,561+397\,058=495\,632.$$

495.632 là **T**, suy từ affine LayerNorm và linear layers có biases. Encoder 85,4 M là **P**. Frozen học ≈0,496 M, nhưng inference vẫn chạy encoder, tổng ≈85,9 M.

Classifier nhận concatenated [μ,σ], chạy **LayerNorm → Linear(1536,256) → GELU → Dropout(0,2) → Linear(256,2)**. GELU/dropout không thêm parameters; dropout có train/eval behavior khác. Freeze encoder chưa freeze classifier hoặc bỏ các nonlinear operations.

## 4. Score và hai phản ví dụ

Toy logits A=(z_B,z_S)=(7,6), B=(4,0): z_B riêng xếp A trước B, nhưng d bằng 1 và 4 nên B có score genuine cao hơn. Softmax q_B=1/(1+e⁻ᵈ) ≈ 0,731 và 0,982; monotone theo d chưa có nghĩa calibrated ngoài miền.

**Crop collision:** hai files giống prefix 2,56 s nhưng khác phần cuối cho cùng input detector; deterministic inference không phân biệt được. Đây là giới hạn quan sát của crop, chưa khẳng định corpus có case đó.

## 5. Tự kiểm

1. 256 frames có chứng minh có đúng 256 valid frames không?
2. 128 tokens có bao nhiêu temporal positions? Vì sao 80 ms khác 95 ms?
3. Vì sao 0,5 M trainable chưa đủ nói model inference chỉ 0,5 M?
4. Đổi attention weights thành [3/4,1/4] làm μ/σ của toy đổi gì?

<details>
<summary>Đáp án và reasoning</summary>

1. Không: 256 là policy sau fbank; count phụ thuộc framing. Với giả định trên, valid 254 rồi pad 2.
2. 32 time × 4 mel. 80 là tám hops; 95 là union windows; attention còn mở context rộng hơn.
3. Freeze bỏ updates, không bỏ forward/trọng số encoder. Runtime cost cần đo riêng.
4. μ=1,5; variance vẫn 0,75 và σ≈0,866025. Std giống nhau chưa đảm bảo classifier score giống nhau.

</details>

**Đào sâu:** patch frames 248–255 có sáu valid và hai padded frames theo convention 254. Trace ảnh hưởng qua projection/attention trước ASP; chưa suy EER. [Pooling Okabe et al.](https://www.isca-archive.org/interspeech_2018/okabe18_interspeech.html), [scoring lớp 4](../lop-04-ky-thuat-detector/08-INFERENCE-SCORING-FUSION.md).
