Faza 04 · lecția 12
Înțelegerea videoclipurilor — modelare temporală
Scopul lecției: Un videoclip este o secvență de imagini plus fizica ce le conectează. Fiecare model video tratează timpul fie ca axă suplimentară (convoluție 3D), fie ca secvență asupra căreia aplică atenția (transformer), fie ca caracteristică extrasă…
Versiunea curentă AlexBred.com: primele 100 de lecții ale programului în limba română.
Cuprinsul lecției
- Obiective de învățare
- Problema
- Conceptul
- Cele trei familii de arhitecturi
- 2D + agregare
- Convoluții 3D
- Transformere spațio-temporale
- Eșantionarea cadrelor
- Evaluare
- Seturi de date pe care le veți întâlni
- Construiți-l
- Pasul 1: Eșantionator de cadre
- Pasul 2: Un baseline 2D+agregare
- Pasul 3: O convoluție 3D umflată în stil I3D
- Pasul 4: Convoluție factorizată (2+1)D
- Utilizați-l
- Livrați-l
- Exerciții
- Termeni-cheie
- Lecturi suplimentare
Un videoclip este o secvență de imagini plus fizica ce le conectează. Fiecare model video tratează timpul fie ca axă suplimentară (convoluție 3D), fie ca secvență asupra căreia aplică atenția (transformer), fie ca caracteristică extrasă o dată și agregată (2D+agregare).
Tip: Învățați + construiți Limbaje: Python Cerințe prealabile: Faza 4 Lecția 03 (CNN-uri), Faza 4 Lecția 04 (Clasificarea imaginilor) Timp: ~45 de minute
Obiective de învățare
- Deosebiți cele trei abordări principale de modelare video (2D+agregare, convoluție 3D, transformer spațio-temporal) și anticipați compromisurile lor dintre cost și acuratețe
- Implementați eșantionarea cadrelor, agregarea temporală și un clasificator de referință 2D+agregare în PyTorch
- Explicați de ce nucleele 3D „umflate” ale I3D se transferă bine din ponderile ImageNet și în ce diferă o convoluție factorizată (2+1)D
- Consultați seturile de date și metricile standard pentru recunoașterea acțiunilor: Kinetics-400/600, UCF101, Something-Something V2; acuratețe top-1 la nivel de clip și de videoclip
Problema
Un videoclip de 30 de secunde la 30 fps conține 900 de imagini. Naiv, clasificarea video este clasificarea imaginilor rulată de 900 de ori, urmată de un fel de agregare. Aceasta funcționează când acțiunea este vizibilă în aproape fiecare cadru (videoclipuri cu sport, gătit, exerciții) și eșuează grav când acțiunea este definită de mișcare: „împingerea unui obiect de la stânga la dreapta” arată ca două obiecte statice în fiecare cadru individual.
Întrebarea centrală a fiecărei arhitecturi video este: când este modelată structura temporală și cum? Răspunsul determină totul — costul de calcul, strategia de preantrenare, posibilitatea de reutilizare a ponderilor ImageNet și seturile de date pe care se antrenează modelul.
Această lecție este intenționat mai scurtă decât lecțiile despre imagini statice. Mecanismele de bază pentru imagini sunt deja disponibile, iar înțelegerea videoclipurilor privește în principal dimensiunea temporală: eșantionarea, modelarea și agregarea.
Conceptul
Cele trei familii de arhitecturi
2D + agregare
Luați un CNN 2D (ResNet, EfficientNet, ViT). Rulați-l independent pe fiecare cadru eșantionat. Mediați (sau aplicați max-pooling ori attention-pooling asupra) reprezentărilor vectoriale ale fiecărui cadru. Transmiteți vectorul agregat unui clasificator.
Avantaje:
- Preantrenarea ImageNet se transferă direct.
- Este cel mai simplu de implementat.
- Este ieftin: T cadre * costul de inferență pentru o singură imagine.
Dezavantaje:
- Nu poate modela mișcarea. Acțiunea = agregatul aparițiilor.
- Agregarea temporală este invariantă la ordine; „deschide ușa” și „închide ușa” arată la fel.
Când se utilizează: sarcini dominate de aspect, transfer learning pe seturi de date video mici, baseline-uri inițiale.
Notă tehnică a traducerii: O medie temporală peste reprezentări calculate independent este invariantă la permutarea cadrelor: nu poate deosebi două clipuri cu același multiset de cadre în ordine inversă. Totuși, afirmația că un model 2D+agregare „nu poate modela mișcarea” este prea absolută: indicii de mișcare dintr-un cadru, distribuția cadrelor sau scurgerile din date pot ajuta clasificarea. Comparația corectă este că această arhitectură nu reprezintă explicit ordinea temporală. Tran et al. (2018) raportează avantajele empirice ale convoluțiilor 3D asupra rețelelor 2D în cadrul experimental studiat.
Convoluții 3D
Înlocuiți nucleele 2D (H, W) cu nuclee 3D (T, H, W). Rețeaua aplică convoluția atât peste spațiu, cât și peste timp. Familii timpurii: C3D, I3D, SlowFast.
Trucul I3D: luați un model 2D ImageNet preantrenat și „umflați” fiecare nucleu 2D copiindu-l pe o axă temporală nouă. O convoluție 2D 3x3 devine o convoluție 3D 3x3x3. Astfel, modelul 3D primește ponderi puternice preantrenate în loc să fie antrenat de la zero.
Avantaje:
- Modelează direct mișcarea.
- Umflarea I3D oferă transfer learning fără cost suplimentar.
Dezavantaje:
- Cu T/8 mai multe FLOPs decât corespondentul 2D (pentru un nucleu temporal de 3 stivuit de 3 ori).
- Nucleele temporale sunt mici; mișcarea pe rază lungă necesită o piramidă sau o abordare cu două fluxuri.
Notă tehnică a traducerii: Factorul „T/8” nu este o proprietate generală a convoluțiilor 3D. Costul depinde de formele fiecărui strat, dimensiunile nucleelor, stride-uri și rezoluția temporală; comparațiile trebuie făcute pentru arhitectura și protocolul de inferență concrete. I3D utilizează într-adevăr umflarea filtrelor 2D pentru a reutiliza arhitectura și chiar parametrii ImageNet. Consultați Carreira & Zisserman (2017).
Notă tehnică a traducerii: Umflarea nu oferă transfer learning „fără cost”: ea este o inițializare pentru o arhitectură cu forme compatibile, iar performanța depinde de preantrenarea și ajustarea ulterioară pe video, de date și de protocolul de evaluare. I3D a evaluat explicit preantrenarea Kinetics înainte de transferul către benchmarkuri mai mici. Consultați Carreira & Zisserman (2017).
Când se utilizează: recunoașterea acțiunilor în care mișcarea este semnalul (Something-Something V2, Kinetics cu clase dominate de mișcare).
Transformere spațio-temporale
Tokenizați videoclipul într-o grilă de patch-uri spațio-temporale și aplicați atenția peste toate. TimeSformer, ViViT, Video Swin, VideoMAE.
Modele de atenție importante:
- Comună — o atenție mare peste (t, h, w). Pătratică în
T*H*W; costisitoare. - Separată — două atenții pe bloc: una peste timp, una peste spațiu. Scalare aproximativ liniară.
- Factorizată — atenția temporală alternează cu atenția spațială între blocuri.
Avantaje:
- Acuratețe SOTA pe fiecare benchmark major.
- Se transferă din transformere pentru imagini (ViT) prin umflarea patch-urilor.
- Acceptă videoclipuri cu context lung prin atenție rară.
Dezavantaje:
- Necesită mult calcul.
- Necesită alegerea atentă a modelului de atenție, altfel timpul de rulare crește abrupt.
Notă tehnică a traducerii: „SOTA pe fiecare benchmark major” nu este o afirmație stabilă sau universală: rezultatele depind de setul de date, preantrenare, numărul de cadre, culturi, clipuri de test și versiunea benchmarkului. TimeSformer a raportat cele mai bune rezultate pe benchmarkurile evaluate în lucrarea sa, nu o garanție permanentă pentru toate benchmarkurile. Consultați Bertasius, Wang & Torresani (2021).
Notă tehnică a traducerii: Pentru P tokenuri spațiale pe cadru și T cadre, atenția „separată” nu este liniară în sens strict: costul atenției este de ordinul
P*T^2 + T*P^2, față deP^2*T^2pentru atenția comună. Transferul dintr-un ViT necesită, de asemenea, adaptarea patch-urilor și a reprezentărilor poziționale temporale; nu este garantat de simpla „umflare” a patch-urilor. Consultați Bertasius, Wang & Torresani (2021).
Când se utilizează: seturi de date mari, înțelegerea video de înaltă fidelitate, sarcini video+text multimodale.
Eșantionarea cadrelor
Un clip de 10 secunde la 30 fps are 300 de cadre; introducerea tuturor celor 300 în orice model este risipitoare. Strategii standard:
- Eșantionare uniformă — alegeți T cadre distribuite uniform de-a lungul clipului. Implicită pentru 2D+agregare.
- Eșantionare densă — fereastră aleatoare contiguă de T cadre. Frecventă pentru convoluții 3D deoarece mișcarea necesită cadre învecinate.
- Multi-clip — eșantionați mai multe ferestre de T cadre din același videoclip, clasificați fiecare fereastră și mediați predicțiile la testare.
T este de obicei 8, 16, 32 sau 64. T mai mare = mai mult semnal temporal, la un cost de calcul mai mare.
Evaluare
Două niveluri:
- Acuratețe la nivel de clip — modelul vede un clip de T cadre și raportează top-k.
- Acuratețe la nivel de videoclip — mediați predicțiile la nivel de clip peste mai multe clipuri din videoclip; este mai mare și mai stabilă.
Raportați-le întotdeauna pe ambele. Un model care obține 78% la nivel de clip / 82% la nivel de videoclip se bazează puternic pe medierea de la testare; unul care obține 80% / 81% este mai robust pentru fiecare clip.
Notă tehnică a traducerii: Diferența dintre cele două scoruri nu demonstrează singură robustețea sau dependența de mediere. Comparați scorurile numai când numărul de clipuri, culturile, eșantionarea și alte detalii ale protocolului sunt identice. De exemplu, ponderile
R2Plus1D_18din Torchvision raportează evaluare la nivel de videoclip cu cinci clipuri, în timp ce tabelul de modele precizează separat un protocol cu un singur crop de clip. Consultați documentația Torchvision.
Seturi de date pe care le veți întâlni
- Kinetics-400 / 600 / 700 — setul de date pentru acțiuni de uz general. 400k de clipuri; URL-uri YouTube (multe sunt acum inactive).
- Something-Something V2 — acțiuni definite de mișcare („mutarea lui X de la stânga la dreapta”). Nu poate fi rezolvat prin 2D+agregare.
- UCF-101, HMDB-51 — mai vechi, mai mici, încă raportate.
- AVA — localizarea acțiunilor în spațiu și timp; mai dificilă decât clasificarea.
Notă tehnică a traducerii: Kinetics-400 nu conține „400k de clipuri”. Descrierea originală definește 400 de clase, cu cel puțin 400 de clipuri de aproximativ 10 secunde pentru fiecare clasă; mărimea efectivă depinde de versiune și de split. Kinetics-600 are 600 de clase, cu cel puțin 600 de clipuri fiecare. URL-urile YouTube pot deveni indisponibile în timp. Consultați Kay et al. (2017) și Carreira et al. (2018).
Construiți-l
Pasul 1: Eșantionator de cadre
Eșantionatoare uniforme și dense care funcționează asupra unei liste de cadre (sau a unui tensor video).
import numpy as np
def sample_uniform(num_frames_total, T):
if num_frames_total <= T:
return list(range(num_frames_total)) + [num_frames_total - 1] * (T - num_frames_total)
step = num_frames_total / T
return [int(i * step) for i in range(T)]
def sample_dense(num_frames_total, T, rng=None):
rng = rng or np.random.default_rng()
if num_frames_total <= T:
return list(range(num_frames_total)) + [num_frames_total - 1] * (T - num_frames_total)
start = int(rng.integers(0, num_frames_total - T + 1))
return list(range(start, start + T))
Ambele întorc T indici pe care îi utilizați pentru a extrage secțiunea corespunzătoare din tensorul video.
Notă tehnică a traducerii: Fragmentul presupune
num_frames_total >= 1. Pentru un videoclip care nu a produs niciun cadru, ramuranum_frames_total <= Tva introduce indicele-1; validați decodarea înainte de eșantionare și decideți explicit dacă acel exemplu este respins sau completat cu cadre sintetice.
Pasul 2: Un baseline 2D+agregare
Rulați un ResNet-18 2D peste fiecare cadru, agregați caracteristicile prin medie și clasificați.
import torch
import torch.nn as nn
from torchvision.models import resnet18, ResNet18_Weights
class FramePool(nn.Module):
def __init__(self, num_classes=400, pretrained=True):
super().__init__()
weights = ResNet18_Weights.IMAGENET1K_V1 if pretrained else None
backbone = resnet18(weights=weights)
self.features = nn.Sequential(*(list(backbone.children())[:-1])) # global avg pool kept
self.head = nn.Linear(512, num_classes)
def forward(self, x):
# x: (N, T, 3, H, W)
N, T = x.shape[:2]
x = x.view(N * T, *x.shape[2:])
feats = self.features(x).view(N, T, -1)
pooled = feats.mean(dim=1)
return self.head(pooled)
model = FramePool(num_classes=10)
x = torch.randn(2, 8, 3, 224, 224)
print(f"output: {model(x).shape}")
print(f"params: {sum(p.numel() for p in model.parameters()):,}")
Unsprezece milioane de parametri, preantrenat ImageNet, rulează pentru fiecare cadru, calculează media și clasifică. Acest baseline se află adesea la doar 5–10 puncte de modele 3D propriu-zise în sarcini dominate de aspect — uneori chiar mai bine, deoarece reutilizează un backbone ImageNet mai puternic.
Notă tehnică a traducerii:
Tensor.viewcere ca forma dorită să fie compatibilă cu stride-urile tensorului. Dacă pipeline-ul produce un tensor necontiguu, liniax.view(...)poate eșua; utilizațix.contiguous().view(...)saureshape(...)după ce decideți explicit compromisul dintre copie și memorie. Consultați documentația PyTorch pentruTensor.view.
Pasul 3: O convoluție 3D umflată în stil I3D
Transformați o singură convoluție 2D într-o convoluție 3D repetând ponderile pe o axă temporală nouă.
def inflate_2d_to_3d(conv2d, time_kernel=3):
out_c, in_c, kh, kw = conv2d.weight.shape
weight_3d = conv2d.weight.data.unsqueeze(2) # (out, in, 1, kh, kw)
weight_3d = weight_3d.repeat(1, 1, time_kernel, 1, 1) / time_kernel
conv3d = nn.Conv3d(in_c, out_c, kernel_size=(time_kernel, kh, kw),
padding=(time_kernel // 2, conv2d.padding[0], conv2d.padding[1]),
stride=(1, conv2d.stride[0], conv2d.stride[1]),
bias=False)
conv3d.weight.data = weight_3d
return conv3d
conv2d = nn.Conv2d(3, 64, kernel_size=3, padding=1, bias=False)
conv3d = inflate_2d_to_3d(conv2d, time_kernel=3)
print(f"2D weight shape: {tuple(conv2d.weight.shape)}")
print(f"3D weight shape: {tuple(conv3d.weight.shape)}")
x = torch.randn(1, 3, 8, 56, 56)
print(f"3D output shape: {tuple(conv3d(x).shape)}")
Împărțirea la time_kernel păstrează aproximativ constante magnitudinile activărilor — important pentru a nu perturba statisticile batch-norm la prima trecere.
Pasul 4: Convoluție factorizată (2+1)D
Împărțiți o convoluție 3D într-o convoluție 2D (spațială) și una 1D (temporală). Același câmp receptiv, mai puțini parametri, acuratețe mai bună pe unele benchmarkuri.
class Conv2Plus1D(nn.Module):
def __init__(self, in_c, out_c, kernel_size=3):
super().__init__()
mid_c = (in_c * out_c * kernel_size * kernel_size * kernel_size) \
// (in_c * kernel_size * kernel_size + out_c * kernel_size)
self.spatial = nn.Conv3d(in_c, mid_c, kernel_size=(1, kernel_size, kernel_size),
padding=(0, kernel_size // 2, kernel_size // 2), bias=False)
self.bn = nn.BatchNorm3d(mid_c)
self.act = nn.ReLU(inplace=True)
self.temporal = nn.Conv3d(mid_c, out_c, kernel_size=(kernel_size, 1, 1),
padding=(kernel_size // 2, 0, 0), bias=False)
def forward(self, x):
return self.temporal(self.act(self.bn(self.spatial(x))))
c = Conv2Plus1D(3, 64)
x = torch.randn(1, 3, 8, 56, 56)
print(f"(2+1)D output: {tuple(c(x).shape)}")
Notă tehnică a traducerii: În acest cod, formula pentru
mid_ceste aleasă pentru a egala aproximativ numărul de parametri al unei convoluții 3D dense, nu pentru a-l reduce. Avantajul factorizării R(2+1)D este separarea transformărilor spațiale și temporale, plus neliniaritatea intermediară; performanța mai bună este un rezultat empiric dependent de sarcină. Consultați Tran et al. (2018).
O rețea R(2+1)D completă este aceeași ca un ResNet-18 în care fiecare convoluție 3x3 este înlocuită cu Conv2Plus1D.
Notă tehnică a traducerii: Aceasta este o aproximație pedagogică, nu o specificație completă a unei implementări R(2+1)D. De exemplu, implementarea oficială Torchvision are un stem R(2+1)D separat și blocuri VideoResNet; transferul direct al tuturor ponderilor unui ResNet-18 2D necesită o mapare explicită a straturilor, inclusiv tratarea normalizărilor și a capului de clasificare. Consultați Torchvision Video ResNet.
Utilizați-l
Două biblioteci acoperă munca video de producție:
torchvision.models.video— R(2+1)D, MViT, Swin3D cu ponderi Kinetics preantrenate. Același API ca modelele de imagini.pytorchvideo(Meta) — zoo de modele, încărcătoare de date pentru Kinetics / SSv2 / AVA, transformări standard.
Pentru modele video de limbaj-viziune (descriere video, întrebări și răspunsuri despre video), utilizați transformers (VideoMAE, VideoLLaMA, InternVideo).
Notă tehnică a traducerii: Disponibilitatea modelelor, formatul de intrare și transformările preantrenate sunt dependente de versiune și de checkpoint. Modulul video Torchvision este marcat beta și fiecare set de ponderi își furnizează propria transformare prin
weights.transforms(). În Transformers, procesorul video poate aplica eșantionare specifică modelului; nu reutilizați implicit preprocesarea unui alt checkpoint. Consultați Torchvision și Hugging Face Video Processor.
Livrați-l
Această lecție produce:
outputs/prompt-video-architecture-picker.md— un prompt care alege 2D+agregare / I3D / (2+1)D / transformer pe baza aspectului în raport cu mișcarea, a dimensiunii setului de date și a bugetului de calcul.outputs/skill-frame-sampler-auditor.md— o abilitate care inspectează eșantionatorul unui pipeline video și semnalează erori obișnuite: index off-by-one, eșantionare inegală cândnum_frames < T, lipsa decupării care păstrează raportul de aspect etc.
Exerciții
- (Ușor) Calculați FLOPs (aproximativ) pentru FramePool cu T=8 față de un ResNet 3D în stil I3D cu T=8. Justificați de ce 2D+agregare este de 3–5 ori mai ieftin.
- (Mediu) Generați un set de date video sintetic: bile aleatoare care se mișcă în direcții aleatoare, etichetate după direcția mișcării („stânga-la-dreapta”, „dreapta-la-stânga”, „diagonală-în-sus”). Antrenați FramePool pe acesta. Arătați că obține acuratețe aproape aleatoare, demonstrând că aspectul singur este insuficient pentru sarcini bazate pe mișcare.
- (Dificil) Construiți un R(2+1)D-18 înlocuind fiecare Conv2d dintr-un ResNet-18 cu
Conv2Plus1D. Umflați ponderile primei convoluții dintr-un ResNet-18 preantrenat ImageNet. Antrenați-l pe setul de date cu mișcare din exercițiul 2 și depășiți FramePool.
Notă tehnică a traducerii: „De 3–5 ori mai ieftin”, „aproape aleator” și „depășiți FramePool” sunt ipoteze de exercițiu, nu rezultate garantate. Pentru o comparație validă, fixați backbone-ul, rezoluția, numărul de cadre, numărul de parametri, augmentările, bugetul de antrenare și protocolul de evaluare. Construiți setul sintetic astfel încât ordinea temporală să fie singura informație despre etichetă; poziția inițială/finală, fundalul sau durata nu trebuie să dezvăluie direcția.
Termeni-cheie
| Termen | Ce spun oamenii | Ce înseamnă de fapt |
|---|---|---|
| 2D + agregare | „Clasificator pe fiecare cadru” | Rulați un CNN 2D pe fiecare cadru eșantionat, agregați prin medie caracteristicile în timp, clasificați |
| Convoluție 3D | „Nucleu spațio-temporal” | Nucleu care aplică convoluția pe (T, H, W); poate modela nativ mișcarea |
| Umflare | „Ridică ponderile 2D la 3D” | Inițializează ponderile unei convoluții 3D repetând ponderile unei convoluții 2D de-a lungul noii axe temporale, apoi le împarte la kernel_T pentru a păstra scara activării |
| (2+1)D | „Convoluție factorizată” | Împarte 3D în 2D spațială + 1D temporală; mai puțini parametri, neliniaritate suplimentară între ele |
| Atenție separată | „Timp, apoi spațiu” | Bloc Transformer cu două atenții pe strat: una peste tokenurile din același cadru, una peste tokenurile de la aceeași poziție |
| Clip | „Fereastră de T cadre” | Subsecvență eșantionată de T cadre; unitatea consumată de un model video |
| Acuratețe clip vs videoclip | „Două configurații de evaluare” | Clip = o eșantionare per videoclip, videoclip = media peste mai multe clipuri eșantionate |
| Kinetics | „ImageNet-ul pentru video” | 400–700 de clase de acțiuni, peste 300k clipuri YouTube, corpusul standard de preantrenare video |
Lecturi suplimentare
- I3D: Quo Vadis, Action Recognition (Carreira & Zisserman, 2017) — introduce umflarea și setul de date Kinetics
- R(2+1)D: A Closer Look at Spatiotemporal Convolutions (Tran et al., 2018) — convoluție factorizată, încă un baseline puternic
- TimeSformer: Is Space-Time Attention All You Need? (Bertasius et al., 2021) — primul transformer video puternic
- VideoMAE (Tong et al., 2022) — preantrenare cu autoencoder mascat pentru video; rețeta dominantă actuală de preantrenare
Notă tehnică a traducerii: VideoMAE este o contribuție influentă din 2022, nu o rețetă universal „dominantă” pentru toate modelele video actuale. Lucrarea raportează rezultate pentru propriul protocol și benchmarkuri; alegerea preantrenării trebuie evaluată în funcție de date, arhitectură și sarcină. Consultați Tong et al. (2022).
Sursă: Originalul în limba engleză
Navigare: ← Lecția 04.11 — Stable Diffusion — arhitectură și ajustare fină · Faza 4 — Viziune computerizată · Lecția 04.13 — Viziune 3D — nori de puncte și NeRF-uri → · Catalog complet