14.4 Csoportos és depthwise konvolúció

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

A 14.3. Paraméterszám, MAC és aktivációmemória egységben a teljes konvolúció paraméterszámát és MAC-igényét vezettük le. Itt a groups paramétert vizsgáljuk: ez nem pusztán egy gyorsítási kapcsoló, hanem a bemeneti és kimeneti csatornák közötti kapcsolat explicit korlátozása. Előismeret a cross-correlation képlet, a súlyalak és a kimeneti méret; Pythonból elég a listaszámolás, PyTorchból a torch.nn.Conv2d alapvető használata.

Induló kérdés: egy Cin=4C_{in}=4, Cout=6C_{out}=6, 3×33\times3-as rétegnél mit jelent a groups=2? Hány súlyt takarít meg, és melyik bemeneti csatorna szűnhet meg hatni valamelyik kimeneti csatornára? A válaszhoz először a pontos definíció kell.

14.4.2 A groups paraméter definíciója

Legyen gg a csoportok száma. A [D10] dokumentáció szerint a PyTorch Conv2d groups paramétere megköveteli, hogy g∣Cing\mid C_{in} és g∣Coutg\mid C_{out} is teljesüljön; pontosabban mindkettő osztható gg-vel. Jelölje

rin=Cing,rout=Coutg. r_{in}=\frac{C_{in}}{g},\qquad r_{out}=\frac{C_{out}}{g}.

A súlytensor alakja ekkor

K∈ℝCout×rin×kh×kw, K\in\mathbb R^{C_{out}\times r_{in}\times k_h\times k_w},

a bias pedig b∈ℝCoutb\in\mathbb R^{C_{out}}. A qq-edik csoport, q∈{0,…,g−1}q\in\{0,\dots,g-1\}, a bemeneti csatornák közül a

𝒞in(q)={qrin,…,(q+1)rin−1} \mathcal C^{(q)}_{in}=\{q r_{in},\dots,(q+1)r_{in}-1\}

halmazt, a kimeneti csatornák közül az

𝒞out(q)={qrout,…,(q+1)rout−1} \mathcal C^{(q)}_{out}=\{q r_{out},\dots,(q+1)r_{out}-1\}

halmazt kapja. A lényeg: a qq-edik kimeneti csoport csatornái kizárólag a qq-edik bemeneti csoport csatornáit látják. A cross-correlation képlete szimmetrikus zero paddinggel, sh,sws_h,s_w stride-dal:

Y[n,o,i,j]=∑c=qrin(q+1)rin−1∑u=0kh−1∑v=0kw−1X[n,c,shi+u−ph,swj+v−pw]K[o,c−qrin,u,v]+b[o], Y[n,o,i,j] = \sum_{c=q r_{in}}^{(q+1)r_{in}-1} \sum_{u=0}^{k_h-1}\sum_{v=0}^{k_w-1} X\Big[n,c,\; s_h i+u-p_h,\; s_w j+v-p_w\Big]\, K\big[o,\; c-q r_{in},\; u,\; v\big]\;+\;b[o],

ahol o∈𝒞out(q)o\in\mathcal C^{(q)}_{out}. Két részletre érdemes figyelni. Először: a súly második indexe 00 és rin−1r_{in}-1 között fut, ezért az abszolút cc bemeneti csatornából le kell vonni a csoport kezdőindexét, qrinq r_{in}-et. Másodszor: a bias továbbra is kimeneti csatornánként egy skalár; a csoportosítás a bias alakját nem változtatja.

A groups=1 eset az eddigi teljes konvolúció: rin=Cinr_{in}=C_{in}, rout=Coutr_{out}=C_{out}, minden bemeneti csatorna minden kimeneti csatornához kapcsolódik. A másik szélső eset a depthwise konvolúció.

14.4.3 Depthwise konvolúció és multiplier

Ha g=Cing=C_{in}, akkor rin=1r_{in}=1: minden bemeneti csatorna saját kernelhalmazt kap, és a csatornák között nincs keverés. A CoutC_{out} kimeneti csatornát a

Cout=mCin C_{out}=m C_{in}

összefüggés írja le, ahol mm pozitív egész, az úgynevezett depthwise multiplier. A súlyalak ilyenkor

K∈ℝmCin×1×kh×kw. K\in\mathbb R^{m C_{in}\times 1\times k_h\times k_w}.

A groups=C_in és Cout=CinC_{out}=C_{in} választás tehát m=1m=1; ekkor minden bemeneti csatornához pontosan egy kimeneti csatorna tartozik. Ha m=2m=2, minden bemeneti csatornából két különböző, egymástól független szűrt kép készül, de a két kimeneti csatorna ugyanazt az egy bemeneti csatornát látja.

A kifejezés „depthwise separable” két réteg kompozícióját jelöli: először egy depthwise réteg térbeli szűrést végez csatornánként, majd egy pontszerű, 1×11\times1-es konvolúció keveri a csatornákat. A pointwise réteg definíciója:

Y[n,o,i,j]=∑c=0Cin−1X[n,c,i,j]K[o,c,0,0]+b[o]. Y[n,o,i,j]=\sum_{c=0}^{C_{in}-1} X[n,c,i,j]\,K[o,c,0,0]+b[o].

Ez minden (i,j)(i,j) térbeli pozícióban ugyanazt a Cin→CoutC_{in}\to C_{out} affin leképezést hajtja végre; a kernel térbeli kiterjedése 1×11\times1, tehát térbeli keverés nincs. A depthwise réteg ezzel szemben térbeli keverést végez, de csatornakeverést nem. A kettő együtt közelítőleg szétválasztja a térbeli és csatornairányú számítást; ennek költségmodelljét a 19.1. Depthwise separable és pointwise réteg egység vizsgálja majd.

14.4.4 Állítás: a grouped operátor blokkmátrix-szerkezete

A levezetési kötelezettség a group korlátozás lineáris algebrai alakja. Rögzítsük a paddinget, stride-ot és kernelt, és lapítsuk a bemeneti X∈ℝCin×H×WX\in\mathbb R^{C_{in}\times H\times W} tensort csatorna-major sorrendben egy x∈ℝCinHWx\in\mathbb R^{C_{in}HW} vektorrá: előbb a 00 csatorna minden pixele, majd az 11 csatorna, és így tovább. Hasonlóan lapítsuk a kimenetet y∈ℝCoutHoutWouty\in\mathbb R^{C_{out}H_{out}W_{out}} vektorrá. A zero padding mellett a cross-correlation lineáris operátor; legyen MM a mátrixa, azaz y=Mxy=Mx a bias nélkül.

Állítás (grouped operátor blokkdiagonális alakja). Ha g∣Cing\mid C_{in} és g∣Coutg\mid C_{out}, akkor a csatorna-major rendezésben az MM mátrix

M=(B(0)0⋯00B(1)⋯0⋮⋮⋱⋮00⋯B(g−1)) M=\begin{pmatrix} B^{(0)} & 0 & \cdots & 0\\ 0 & B^{(1)} & \cdots & 0\\ \vdots & \vdots & \ddots & \vdots\\ 0 & 0 & \cdots & B^{(g-1)} \end{pmatrix}

alakú, ahol a qq-edik blokk

B(q)∈ℝroutHoutWout×rinHW B^{(q)}\in\mathbb R^{\,r_{out}H_{out}W_{out}\;\times\; r_{in}HW}

éppen annak a teljes cross-correlationnak a mátrixa, amely a qq-edik csoport

K̃(q)=K[qrout:(q+1)rout,:,:,:]∈ℝrout×rin×kh×kw \widetilde K^{(q)}=K\big[q r_{out}:(q+1)r_{out},\; :,\; :,\; :\big] \in\mathbb R^{r_{out}\times r_{in}\times k_h\times k_w}

súlyához tartozik.

Bizonyítás. A csatorna-major rendezésben az inputvektor qq-edik blokkja, x(q)∈ℝrinHWx^{(q)}\in\mathbb R^{r_{in}HW}, pontosan a 𝒞in(q)\mathcal C^{(q)}_{in} csatornák pixeleit tartalmazza. A kimeneti yy vektor qq-edik blokkja, y(q)∈ℝroutHoutWouty^{(q)}\in\mathbb R^{r_{out}H_{out}W_{out}}, a 𝒞out(q)\mathcal C^{(q)}_{out} csatornák pixeleit tartalmazza. A definiáló képlet szerint minden o∈𝒞out(q)o\in\mathcal C^{(q)}_{out} kimeneti csatorna összegzése csak a c∈𝒞in(q)c\in\mathcal C^{(q)}_{in} csatornákon fut. Ezért y(q)y^{(q)} nem függ x(p)x^{(p)}-től, ha p≠qp\neq q; a mátrix qq-edik sorblokkjában minden nem-qq oszlopblokk zérus. A qq-edik diagonális blokk elemeit a fenti képlet cc-re és oo-ra megszorított változata adja. Ha az összegzésben bevezetjük a csoporton belüli indexeket c′=c−qrinc' = c-q r_{in} és o′=o−qrouto'=o-q r_{out}, a kapott egyenlet alakja pontosan egy rinr_{in} bemeneti és routr_{out} kimeneti csatornás, K̃(q)\widetilde K^{(q)} súlyú, ugyanolyan paddingű és stride-ú cross-correlation. Ez pedig definíció szerint B(q)B^{(q)}. Ezzel az állítást beláttuk. ▫\square

A bias bb hozzáadása nem rontja a szerkezetet: minden kimeneti koordinátához a saját csatornájának skalárja adódik, csatornák közötti keverés nélkül. Az állítás egyben megmutatja, mit jelent a „kapcsolat korlátozása”: a csatornacsoportok szintjén a kapcsolati mátrix diagonális, míg groups=1 esetén egyetlen blokk van, tehát minden csatornapár össze van kötve. A mátrix blokkjain belül a térbeli pozíciók természetesen továbbra is keverednek a kernel által; a group a térbeli keverést nem tiltja, csak a csatornák közötti utat szűkíti.

14.4.5 Kézi kis példa

Vegyünk egy N=1N=1, Cin=3C_{in}=3, m=2m=2, tehát Cout=6C_{out}=6, g=3g=3 depthwise konfigurációt, 3×33\times3 bemenettel, 2×22\times2 kernellel, padding és bias nélkül. A kimeneti méret Hout=Wout=2H_{out}=W_{out}=2. Állítsunk be minden depthwise kernel elemet 11-re, és legyen a cc bemeneti csatorna konstans cc értékű: X[0,c,⋅,⋅]=cX[0,c,\cdot,\cdot]=c.

A 2×22\times2-es csupa egyes kernel egy konstans cc bemeneten a 4c4c összeget adja mind a négy kimeneti pozícióban. A cc bemeneti csatornához a o=2co=2c és o=2c+1o=2c+1 kimeneti csatornák tartoznak, tehát a várt kimenet

Y[0,:,0,0]=(0,0,4,4,8,8). Y[0,:,0,0]=(0,0,4,4,8,8).

A 00 bemeneti csatorna nem hat az 11 kimeneti csatornára, és a 22 bemeneti csatorna sem hat a 00 kimeneti csatornára; a kapcsolat csatornánként izolált. Ez a legkisebb példa, amelyben a depthwise korlátozás ténylegesen látszik.

# munkakönyvtár: lab/
import torch

torch.manual_seed(0)
conv = torch.nn.Conv2d(3, 6, (2, 2), padding=0, groups=3, bias=False,
                       dtype=torch.float32)
with torch.no_grad():
    conv.weight.fill_(1.0)

x = torch.zeros(1, 3, 3, 3, dtype=torch.float32)
for c in range(3):
    x[0, c].fill_(float(c))

y = conv(x)
print(y.shape)
print(y[0, :, 0, 0])

A várt, a képletből számított kimenet (1,6,2,2) és tensor([0., 0., 4., 4., 8., 8.]); ez képletből számított érték, nem mérési jegyzőkönyv. A súlyok ellenőrzése:

assert conv.weight.shape == (6, 1, 2, 2)

A második dimenzió 11, nem 33; ez a depthwise alak legfontosabb ellenőrzése.

14.4.6 Labor: csoportkonfiguráció, súlyszámlálás, hibás oszthatóság

A labor célja három konfiguráció paraméterszámának összehasonlítása, a súlyalak ellenőrzése és egy oszthatósági hiba pontos megfogása. Az alábbi szkript a 14.3. Paraméterszám, MAC és aktivációmemória képletét használja, és a [D10] dokumentációban rögzített in_channels/out_channels oszthatósági feltételre épít.

# munkakönyvtár: lab/
import torch

def count_params(conv):
    return sum(p.numel() for p in conv.parameters())

def describe(name, cin, cout, k, groups):
    conv = torch.nn.Conv2d(cin, cout, (k, k), bias=True, groups=groups,
                           dtype=torch.float32)
    w = conv.weight
    expected_w = cout * (cin // groups) * k * k
    assert w.shape == (cout, cin // groups, k, k), w.shape
    assert expected_w + cout == count_params(conv)
    mac_one_output = (cin // groups) * k * k
    print(f"{name:22s} weight={tuple(w.shape)} params={count_params(conv):3d} "
          f"MAC/output={mac_one_output}")

describe("full g=1",         3, 12, 3, 1)
describe("grouped g=3",      3, 12, 3, 3)
describe("depthwise g=3",    3,  3, 3, 3)
describe("pointwise 1x1",    3, 12, 1, 1)

try:
    torch.nn.Conv2d(5, 12, 3, groups=2)
except ValueError as e:
    print("hibas_groups:", type(e).__name__, "oszthatosagi feltetel serult")

A szkript a képletből számított várt kimenete, nem mért futás:

Konfiguráció Súlyalak Paraméterek
full g=1 (12, 3, 3, 3) 336
grouped g=3 (12, 1, 3, 3) 120
depthwise g=3 (3, 1, 3, 3) 30
pointwise 1x1 (12, 3, 1, 1) 48

A depthwise réteg után egy 3→123\to12 csatornás pointwise réteg összesen 30+48=7830+48=78 paramétert használ a teljes réteg 336336 paraméteréhez képest. A MAC-érték kimeneti elemenként a full esetben 3⋅9=273\cdot9=27 szorzás, a grouped esetben 1⋅9=91\cdot9=9; a pointwise utótag hozzáadását a 19.1. Depthwise separable és pointwise réteg végzi el teljes költségmodellként.

Számított paraméterszám a labor konfigurációban - A képletekből számított érték, nem futtatott mérés.

A hibás oszthatóság ellenpéldája: Cin=5C_{in}=5, g=2g=2 esetén 2∤52\nmid5, ezért a konstruktor ValueError kivételt vet. Ugyanígy sérül a feltétel, ha CoutC_{out} nem osztható. A pontos hibaüzenet szövege PyTorch-verziófüggő; a labor a kivétel típusát és az oszthatósági feltételt ellenőrzi, nem a konkrét szöveget.

14.4.7 Feladatok

F1 (fogalmi, nehézség 1). Magyarázza el, mi a különbség a groups=1, a groups=C_in és egy közbülső groups=2 konfiguráció között a csatornák kapcsolatában. Adjon kis ellenpéldát arra, hogy a groups nem értelmezhető, ha g∤Cing\nmid C_{in} vagy g∤Coutg\nmid C_{out}. Átadandó: definíciók, egy-egy konkrét csatornahalmaz-példa és az oszthatósági hiba oka.

F2 (levezetési/bizonyítási, nehézség 2). Legyen Cin=6C_{in}=6, Cout=6C_{out}=6, g=3g=3, kernel 3×33\times3, input 4×44\times4, padding 00, stride 11. Adja meg a csoportonkénti be- és kimeneti csatornahalmazokat, a súly alakját, a paraméterszámot, és a csatorna-major lapításban az MM mátrix blokkméreteit. Írja fel a középső csoport második kimeneti csatornájának egyetlen kimeneti elemére a teljes összegképletet. Átadandó: halmazok, alakok, blokkméretek és a képlet minden indexhatárral.

F3 (implementációs, nehézség 2). Írjon PyTorch-szkriptet, amely a fenti depthwise kézi példát ellenőrzi torch.allclose hívással, megszámolja a paramétereket egy groups=1 és egy groups=3 rétegnél, és próbaként megkísérli a Cin=5C_{in}=5, g=2g=2 konstrukciót, elkapva a ValueError-t. Átadandó: futtatható kód, elvárt kimenet és tolerancia.

F4 (hibakeresési, nehézség 2). Egy fejlesztő a korábbi NumPy referencia conv2d függvényét hívja groups=2 argumentummal. A függvény csak groups=1-et támogat, és a paramétert csendben figyelmen kívül hagyja. Hol van a hiba, mi a következménye, és milyen teszt fedné fel azonnal? Átadandó: a hiba oka, egy olyan input, amelyen a helyes és a hibás kimenet különbözik, és a javítás módja.

F5 (kísérleti/transzfer, nehézség 2). Tervezzen GlyphLab-kísérletet, amely egy teljes 3×33\times3-as konvolúciót hasonlít össze egy depthwise separable réteggel azonos kimeneti csatornaszámon. Adja meg a kérdést, a megfigyelési egységet, a splitet, a baseline-t, a változó tényezőt, a metrikát és a következtetés korlátját. Átadandó: protokoll, legalább két lehetséges kimenetel értelmezése; előre rögzített győztest ne állítson.

14.4.8 Megoldások és indoklás

F1. groups=1 esetén egyetlen csoport van: mind a CinC_{in} bemeneti csatorna összekötött mind a CoutC_{out} kimeneti csatornával. groups=C_in esetén rin=1r_{in}=1, a qq-edik kimeneti csoport csak a qq bemeneti csatornát látja; ez a depthwise eset. Ha g=2g=2 és Cin=4C_{in}=4, Cout=6C_{out}=6, akkor a 00 csoport az {0,1}\{0,1\} bemeneti és {0,1,2}\{0,1,2\} kimeneti csatornát, az 11 csoport a {2,3}\{2,3\} bemeneti és {3,4,5}\{3,4,5\} kimeneti csatornát kapja. A 00 bemeneti csatorna nem hathat a 33 kimeneti csatornára. Az oszthatóság azért kell, mert a csoportoknak egyenlő méretű partíciót kell alkotniuk; Cin=5C_{in}=5, g=2g=2 esetén nem tudunk két egyenlő, diszjunkt csatornahalmazt képezni. Ugyanez a kimeneti oldalon is fennáll.

F2. rin=rout=6/3=2r_{in}=r_{out}=6/3=2. A csoportok: q=0q=0: be {0,1}\{0,1\}, ki {0,1}\{0,1\}; q=1q=1: be {2,3}\{2,3\}, ki {2,3}\{2,3\}; q=2q=2: be {4,5}\{4,5\}, ki {4,5}\{4,5\}. A súly alakja (6,2,3,3)(6,2,3,3); a tanulható paraméterszám 6⋅2⋅9+6=1146\cdot2\cdot9+6=114. A kimeneti méret Hout=Wout=2H_{out}=W_{out}=2, a lapított input mérete 6⋅16=966\cdot16=96, a lapított output mérete 6⋅4=246\cdot4=24. Az MM mátrix 24×9624\times96-os, három blokkal; minden blokk routHoutWout=8r_{out}H_{out}W_{out}=8 sor és rinHW=32r_{in}HW=32 oszlop méretű, tehát B(q)∈ℝ8×32B^{(q)}\in\mathbb R^{8\times32}. A középső q=1q=1 csoport második kimeneti csatornája o=3o=3, a bemeneti csatornák c∈{2,3}c\in\{2,3\}. Padding nélkül, sh=sw=1s_h=s_w=1 mellett egy (i,j)(i,j) kimeneti elem:

Y[n,3,i,j]=∑c=23∑u=02∑v=02X[n,c,i+u,j+v]K[3,c−2,u,v]+b[3]. Y[n,3,i,j]=\sum_{c=2}^{3}\sum_{u=0}^{2}\sum_{v=0}^{2} X[n,c,i+u,j+v]\,K[3,\,c-2,\,u,\,v]+b[3].

A csoporton belüli második súlyindex mindig c−qrin=c−2c-q r_{in}=c-2.

F3. A teljes megoldás:

# munkakönyvtár: lab/
import torch

torch.manual_seed(0)

conv = torch.nn.Conv2d(3, 6, (2, 2), padding=0, groups=3, bias=False,
                       dtype=torch.float32)
with torch.no_grad():
    conv.weight.fill_(1.0)
x = torch.zeros(1, 3, 3, 3, dtype=torch.float32)
for c in range(3):
    x[0, c].fill_(float(c))
y = conv(x)
expected = torch.tensor([[[[0., 0.], [0., 0.]],
                          [[0., 0.], [0., 0.]],
                          [[4., 4.], [4., 4.]],
                          [[4., 4.], [4., 4.]],
                          [[8., 8.], [8., 8.]],
                          [[8., 8.], [8., 8.]]]])
assert y.shape == (1, 6, 2, 2)
assert torch.allclose(y, expected, atol=1e-6)

full = torch.nn.Conv2d(3, 6, 3, groups=1, bias=True, dtype=torch.float32)
grouped = torch.nn.Conv2d(3, 6, 3, groups=3, bias=True, dtype=torch.float32)
n_full = sum(p.numel() for p in full.parameters())
n_grp = sum(p.numel() for p in grouped.parameters())
print(n_full, n_grp, full.weight.shape, grouped.weight.shape)

try:
    torch.nn.Conv2d(5, 12, 3, groups=2)
except ValueError as e:
    print("elkapva", type(e).__name__)

A várt kimenet: 168 60, (6,3,3,3) és (6,1,3,3), majd elkapva ValueError. A 3→63\to6 full réteg paraméterszáma 6⋅3⋅9+6=1686\cdot3\cdot9+6=168, a grouped 6⋅1⋅9+6=606\cdot1\cdot9+6=60. A tolerancia 10−610^{-6} bőven elég, mert a példa egész értékű szorzásokat tartalmaz, és az összegek float32-ben pontosan reprezentálhatók.

F4. A hiba oka: a referencia conv2d aláírásában a groups paraméter vagy hiányzik, vagy dekoratív, ellenőrzés nélkül. A függvény ezért a teljes groups=1 úton számol, a hívó viszont grouped súlyt és csatornakiosztást feltételez; a kimenet a csoportok közötti nem kívánt keverést is tartalmazza. A következmény: hibás kísérleti eredmény, amely a tanulás során csak közvetve, például váratlanul nagy kapacitásként vagy rossz általánosításként jelenik meg. Azonnali teszt: depthwise cél, Cin=2C_{in}=2, m=1m=1, kernel 2×22\times2 csupa egyes, bemenet X[0,0]=1X[0,0]=1, X[0,1]=2X[0,1]=2 konstans mezőkön. A helyes depthwise kimenet csatornánként 44 és 88; a hibás teljes konvolúció mindkét kimeneti csatornára 1212-t adna, mert mindkét bemeneti csatornát összegzi. Javítás: a függvényben explicit

if groups != 1:
    raise NotImplementedError("a referencia jelenleg csak groups=1-et tamogat")

ellenőrzés, és grouped teszt esetén a PyTorch Conv2d mint független kontroll használata. A keretmegállapodás szerint a saját NumPy-referenciát nem szabad teljes grouped implementációnak nevezni.

F5. Kérdés: azonos kimeneti csatornaszám mellett a depthwise separable réteg eléri-e a teljes konvolúció validációs pontosságát a GlyphLab orientációfeladaton, miközben kevesebb paramétert használ? Megfigyelési egység: scene_id, mert a két view egy jelenethez tartozik. Split: a mellékelt, jelenetszintű train/val/test felosztás, osztályonként 40/10/1040/10/10 jelenettel. Baseline: ugyanaz a háló egyetlen full Conv2d(1, C, 3) réteggel, majd globális pooling és lineáris fej. Változó tényező: a konvolúciós blokk full vagy depthwise(3×33\times3) + pointwise(1×11\times1) alakú, azonos CC kimeneti csatornaszámmal. Metrika: val accuracy és val loss; modellválasztás kizárólag val loss alapján, legjobb checkpoint. Záróteszt a rögzített testen, párosítva a clean/corrupt összevetéshez; legalább három seed, és a seed-szórás jelenetszintű bootstrap intervallummal, ahogy a 23.3. Páros összehasonlítás és csoportszintű intervallum tárgyalja. Lehetséges kimenetelek: ha a depthwise separable val lossban nem marad el, a korlátozott csatornakapcsolat ennél a feladatnál elegendő; ha elmarad, a teljes csatornakeverés szükséges az orientációhoz. Korlát: a 24×2424\times24-es szintetikus adat nem természetes képi benchmark, így az eredmény nem vihető át más feladatra.

14.4.9 Tipikus tévedés és ellenpélda

A leggyakoribb tévedés az, hogy a groups értéket csupán sebességkapcsolónak tekintik. Ez két irányban hibás. A paraméterszám valóban csökken, de a függvényosztály is szűkül: a fenti depthwise példában a 00 bemeneti csatorna semmilyen kernelérték mellett sem hathat a 33 kimeneti csatornára, mert a mátrix megfelelő blokkja szerkezetileg zérus. Ez nem optimalizálási, hanem reprezentációs korlát.

A második tévedés a saját NumPy-referencia túlértékelése. Ha a conv2d referencia groups=1-re íródott, és valaki groups=2 hívással használja, akkor a függvény vagy hibát vet, vagy ami rosszabb, csendben teljes konvolúciót számol. Az utóbbi nem grouped implementáció, hanem hibás hívás. Az ellenőrzés módja a fenti F4-teszt: olyan input, amelyen a csoportok közötti keverés jelenléte egyetlen skalárban látszik.

14.4.10 Önellenőrzés és visszahívás

Ellenőrző lista: a súly második dimenziója Cin/gC_{in}/g, nem CinC_{in}; a bias CoutC_{out} elemű; a csoportindex az output oldalon ⌊o/rout⌋\lfloor o/r_{out}\rfloor; a kernel második indexe csoporton belüli, ezért c−qrinc-q r_{in} szerepel; a depthwise esetben g=Cing=C_{in} és Cout=mCinC_{out}=mC_{in}. A labor assert ellenőrzi a súlyalakot és a paraméterszámot.

Visszahívás 13.4. Határkezelés és frekvenciaintuíció alfejezetből: a határfeltétel a csatornabontástól független; a valid és zero padding ugyanúgy érvényes minden csoporton belül, mert a group csak a csatornák közötti kapcsolatot korlátozza, a térbeli indexelést nem. 10.4. Tanítási lépés és tanuló MLP alfejezetből: a tanítási lépésben a backward a tényleges kapcsolatok mentén folyik; a zérus mátrixblokk miatt egy bemeneti csatorna gradiense a rétegen keresztül csak a saját csoportjának kimeneteitől származhat. 2.4. Kis tudományos szoftverprojekt alfejezetből: a labor explicit konfigurációt, invariáns-ellenőrzést és hibás inputot is tesztel, nem csupán egy API-hívást mutat be.

14.4.11 Rövid összefoglaló

A groups=g paraméter a be- és kimeneti csatornákat gg diszjunkt csoportra osztja; a qq-edik kimeneti csoport csak a qq-edik bemeneti csoportot látja. A súly alakja Cout×(Cin/g)×kh×kwC_{out}\times(C_{in}/g)\times k_h\times k_w, a paraméterszám Cout(Cin/g)khkw+CoutC_{out}(C_{in}/g)k_hk_w+C_{out}. Csatorna-major lapításban a lineáris operátor mátrixa blokkdiagonális, gg darab routHoutWout×rinHWr_{out}H_{out}W_{out}\times r_{in}HW blokkal; ez bizonyított, bias nélkül mondva ki. A depthwise eset g=Cing=C_{in}, a pointwise 1×11\times1-es réteg térbeli keverés nélkül kever csatornát; kettejük kompozíciója a depthwise separable réteg. A hibás oszthatóság konstrukciós hibát ad, a hiba csendes elnyelése pedig hamis grouped eredményhez vezet.

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

A 15.1. Súly- és biasgradiens egység a konvolúciós backwardban a súly- és biasgradienst vezeti le. A grouped mátrixszerkezet ott gradiensmaszkként jelenik meg: a súlygradiens csak azokra a csatornapárokra nemzérus, amelyek ugyanabba a csoportba tartoznak, a bemeneti gradiens pedig csak a kapcsolt bemeneti csatornákra folyik vissza.