AutoInt + OBPR
Adaptacja architektury AutoInt do uczenia online z wykorzystaniem OBPR
Cel
::: block Problem: Standardowy AutoInt nie douczał się w czasie rzeczywistym
Rozwiązanie: Wydobycie binarnego embeddingu z AutoInt i przekazanie go do OBPR, który dostosowuje wagi online
note: Nasz model AutoInt do predykcji CTR działał dobrze offline, ale nie miał zdolności adaptacji w czasie rzeczywistym. Potrzebowaliśmy architektury, która: (1) zachowa jakość offline predykcji AutoInt, (2) generuje binarny embedding, który OBPR może przetwarzać online. OBPR (Online Bayesian Probit Regression) to istniejące rozwiązanie, które aktualizuje wagi wektora binarnego na podstawie spływających danych real-time.
flowchart TB subgraph Inputs CAT[Categorical] NUM[Numerical] ANUM[Array Numerical] ACAT[Array Categorical] end CAT --> EMB[Embeddings] ACAT --> AEMB[Array Embeddings] EMB --> ATT[Multi-Head Self-Attention] AEMB --> ATT ATT --> COMP[Dense 32 + BN + ReLU] EMB --> DNN[DNN 256, 256] NUM --> DNN ANUM --> DNN ACAT --> DNN AEMB --> DNN NUM --> LIN[Linear] COMP --> STACK[Concatenate] DNN --> STACK STACK --> CONCAT[Concatenate] LIN --> CONCAT STACK --> D1[Dense] D1 --> ADD((+)) LIN --> ADD ADD --> SIG[Sigmoid] SIG --> OUT1[AutoInt Output] CONCAT --> DHL["LSH losowa projekcja \n (output binarny)\n\n"] DHL --> OBPR_D[Dense] OBPR_D --> PRED[Probit] PRED --> OUT2[OBPR Output] style CONCAT fill:#B22222,color:#fff style DHL fill:#B22222,color:#fff style OBPR_D fill:#B22222,color:#fff style PRED fill:#B22222,color:#fff style OUT2 fill:#B22222,color:#fff
note: W oryginalnej architekturze binaryzacja opierała się na losowej projekcji LSH (Locality Sensitive Hashing). Warstwa BinarizationLSHLayer używała losowej macierzy W i losowego biasu b - żaden z tych parametrów nie był uczony. To powodowało, że jakość binarnej reprezentacji była niska i niestabilna. Warstwa PrepareForBayesianLearning łączyła mu i sigmę w niestandardowy sposób.
flowchart TB subgraph Inputs CAT[Categorical] NUM[Numerical] ANUM[Array Numerical] ACAT[Array Categorical] end CAT --> EMB[Embeddings] ACAT --> AEMB[Array Embeddings] EMB --> ATT[Multi-Head Self-Attention] AEMB --> ATT ATT --> COMP[Dense 32 + BN + ReLU] EMB --> DNN[DNN 256, 256] NUM --> DNN ANUM --> DNN ACAT --> DNN AEMB --> DNN NUM --> LIN[Linear] COMP --> STACK[Concatenate] DNN --> STACK STACK --> D1[Dense] D1 --> ADD((+)) LIN --> ADD ADD --> SIG[Sigmoid] SIG --> OUT1[AutoInt Output] STACK --> DHL["DeepHashingLayer \n (trenowalna projekcja) \n\n"] DHL --> SFL[SignFlipLayer] SFL --> OBPR_D[Dense] LIN --> DISC[Discretization] DISC --> OBPR_L[Dense] OBPR_D --> SUM((+)) OBPR_L --> SUM SUM --> PRED[Probit] PRED --> OUT2[OBPR Output] style DHL fill:#27ae60,color:#fff style SFL fill:#27ae60,color:#fff style DISC fill:#27ae60,color:#fff style OBPR_D fill:#27ae60,color:#fff style OBPR_L fill:#27ae60,color:#fff style PRED fill:#27ae60,color:#fff style OUT2 fill:#27ae60,color:#fff
note: Nowa architektura wprowadza kluczowe zmiany: (1) DeepHashingLayer z uczalną projekcją zamiast losowej LSH, (2) dwuścieżkową binaryzację - osobno dla deep features i linear features, (3) SignFlipLayer zapewniający rzadką reprezentację, (4) adaptacyjną dyskretyzację linear logit, (5) dedykowane warstwy OBPRMuSigmaCalculation i OBPRPrediction. Wszystkie nowe warstwy (na zielono) zastąpiły stare warstwy z losową projekcją (na czerwono na poprzednim slajdzie).
flowchart TB subgraph BEFORE["PRZED: Random LSH"] I1[embedding] --> W1["W, b ~ random"] W1 --> S1["sign(Wx + b)\n\n"] S1 --> B1["{0, 1}"] end
flowchart TB subgraph AFTER["PO: Deep Hashing"] I2[embedding] --> E2["Dense\n(trenowalny)\n\n"] E2 --> T2["× temperature\n\n"] T2 --> TH2["tanh"] TH2 -->|trening| SOFT["soft ∈ (-1,1)\n+ quantization loss\n\n"] TH2 -->|inferencja| HARD["hard ∈ {-1, 1}\n\n"] end
note: DeepHashingLayer to najważniejsza zmiana architektoniczna. Zamiast losowej projekcji, używamy uczalnej warstwy Dense. Podczas treningu wyjście to wartości ciągłe (soft) przepuszczone przez tanh, z dodatkowym quantization loss który pchnie wartości ku -1 lub 1. Podczas inferencji stosujemy twardą binaryzację. Temperature scheduling stopniowo zwiększa separację bitów w trakcie treningu. Parametr temperature rośnie liniowo od 2 do 5 w ciągu pierwszych 20 epok.
Proces trenowania
::: block
- Trening AutoInt (baseline) - standardowy trening całej sieci
- Adaptacja warstwy Discretization
- Zamrożenie AutoInt + trening warstw OBPR - zamrożenie wszystkich warstw bazowego AutoInt. Trening z temperature scheduling
- Ekstrakcja wag do standalone modelu OBPR
- Douczanie modelu OBPR offline
Finalne metryki
::: block
| Etap | valid BSS | test BSS | valid AUC PRC | test AUC PRC |
|---|---|---|---|---|
| AutoInt baseline | 0.031 | 0.027 | 0.060 | 0.056 |
| OBPR pre-fit | 0.030 | 0.028 | 0.060 | 0.056 |
| OBPR post-fit | 0.031 | 0.028 | 0.060 | 0.057 |
note: Finalne metryki pokazują, że OBPR output praktycznie nie traci jakości względem bazowego AutoInt. BSS na valid: 0.031 vs 0.031 (delta ~0). BSS na test: 0.028 vs 0.027 (OBPR minimalnie lepszy!). AUC PRC na valid: 0.060 vs 0.060 (identyczny). Dla porównania, na początku prac delta BSS wynosiła -0.036, co oznaczało dramatyczną degradację. Redukcja degradacji z -0.036 do ~0 to główne osiągnięcie tego projektu.
Co zadziałało
::: block
- DeepHashingLayer (trenowalna projekcja) + linear temperature scheduling
- Dyskretyzacja linear_logit
Co nie zadziałało
::: block
- Uczenie jednej sieci end-to-end z State-Through Estimator (STE)
- Konkatenacja linear_logit zamiast dyskretyzacji
- Wyuczalna binaryzacja linear_logit
- Balance loss
- Decorelation loss