14.3 Paraméterszám, MAC és aktivációmemória

14.3.1 Cél, előismeret és induló kérdés

Ez az alfejezet a konvolúciós réteg három, egymástól élesen különböző mérőszámát vezeti be: a paraméterszámot (parameter count), a MAC-műveletek számát (multiply–accumulate) és az aktivációmemóriát. A kiinduló kérdés a következő: egy 3→43\to4 csatornás, 3×33\times3-as konvolúció 112 tanulható skalárt tartalmaz; hány szorzás–összeadás műveletet végez ez a réteg egyetlen 8×88\times8-as képen? Ha a tipp tízes nagyságrendű, a válasz három nagyságrenddel nagyobb lesz: a súlymegosztás miatt minden paraméter sok térbeli pozícióban újra dolgozik. A 14.2. Több bemeneti és kimeneti csatorna alfejezetben levezetett kernel bank és a 13.3. Lokális szűrők és tanult reprezentáció alfejezetben tárgyalt súlymegosztás itt válik költségmodellé.

14.3.2 Definíciók és intuíció

Legyen egy 2D konvolúciós réteg bemenete X∈ℝN×Cin×H×WX\in\mathbb R^{N\times C_{in}\times H\times W}, súlya K∈ℝCout×(Cin/g)×kh×kwK\in\mathbb R^{C_{out}\times (C_{in}/g)\times k_h\times k_w}, biasa b∈ℝCoutb\in\mathbb R^{C_{out}}, ahol gg a groups paraméter, CinC_{in} és CoutC_{out} osztható gg-vel, a kimeneti térbeli méret pedig Hout×WoutH_{out}\times W_{out} a 14.1. Stride, padding, dilation és outputméret alfejezetben rögzített képlet szerint.

Paraméterszám. A réteg tanulható skalár együtthatóinak száma: P=Cout⋅Cing⋅kh⋅kw+Cout,P = C_{out}\cdot\frac{C_{in}}{g}\cdot k_h\cdot k_w + C_{out}, ahol az utolsó tag a bias, és csak bias=True esetén szerepel. A PP a modell kapacitásának egy durva mutatója, és független a bemenet NN, HH, WW méretétől.

MAC. Egy MAC egyetlen valós szorzásból és egyetlen valós összeadásból álló műveletpár. A réteg forward keresztkorrelációja M=N⋅Cout⋅Hout⋅Wout⋅Cing⋅kh⋅kwM = N\cdot C_{out}\cdot H_{out}\cdot W_{out}\cdot \frac{C_{in}}{g}\cdot k_h\cdot k_w MAC-ot végez. A MAC a számítási költség mutatója, és a batch méretével lineárisan nő.

FLOP konvenció. Ebben a könyvben egy MAC-ot két lebegőpontos műveletnek számolunk: egy szorzásnak és egy összeadásnak, tehát a lineáris részre FLOP=2M\text{FLOP}=2M. A bias hozzáadása kimeneti elemenként további egy összeadás, tehát a teljes forward FLOPbias=2M+NCoutHoutWout,\text{FLOP}_{bias} = 2M + N C_{out} H_{out} W_{out}, ha a bias-összeadást is számoljuk. Ez a konvenció nem univerzális; egyes profilozók a MAC-ot magát nevezik műveletnek. A félreértés elkerülésére mindig a MAC-értéket adjuk meg elsődlegesen, és a FLOP-átszámítást külön jelöljük.

Aktivációmemória. A réteg kimeneti tenzora Xout∈ℝN×Cout×Hout×WoutX_{out}\in\mathbb R^{N\times C_{out}\times H_{out}\times W_{out}}, elemszáma A=NCoutHoutWoutA=N C_{out}H_{out}W_{out}, memóriaigénye A⋅sA\cdot s bájt, ahol ss a dtype mérete: float32 esetén s=4s=4, float64 esetén s=8s=8. A visszafelé menethez a keretrendszer a bemeneti aktivációt is eltárolhatja, ezért a réteg tényleges aktivációigénye ennél nagyobb lehet.

Gradienspuffer. A visszafelé menet tenzorai: a súlygradiens ∇KL\nabla_K L alakja megegyezik KK alakjával, a biasgradiens ∇bL\nabla_b L hossza CoutC_{out}, a bemeneti gradiens ∇XL\nabla_X L alakja megegyezik XX alakjával. A gradienspuffer legalább ezen tenzorok együttes mérete; a pontos foglalás implementációfüggő, ezért itt alsó becslést adunk.

Batch-skálázás. Az NN növelése a paraméterszámot nem változtatja, a MAC-ot és az aktivációmemóriát viszont NN-szeresére növeli. Ezért nagy batch esetén a szűk keresztmetszet jellemzően a számítás és a memória, nem a paraméterek tárolása.

14.3.3 Paraméterszám: tétel és bizonyítás

Tétel (Conv2d paraméterszám). Legyen egy torch.nn.Conv2d réteg CinC_{in} bemeneti és CoutC_{out} kimeneti csatornával, gg csoporttal, kh×kwk_h\times k_w kernelmérettel, és bias=True esetén. Ekkor a réteg tanulható paramétereinek száma P=Cout⋅Cing⋅kh⋅kw+Cout.P = C_{out}\cdot\frac{C_{in}}{g}\cdot k_h\cdot k_w + C_{out}. Ha bias=False, a +Cout+C_{out} tag elmarad.

Bizonyítás. A [D10] dokumentációban rögzített súlyalak (Cout,Cin/g,kh,kw)(C_{out}, C_{in}/g, k_h, k_w). Egy (d1,…,dr)(d_1,\ldots,d_r) dimenziójú tenzor elemszáma a dimenziók szorzata, mert az indexhalmaz a {0,…,d1−1}×⋯×{0,…,dr−1}\{0,\ldots,d_1-1\}\times\cdots\times\{0,\ldots,d_r-1\} Descartes-szorzat, amelynek számossága d1⋯drd_1\cdots d_r. Ezért a súlytenzor Cout(Cin/g)khkwC_{out}(C_{in}/g)k_hk_w elemet tartalmaz. A bias tenzor alakja (Cout)(C_{out}), tehát CoutC_{out} további skalárt ad. A súly és a bias két diszjunkt paraméterhalmaz, így a számok összeadódnak. Speciálisan g=1g=1 esetén visszakapjuk a teljes csatornaösszekapcsolású képletet: CoutCinkhkw+CoutC_{out}C_{in}k_hk_w+C_{out}. ∎

A csoportos esetben minden kimeneti csatorna csak Cin/gC_{in}/g bemeneti csatornát lát; a csoportosítás tehát a paraméterszámot is csökkenti, de a csatornák közötti kapcsolatot is korlátozza. Ezt a kompromisszumot a 14.4. Csoportos és depthwise konvolúció vizsgálja részletesen.

14.3.4 MAC és FLOP: lemma és konvenció

Lemma (MAC-szám). A fenti jelölésekkel, N×Cin×H×WN\times C_{in}\times H\times W bemenet és N×Cout×Hout×WoutN\times C_{out}\times H_{out}\times W_{out} kimenet esetén a réteg forward keresztkorrelációja M=NCoutHoutWout⋅Cing⋅kh⋅kwM = N C_{out} H_{out} W_{out} \cdot \frac{C_{in}}{g}\cdot k_h\cdot k_w MAC-ot végez.

Bizonyítás. Rögzítsünk egy kimeneti elemet a (n,o,i,j)(n,o,i,j) indexnégyessel. A 14.2. Több bemeneti és kimeneti csatorna alfejezetbeli forward összeg szerint ez az elem a csatornacsoport Cin/gC_{in}/g bemeneti csatornáján és a kernel kh⋅kwk_h\cdot k_w pozícióján egy-egy szorzást végez, és az eredményeket összeadja. A szorzás–összeadás párok száma tehát (Cin/g)khkw(C_{in}/g)k_hk_w, függetlenül a konkrét pozíciótól. A kimeneti elemek száma NCoutHoutWoutN C_{out}H_{out}W_{out}. A két mennyiség szorzata adja MM-et. A bias hozzáadása kimeneti elemenként egyetlen összeadás, szorzás nélkül, ezért a MAC-értékben nem szerepel; a FLOP-konvencióban külön tételként adjuk hozzá. ∎

A MAC tehát a kimeneti tenzor elemszámának és az egy kimeneti elemhez tartozó belső összeg hosszának szorzata. A dilation paraméter nem változtatja a kernelpozíciók khkwk_hk_w számát, csak a Hout,WoutH_{out},W_{out} értékeken keresztül hat a MAC-ra.

14.3.5 Aktivációmemória, gradienspuffer és batch-skálázás

Egy réteg kimeneti aktivációja A=NCoutHoutWoutA=N C_{out}H_{out}W_{out} elemet tartalmaz. A csak a kimenetre számított memória A⋅sA\cdot s bájt. A teljes hálózat aktivációmemóriája a rétegenkénti kimenetek összege, ha minden réteg kimenetét megőrizzük a backwardhoz; a bemeneti tenzor mérete NCinHW⋅sN C_{in}HW\cdot s. A gyakorlati keretrendszerek memóriahasználata ennél nagyobb lehet a gradienspuffer és a köztes munkaterületek miatt.

A gradienspuffer legfontosabb tagjai:

Tenzor Alak Elemszám
∇KL\nabla_K L Cout×(Cin/g)×kh×kwC_{out}\times(C_{in}/g)\times k_h\times k_w P−CoutP-C_{out}
∇bL\nabla_b L CoutC_{out} CoutC_{out}
∇XL\nabla_X L N×Cin×H×WN\times C_{in}\times H\times W NCinHWN C_{in}HW

A paramétergradiensek mérete batch-független, mert a veszteség batch-átlaga már egyetlen tenzorként aggregálja a gradienst. A bemeneti gradiens viszont NN-szeresére nő. A gradiensellenőrzés 10.3. Gradiensellenőrzés és numerikus hibamérce alfejezetben float64-ben futott, ami s=8s=8 bájtos elemekkel kétszeres memóriát jelent a float32 traininghez képest; ezért a numerikus ellenőrzés és a tanítás memóriaigénye nem hasonlítható össze közvetlenül.

14.3.6 Kézi kis számpélda

Legyen N=2N=2, bemenet 2×3×8×82\times3\times8\times8. Két réteget vizsgálunk: conv1 Cin=3C_{in}=3, Cout=4C_{out}=4, k=3k=3, p=1p=1, s=1s=1; conv2 Cin=4C_{in}=4, Cout=8C_{out}=8, k=3k=3, p=1p=1, s=2s=2. A kimeneti méretek: Hout,1=8H_{out,1}=8, Hout,2=⌊(8+2−3)/2⌋+1=4H_{out,2}=\lfloor(8+2-3)/2\rfloor+1=4.

Réteg CinC_{in} CoutC_{out} k,p,sk,p,s HoutH_{out} Paraméter MAC
conv1 3 4 3, 1, 1 8 4⋅3⋅9+4=1124\cdot3\cdot9+4=112 2⋅4⋅82⋅3⋅9=138242\cdot4\cdot8^2\cdot3\cdot9=13824
conv2 4 8 3, 1, 2 4 8⋅4⋅9+8=2968\cdot4\cdot9+8=296 2⋅8⋅42⋅4⋅9=92162\cdot8\cdot4^2\cdot4\cdot9=9216
Összes 408 23040

Az aktivációk: conv1 kimenete 2⋅4⋅82=5122\cdot4\cdot8^2=512 elem, 20482048 bájt float32-ben; conv2 kimenete 2⋅8⋅42=2562\cdot8\cdot4^2=256 elem, 10241024 bájt. A FLOP-átszámítás a lineáris részre 2⋅23040=460802\cdot23040=46080; a bias-összeadások száma 512+256=768512+256=768, így a teljes forward FLOP 4684846848. A paraméterszám ugyanakkor 408408: a súlymegosztás miatt egy-egy paraméter átlagosan több mint ötvenszer vesz részt a számításban.

14.3.7 Labor: API-ellenőrzés

A labor célja, hogy a kézzel számolt értékeket a PyTorch API objektumain ellenőrizze. A kód CPU-n, float32-ben fut; seedre nincs szükség, mert csak alak- és paraméterellenőrzést végzünk. A 2.3. Izolált környezet, notebook és verzió alfejezetben rögzített izolált környezetben futtatandó.

# lab/n055/param_mac_check.py
# Munkakönyvtár: lab/n055
# Környezet: Python 3.12 tanulási profil, CPU, torch float32.
import torch
import torch.nn as nn

def conv_output_size(h, k, p, s):
    return (h + 2*p - k) // s + 1

def conv_mac(n, c_out, h_out, w_out, c_in_per_group, kh, kw):
    return n * c_out * h_out * w_out * c_in_per_group * kh * kw

def report(conv, x):
    with torch.no_grad():
        y = conv(x)
    n, c_out, h_out, w_out = y.shape
    c_in_per_group = conv.in_channels // conv.groups
    params = sum(t.numel() for t in conv.parameters())
    macs = conv_mac(n, c_out, h_out, w_out, c_in_per_group,
                    conv.kernel_size[0], conv.kernel_size[1])
    act_bytes = y.numel() * y.element_size()
    return params, macs, tuple(y.shape), act_bytes

class SmallCNN(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(3, 4, 3, padding=1)
        self.conv2 = nn.Conv2d(4, 8, 3, padding=1, stride=2)

    def forward(self, x):
        x = torch.relu(self.conv1(x))
        return self.conv2(x)

model = SmallCNN()
total_params = sum(t.numel() for t in model.parameters())
assert total_params == 408, total_params
print("Teljes paraméterszám:", total_params)

x1 = torch.zeros(2, 3, 8, 8, dtype=torch.float32)
x2 = torch.zeros(2, 4, 8, 8, dtype=torch.float32)
for name, conv, x in [("conv1", model.conv1, x1),
                      ("conv2", model.conv2, x2)]:
    p, m, shape, abytes = report(conv, x)
    print(name, "params=", p, "mac=", m, "shape=", shape,
          "activation_bytes=", abytes)
    assert (shape[2], shape[3]) == (
        conv_output_size(x.shape[2], conv.kernel_size[0],
                         conv.padding[0], conv.stride[0]),
        conv_output_size(x.shape[3], conv.kernel_size[1],
                         conv.padding[1], conv.stride[1]))

Az alábbi kimenet a képletekből számított szemléltetés, amelyet a fenti kód külön futtatásával kell ellenőrizni:

Teljes paraméterszám: 408
conv1 params= 112 mac= 13824 shape= (2, 4, 8, 8) activation_bytes= 2048
conv2 params= 296 mac= 9216 shape= (2, 8, 4, 4) activation_bytes= 1024

Az assert a kimeneti méretet is ellenőrzi, így a padding és stride képlete nem számolódhat félre. Az element_size() float32 esetén 4-et ad; ha a környezet véletlenül float64-et használna, az aktivációbájtok megduplázódnának, amit a nyomtatott érték azonnal mutat.

14.3.8 Feladatok

F1 (fogalmi, nehézség 1). Magyarázza el saját szavaival, miért lehet egy konvolúciós réteg paraméterszáma kicsi, miközben a MAC-értéke nagy. Használja a labor conv1 rétegét konkrét számpéldaként. Elvárt átadandó: a súlymegosztás és a kimeneti térbeli méret szerepeltetése; a 112 paraméter és a 13824 MAC összevetése.

F2 (levezetési, nehézség 2). Vezesse le a paraméterszámot és a MAC-ot egy csoportos konvolúcióra: Cin=6C_{in}=6, Cout=6C_{out}=6, g=3g=3, kh=kw=3k_h=k_w=3, bias=True, bemenet N=1N=1, H=W=10H=W=10, padding 00, stride 11. Ellenőrizze a g=1g=1 esetet is, és fogalmazza meg, mit veszít a csoportosítás a megtakarításért cserébe. Elvárt átadandó: mindkét eset PP, HoutH_{out} és MM értéke, valamint a kapcsolatkorlátozás megnevezése.

F3 (implementációs, nehézség 2). Írjon egy conv_stats(model, x) függvényt, amely egy nn.Sequential modellen végighaladva összegzi a konvolúciós rétegek paraméterszámát, MAC-értékét és aktivációbájtjait float32 bemenetre. A ReLU rétegen haladjon át alakváltozás nélkül. Tesztelje a labor SmallCNN modelljén. Elvárt átadandó: futtatható kód és a (408,23040,3072)(408, 23040, 3072) hármas ellenőrzése assert-tel.

F4 (hibakeresési, nehézség 2). Adott a következő hibás becslés:

params_bad = c_out * c_in * kh * kw       # (1)
macs_bad = c_out * h_out * w_out * kh * kw  # (2)

Azonosítsa mindkét hiba okát és következményét a labor conv1 rétegén, adja meg a javított képletet, és ellenőrizze, hogy a javítás visszaadja a 112 és 13824 értékeket. Elvárt átadandó: mindkét hibás részképlet hibája, a bias=True és a batch/csatornatényező szerepének magyarázata, javítás és ellenőrzés.

F5 (kísérleti/transzfer, nehézség 3). Tervezzen mérést annak eldöntésére, hogy két, azonos paraméterszámú, de eltérő konvolúciós elrendezésű modell közül melyiknek kisebb az inference-késleltetése egy adott CPU-n. Adjon meg protokollt: bemeneti méret, batch, warmup, ismétlésszám, időmérés módja, szinkronizáció, metrika és a következtetés érvényességi korlátja. Elvárt átadandó: egy lehetséges terv az alternatívák indoklásával; előre megadott győztes nem szükséges.

14.3.9 Megoldások és indoklás

F1 mintamegoldás. A conv1 súlytenzora 4⋅3⋅9=1084\cdot3\cdot9=108, biasszal együtt 112 tanulható skalárt tartalmaz. A forward során a kimeneti tenzornak 2⋅4⋅8⋅8=5122\cdot4\cdot8\cdot8=512 eleme van, és minden kimeneti elemhez 3⋅9=273\cdot9=27 szorzás–összeadás pár tartozik: 512⋅27=13824512\cdot27=13824 MAC. A paraméterek tehát azért használódnak ennyiszer, mert ugyanaz a 3×33\times3-as kernel súlya a kép minden térbeli pozíciójában újra és újra alkalmazódik; ez a 13.3. Lokális szűrők és tanult reprezentáció alfejezetben tárgyalt súlymegosztás. A paraméterszám a kapacitást, a MAC a számítási költséget méri, a kettő nem cserélhető fel.

F2 megoldás. A kimeneti méret: Hout=Wout=(10+0−3)/1+1=8H_{out}=W_{out}=(10+0-3)/1+1=8. A g=3g=3 esetben minden kimeneti csatorna Cin/g=6/3=2C_{in}/g=6/3=2 bemeneti csatornát lát. A Tétel szerint P3=6⋅63⋅3⋅3+6=6⋅2⋅9+6=114,P_3=6\cdot\frac{6}{3}\cdot3\cdot3+6=6\cdot2\cdot9+6=114, és a Lemma szerint M3=1⋅6⋅8⋅8⋅63⋅3⋅3=1⋅6⋅64⋅2⋅9=6912.M_3=1\cdot6\cdot8\cdot8\cdot\frac{6}{3}\cdot3\cdot3=1\cdot6\cdot64\cdot2\cdot9=6912. A g=1g=1 esetben minden kimeneti csatorna mind a 6 bemeneti csatornát látja: P1=6⋅6⋅9+6=330,M1=1⋅6⋅64⋅6⋅9=20736.P_1=6\cdot6\cdot9+6=330,\qquad M_1=1\cdot6\cdot64\cdot6\cdot9=20736. A csoportosítás tehát a paramétereket és a MAC-ot harmadára csökkenti, de cserébe az egyes kimeneti csatornák nem férhetnek hozzá a bemeneti csatornák többségéhez; a csatornák közötti kapcsolat korlátozott.

F3 mintakód.

# lab/n055/feladat_f3.py
import torch
import torch.nn as nn

def conv_stats(model, x, dtype_size=4):
    total_params = total_macs = total_act_bytes = 0
    h = x
    for layer in model:
        if isinstance(layer, nn.Conv2d):
            total_params += sum(p.numel() for p in layer.parameters())
            h = layer(h)
            n, c_out, h_out, w_out = h.shape
            c_in_per_group = layer.in_channels // layer.groups
            total_macs += n * c_out * h_out * w_out * c_in_per_group \
                          * layer.kernel_size[0] * layer.kernel_size[1]
            total_act_bytes += h.numel() * dtype_size
            # h.element_size() == dtype_size float32 esetén
        elif isinstance(layer, nn.ReLU):
            h = layer(h)  # az alak nem változik
        else:
            raise TypeError(f"Nem kezelt réteg: {type(layer)}")
    return total_params, total_macs, total_act_bytes

model = nn.Sequential(
    nn.Conv2d(3, 4, 3, padding=1),
    nn.ReLU(),
    nn.Conv2d(4, 8, 3, padding=1, stride=2),
)
x = torch.zeros(2, 3, 8, 8, dtype=torch.float32)
stats = conv_stats(model, x)
print(stats)
assert stats == (408, 23040, 3072), stats

A megoldás a labor SmallCNN rétegsorrendjét követi: conv1, ReLU, conv2. A ReLU alakváltozás nélkül adódik tovább, ezért az aktivációösszegbe nem számít új tenzort; ez a leképezés itt elfogadott, de a valódi keretrendszer memóriája ennél nagyobb lehet a gradienspuffer miatt.

F4 megoldás. Az (1) képlet két hibát tartalmaz: hiányzik a groups osztás, és hiányzik a bias. A labor conv1 rétegen g=1g=1, ezért a csoportosítás most nem látszik, de a bias igen: a hibás érték 4⋅3⋅9=1084\cdot3\cdot9=108, a helyes 108+4=112108+4=112. A (2) képlet elfelejti a batch NN és a bemeneti csatornacsoport Cin/gC_{in}/g tényezőjét; a labor conv1-nél a hibás érték 4⋅64⋅3⋅3=23044\cdot64\cdot3\cdot3=2304, a helyes 2⋅4⋅64⋅3⋅9=138242\cdot4\cdot64\cdot3\cdot9=13824, tehát hatszoros alulbecslés. A javítás:

params_ok = c_out * (c_in // groups) * kh * kw + (c_out if bias else 0)
macs_ok = n * c_out * h_out * w_out * (c_in // groups) * kh * kw

A labor conv1-re params_ok=112, macs_ok=13824, ami visszaadja a kézzel számolt értéket. A hiba következménye a költségmodell alulbecslése: rossz memória- és futásidő-előrejelzés.

F5 mintamegoldás. Protokollterv: rögzített bemenet N×3×64×64N\times3\times64\times64, float32, CPU; a két modell paraméterszámát egyezőre állítjuk, de az egyik kevés nagy kernelű réteget, a másik sok kis réteget használ. Bemelegítés: 20 forward hívás időmérés nélkül. Mérés: 200 ismétlés, minden ismétlésben egy teljes forward, a CPU-időt time.perf_counter-rel mérjük, és a mérést torch.inference_mode() alatt végezzük. Metrika: a batch-késleltetés mediánja és az ismétlések interkvartilis tartománya. Összehasonlítás: a két modell váltakozó sorrendben fut, hogy a hőmérsékleti és ütemezési hatás ne terhelje egyoldalúan az egyiket. Következtetési korlát: az eredmény csak erre a hardverre, dtype-ra és batchre érvényes; más gépre vagy GPU-ra nem vihető át. A mérés előre nem dönt győztest; a paraméterszám egyezése mellett a MAC és a memória-sávszélesség-hatás különválasztása további profillal lehetséges, amit a 24.2. CPU/GPU profiling és helyes időmérés dolgoz ki.

14.3.10 Tipikus tévedés ellenpéldával

A leggyakoribb tévedés: „A kevés paraméter garantálja a kis inference-késleltetést.” A paraméterszám és a késleltetés különböző mennyiség; a késleltetést a MAC, a memóriaforgalom, a kernelimplementáció és a hardver együtt határozza meg.

Ellenpélda: legyen az AA modell egyetlen bias nélküli 3×33\times3-as konvolúció 8→168\to16 csatornával, 224×224224\times224-es bemeneten. Paraméterszáma 16⋅8⋅9=115216\cdot8\cdot9=1152, MAC-értéke N=1N=1 esetén 16⋅8⋅9⋅2242≈57,816\cdot8\cdot9\cdot224^2\approx 57{,}8 millió. A BB modell egyetlen bias nélküli 1×11\times1-es konvolúció 512→512512\to512 csatornával, 7×77\times7-es bemeneten. Paraméterszáma 512⋅512=262144512\cdot512=262144, tehát több mint kétszázszor nagyobb AA-énál; MAC-értéke viszont 512⋅512⋅49≈12,8512\cdot512\cdot49\approx12{,}8 millió, tehát kisebb, mint AA-é. A paraméterszám szerinti rangsor tehát megfordulhat a számítási igény szerinti rangsorhoz képest. A tényleges késleltetést csak méréssel lehet eldönteni, de a MAC-eltérés már mutatja, hogy a paraméterszám önmagában nem elégséges előrejelző.

14.3.11 Önellenőrzés és korábbi fogalmak visszahívása

Ellenőrző lista: a paraméterképletben a bias-tag csak bias=True esetén szerepel; a groups osztja CinC_{in}-t és CoutC_{out}-ot; a MAC-képletben NN, CoutC_{out}, HoutH_{out}, WoutW_{out}, Cin/gC_{in}/g, khk_h, kwk_w mind tényező; a FLOP-átszámítás 2M2M plusz bias-add. Szélsőeset: Hout=Wout=1H_{out}=W_{out}=1, N=1N=1 esetén a MAC a kernel bank méretével egyezik, Cout(Cin/g)khkwC_{out}(C_{in}/g)k_hk_w. A gradienspuffer paraméterrésze batch-független, bemenetirésze batch-lineáris. A 14.2. Több bemeneti és kimeneti csatorna kernel bankja adja a paraméterszám tényezőit; a 13.3. Lokális szűrők és tanult reprezentáció súlymegosztása magyarázza, miért haladhatja meg a MAC a paraméterszámot; a 10.3. Gradiensellenőrzés és numerikus hibamérce float64 ellenőrzése miatt a gradiensellenőrzés memóriája nem azonos a float32 training memóriájával.

14.3.12 Rövid összefoglaló

A konvolúciós réteg paraméterszáma Cout(Cin/g)khkw+CoutC_{out}(C_{in}/g)k_hk_w+C_{out}; ez a kapacitást méri, és független a bemeneti felbontástól. A MAC-érték NCoutHoutWout(Cin/g)khkwN C_{out}H_{out}W_{out}(C_{in}/g)k_hk_w; a súlymegosztás miatt minden paraméter sok térbeli pozícióban dolgozik, ezért a MAC a kimeneti mérettel nő. A könyv FLOP-konvenciója egy MAC-ot két lebegőpontos műveletnek számol, a bias-összeadást külön tételként kezeli. Az aktivációmemória a kimeneti elemszám és a dtype méret szorzata, a gradienspuffer a paraméter- és bemenetigradiensek alakját követi. A paraméterszám nem helyettesíti a futásidő-mérést.

14.3.13 Következő alkalmazás és források

A 14.4. Csoportos és depthwise konvolúció egység a csoportos és depthwise konvolúciót vizsgálja; az itteni paraméter- és MAC-képlet ott válik a depthwise separable réteg költségmodelljének alapjává. A csoportosítás megtakarítása és kapcsolatkorlátozása közötti kompromisszumot számszerűen ott mérjük össze.