Learning to Represent Data

Naučiť sa reprezentovať údaje

Neurónové siete nám môžu pomôcť izolovať niektoré abstraktné atribúty v údajoch a naučiť sa reprezentácie, ktoré sú vhodné na riešenie problémov.

V príkladoch, ktoré sme doteraz použili, sme sa najčastejšie spoliehali na existenciu nejakého súboru atribútov v súbore údajov. V skutočnosti veľké množstvo domén generuje údaje, ktoré sú v tejto forme, s atribútmi v stĺpcoch a inštanciami v jednotlivých riadkoch. Ako sme videli v úvodnej časti príbehu o príprave údajov, aj keď máme tieto atribúty, nie je najintuitívnejšie rozhodnúť sa, ktoré atribúty zvoliť na vytvorenie modelu. To nás postavilo do pozície, aby sme vyskúšali rôzne kombinácie alebo vymysleli techniky, ktoré nám môžu pomôcť pri výbere atribútov. Vzhľadom na zložitosť funkcií, ktoré modelujú, sa neurónové siete môžu pochváliť schopnosťou naučiť sa filtrovať a zoskupovať atribúty, na ktorých záleží.

Táto vlastnosť neurónových sietí je dôležitá najmä pri práci s netabuľkovými údajmi - mnohokrát sme si položili otázku, ako reprezentovať napríklad obrázky, textové údaje alebo zvukové záznamy. Aj keď tieto formáty poznáme, je pre nás ťažké stručne a použiteľne presne opísať, čo obsahujú. To nás okrem iného motivovalo aplikovať paradigmu programovania založeného na údajoch. Neurónové siete sa môžu (a čoskoro uvidíme) naučiť niektoré abstraktné atribúty z dát v ich zdrojovej podobe, ktoré sú užitočné pre úspešné riešenie problémov.

Nižšie si predstavíme konvolučné neurónové siete, ktoré sa používajú predovšetkým pri práci s obrázkami a videom a na učenie sa vizuálnych atribútov vstupu, a potom rekurentných neurónových sietí a transformátorov, typov neurónových sietí, ktoré sa používajú na učenie sa atribútov sekvenčných údajov, ako je text alebo zvuk.

Konvolučné neurónové siete

Konvolučné neurónové siete sú typom neurónovej siete, ktorá sa primárne používa v oblasti počítačového videnia na prácu s obrázkami a video obsahom.

Čiernobiele obrázky sú znázornené maticami pixelov. Počet typov tejto matice zodpovedá výške obrázka, zatiaľ čo počet stĺpcov tejto matice zodpovedá jeho šírke. Jednotlivé hodnoty pixelov sú čísla v rozsahu od 0 do 255, kde 0 je čierna a 255 biela. Všetky hodnoty medzi nimi predstavujú nejaký odtieň sivej. Uhádnete, čo sa skrýva za obrázkom, ktorý je reprezentovaný maticou pixelov nižšie? Ak ustúpite dostatočne ďaleko a nakreslíte obrysy pozdĺž tmavších odtieňov, možno budete môcť uhádnuť, čo je na obrázku. Pomáha, že v komunite strojového učenia sú obrázky mačiek pomerne bežnou voľbou.

im1

cat

Tak ako je pre nás ľudí ťažké pochopiť, čo je v obraze reprezentovanom skupinou čísel, tak je to aj s konvolučnými neurónovými sieťami. Svoju analýzu obrázka začínajú tak, že najprv rozpoznajú niektoré jednoduché prvky, ako sú vodorovné a zvislé čiary, a potom ich ďalej kombinujú a pridávajú zložitosť, až kým nedospia k zložitým popisom obrázka, ktorý im môže pomôcť vyriešiť danú úlohu. Teraz je prirodzenou otázkou, ako začať s jednoduchými obrysmi a stavať na nich, aby ste získali zložitejšie štruktúry. Odpoveď  poskytne konvolučný operátor .

 Najjednoduchší spôsob, ako zaviesť operátor konvolúcie, je pomocou ilustrácií. Predstavme si, že na vstupe máme maticu 6x6 pixelov, ktorá predstavuje obrázok, a malú maticu, takzvaný filter, s rozmermi 3x3 pixely. Nech sú to matice zobrazené na obrázku nižšie. Začneme aplikovať operátor konvolúcie na obrázok (označíme ho ✷ ) prekrytím časti obrázka v ľavom hornom rohu s filtrom , Potom vynásobte jednotlivé hodnoty a súčet hodnôt zapíšte do novej matice . Táto matica bude výsledkom aplikácie konvolučného operátora.or.

Konvolúcia - krok 1

Budeme pokračovať v aplikácii operátora konvolúcie: filter budeme prekrývať s časťou obrázka umiestnenou v ľavom hornom rohu, ale tak, aby bol teraz posunutý o jeden pixel od ľavého okraja, t.j. v porovnaní s predchádzajúcou pozíciou. Opäť vynásobíme jednotlivé hodnoty, spočítame ich a zapíšeme do výslednej matice.

Konvolúcia - krok 2

Filter je možné posunúť o jednu polohu doprava až k okraju. Potom ho musíme znížiť o jednu polohu nadol a vrátiť späť hneď vedľa okraja. Potom môžeme pokračovať v procese, kým sa nedostaneme do pravého dolného rohu. Výsledkom tejto operácie je matica s rozmermi 4x4 pixely, ktorej hodnoty sú znázornené na obrázku nižšie (určite sa uistite!).

im4

Konvolúcia - výsledok

O koľko sa filter posunie v každej iterácii, je definované hyperparametrom nazývaným rolovanie (stride). V našom prípade mal posun hodnotu 1, pretože sme filter posunuli o jednu pozíciu doprava, teda keď mal byť o jednu pozíciu nižšie. Aby sme mohli pri aplikácii konvolučnej operácie ovplyvniť rozmery výslednej matice (zvyčajne chceme zachovať rozmery, ktoré zodpovedajú vstupnej matici), môžeme okolo počiatočného obrázka pridať rámček. Zvyčajne ide o blok núl alebo jednotiek alebo čísel, ktorých hodnoty zodpovedajú hodnotám najbližšieho pixelu na obrázku. Nazýva sa to rozšírenie (padding) a jeho šírka sú vždy zdôraznené pri aplikácii konvolučnej operácie. Je pre nás obzvlášť dôležité, ak sú vlastnosti, ktoré chceme, aby sa náš model naučil, blízko okraja obrázka.

Animácia nižšie ilustruje celý proces aplikácie filtrov na obrázok, t. j. na vrchu jej matice. Ako vidíte, bol použitý posun veľkosti 1 a rozšírenie veľkosti 0.

im5

Animácia konvolučnej operácie

Ak použijeme filter z predchádzajúceho príkladu pomocou operácie konvolúcie na počiatočný obrázok mačiatka, dostaneme obrázok nižšie. Môžete vidieť, že všetky zvislé čiary, ktoré sa zobrazujú na obrázku, sú zvýraznené.

im6

Vertikálne odsávanie hrán

Tu je vysvetlenie. Pozrite sa na obrázok zľava doprava. Keď sa prvýkrát presuniete zo svetlej časti obrázka do tmavej časti obrázka, v skutočnosti uvidíte zvislý okraj. Poďme teraz použiť filter zľava doprava pomocou konvolučnej operácie. Najvyšší výsledok iterácie konvolúcie bude, keď je pravá strana nášho filtra (stĺpec s číslom -1) umiestnená presne na zvislej hrane. Keďže okraj je tmavý, hodnoty, ktoré zodpovedajú tejto farbe, sú malé, pretože čierna farba je reprezentovaná nulou. Hodnoty naľavo od okraja sú svetlé, takže čísla, ktoré zodpovedajú týmto farbám, sú väčšie (hodnota pre bielu je 255). Keď sa malé hodnoty zodpovedajúce čiernej farbe hrán vynásobia -1, t.j. pravou časťou filtra, a veľké hodnoty, ktoré zodpovedajú svetlým farbám naľavo od okraja, sa vynásobia 0 a 1, t. j. výsledkom je vyššia hodnota, ako keby sa filter našiel kdekoľvek inde, kde filter nie je.

Jediné, čo musíte urobiť, je otočiť filter, ktorý oddeľuje zvislé hrany! Dáva vám to zmysel?

Teraz, keď vieme, ako oddeliť zvislé a vodorovné hrany, môžeme kombinovať rôznymi spôsobmi, aby sme vyčlenili čiary, ktoré nie sú len horizontálne a vertikálne. Ďalšou kombináciou týchto výsledkov môžeme dokonca extrahovať sférické kontúry. To sme mali na mysli, keď sme povedali, že začíname s jasnými, ľahko naučiteľnými charakteristikami a potom krok za krokom staviame na zložitosti charakteristík, ktoré sa môžeme naučiť.

 Vrstvy neurónovej siete charakterizované aplikáciou konvolučného operátora sa nazývajú konvolučné vrstvy (convolutional layers). Zatiaľ čo priekopníci v oblasti počítačového videnia vytvorili filtre ručne, cieľom trénovania konvolučných neurónových sietí je naučiť sa sami hodnoty, ktoré v nich figurujú.

Na obrázku nižšie môžete vidieť reprezentácie naučených filtrov na vrstvách konvolučnej neurónovej siete, ktorá rozpoznáva tváre. Na najnižšej vrstve sú to niektoré horizontálne, zvislé a diagonálne čiary, na druhej vrstve sú to už obrysy, ktoré zodpovedajú častiam tváre, ako je nos, oči a ústa, zatiaľ čo v tretej vrstve sú to filtre, ktoré zodpovedajú kontúram tváre.

Classification process of passing through successive layers of the image

Okrem konvolučnej prevádzky sa konvolučné siete vyznačujú aj  agregačnou prevádzkou (pooling). Ako už názov napovedá, cieľom tejto operácie je agregácia, teda konsolidácia vchodov. Na obrázku nižšie môžete vidieť dva typy agregačných operátorov: ten, ktorý používa maximum, a ten, ktorý používa priemer na agregáciu informácií. Rovnako ako konvolučný operátor, aj tento operátor sa aplikuje na bloky vstupu tak, že si všimne blok a vykoná na ňom potrebný výpočet. Takto získaná hodnota sa zadá do novej matice. Na obrázku sú oba operátory použité na bloky 2x2. Intuitívne povedané, najdominantnejšiu časť zdôrazňujeme maximami, pričom výpočtom priemeru berieme do úvahy príspevok všetkých častí.

Aplikáciou agregačnej operácie získame možnosť zmenšiť rozmer vstupu, ale zároveň zachovať niektoré informácie, ktoré sú obsiahnuté. Na obrázku môžete vidieť, že použitím agregačného operátora sme zredukovali maticu zo 4x4 na 2x2. Prečo potrebujeme zmenšenie rozmerov? V dôsledku toho nám sieť musí dať konkrétnu odpoveď, povedzme, či je na obrázku mačka alebo nie, na čo potrebujeme malý počet neurónov.

Vrstvy neurónovej siete, ktoré sa vyznačujú aplikáciou agregačného operátora, sa nazývajú  agregačné vrstvy (pooling layers). Nie sú v nich žiadne ďalšie parametre, ktoré by sa sieť potrebovala naučiť, ale ako sme videli, pomáhajú nám kontrolovať rozmery matíc, s ktorými pracujeme.

Teraz, keď vieme, aké sú stavebné kamene konvolučnej neurónovej siete, pozrime sa, ako ich môžeme prepojiť a získať funkčný model, ktorý nám môže pomôcť vyriešiť klasifikačnú úlohu. Predstavme si, že potrebujeme vyriešiť úlohu klasifikácie viacerých tried, v ktorej pre každý obrázok kreslenej postavičky musíme určiť, či je to Tweety, Goofy alebo Dacia Duck. Pozrime sa na ilustráciu architektúry hlbokej konvolučnej neurónovej siete, ktorú sme si vybrali na vyriešenie tejto úlohy a diskutujme o tom, aká je motivácia pre jej vznik.

Na začiatku siete je vstupná vrstva, ktorá obsahuje pixely obrázka. Nasleduje konvolučná vrstva (modrý blok). Cieľom tejto vrstvy je použiť operátor konvolúcie na extrakciu prvej sady abstraktných atribútov. Potom umiestnime agregačnú vrstvu (zelený blok), za ktorou nasleduje ďalšia konvolučná vrstva (oranžový blok) a agregačná vrstva (červený blok). V praxi sa konvolučné a agregačné vrstvy kombinujú a často sa nachádzajú vedľa seba, pretože agregačné vrstvy sa ďalej agregujú, t. j. sumarizujú to, čo sa konvolučné vrstvy naučili. Druhá konvolučná vrstva nám umožňuje aplikovať druhý konvolučný operátor na atribúty už extrahované prvou konvolučnou vrstvou a vytvárať zložitejšie atribúty obrazu. Po tomto bloku vrstiev nasleduje vrstva (sivý blok), ktorá má za úlohu "opraviť" maticu (alebo presnejšie tenzor), ktorú sme dovtedy dostali a prebaliť jej hodnoty tak, aby boli všetky vedľa seba v jednom poli. Vrstvy na tento účel sa nazývajú vyrovnávacie vrstvy (flattening layers). Po korekcii môžeme ďalej stavať na plne prepojenej neurónovej sieti. Táto sieť bude mať teraz abstraktné atribúty ako vstupy, ktoré sa pre ňu učí kombináciou konvolučných vrstiev a agregačných vrstiev. Okrem opravenej vstupnej vrstvy vidíme v obrázku aj skrytú vrstvu, ako aj výstupnú vrstvu, v ktorej sú presne tri neuróny - jeden pre každú z kreslených postavičiek. Výstupné hodnoty týchto neurónov zodpovedajú pravdepodobnosti, že vstupný obraz patrí do triedy, ktorú reprezentujú. Pri obrázku Twitteru, ktorý máme na vstupe, si môžeme všimnúť, že výstupná hodnota tretieho neurónu, ktorá presne zodpovedá tejto triede, je najväčšia a je 0,7.

 Teraz môžeme vidieť aj to, ako vyzerá architektúra  siete VGGNet, populárnej konvolučnej siete, ktorá sa aktívne využíva v praxi.

VGGNet je hlboká konvolučná neurónová sieť vyvinutá oxfordským tímom Visual Geometry Group (odtiaľ názov VGGNet ). Na prestížnej súťaži Large Scale Visual Recognition Challenge , ktorá sa konala v roku 2014, sa táto sieť ukázala ako najlepšia pri riešení problému lokalizácie objektov v obraze a ako druhá v rade v probléme klasifikácie objektov z obrázka. Viac ako 1,2 milióna obrázkov bolo použitých na klasifikačnú úlohu množiny ImageNet, ktorú sme poznali, a klasifikáciu do možných 1000 tried. Trénovanie tejto siete trvalo 15 až 20 dní pomocou 4 grafických kariet (najlepšie v tom čase) NVIDIA Titan Black . Pred ňou bola v týchto úlohách najlepšia sieť AlexNet , ktorá je pozoruhodná tým, že zavádza prax používania grafických kariet na trénovanie neurónových sietí a umožňuje ďalší rozvoj hlbokého učenia.

 Architektúra  siete VGG-16, verzia siete so 16 vrstvami, je znázornená na obrázku nižšie. Ako vidíme, na vstupe sa očakáva farebný obraz s rozmermi 244x244 pixelov a sieť kombinuje konvolučné vrstvy a agregačné vrstvy (s maximom) a končí plne prepojenou neurónovou sieťou s 1000 neurónmi na výstupe, kde každý neurón zodpovedá jednej konkrétnej triede množiny ImageNet. Samotná sieť má 138 miliónov parametrov a na ich uloženie je potrebných približne 500 MB pamäte.

Sieťový displej VGG-16

Zvýšenie počtu vrstiev konvolučnej časti siete zvyčajne prináša lepšie výsledky v praxi. Počet vrstiev sa však nemôže zvyšovať donekonečna. Nielen kvôli obmedzeniam zdrojov, času a nákladov, ale aj kvôli matematickým vlastnostiam hlbokých neurónových sietí, ktoré ďalej sťažujú aplikáciu algoritmu spätného šírenia a trénovanie samotnej siete.

Ak vás tento matematický problém zaujíma, môžete si skúsiť prečítať viac o miznúcich a explodujúcich gradientoch, najmä v časti konvolučných sietí a zvyškových spojení.

Predtým, ako sa pustíme do práce s konvolučnými neurónovými sieťami, pozrime sa na problematiku práce s farebnými obrázkami. Doteraz sme ich nespomenuli.

 Keď potrebujeme prezentovať farebný obrázok, ktorý používa farebný formát RGB a zobrazuje všetky farby ako kombinácie červenej, zelenej a modrej, použijeme tri matice. Pre každú z farieb je k dispozícii jedna matica. Počet matíc, ktoré používame na zobrazenie obrázkov, sa nazýva kanály . Čiernobiele obrázky majú teda iba jeden kanál, zatiaľ čo farebné obrázky majú tri kanály.

Zobrazenie obrázkov, ktoré používajú farebný formát RGB

Prítomnosť farieb ovplyvňuje výkon konvolučnej operácie prispôsobením počtu kanálov filtra počtu kanálov obrázka, na ktorý ho aplikujeme. Ďalej musíte spárovať každý z filtračných kanálov s obrazovým kanálom (červený s červeným, modrý s modrým a zelený so zeleným) a vykonať konvolučnú operáciu, ako keby ste pracovali s jedným kanálom. Potom musíme pridať matice, ktoré takto získame, a výslednú maticu deklarovať ako konečný výsledok. Na obrázku nižšie môžeme vidieť dva filtre v konvolučnej vrstve, ktoré sú aplikované na farebný vstupný obrázok. V dôsledku použitia každého z týchto filtrov získame samostatné matice, ktoré po "zlúčení" predstavujú konečný výsledok konvolučnej vrstvy. V praxi je zvyčajne umiestnených viacero filtrov na úrovni jednej konvolučnej vrstvy, takže ako výsledky sa získajú tenzory. Konvolučné operácie sa potom aplikujú na tieto tenzory rovnakým spôsobom - dbá sa len na to, aby počet filtračných kanálov zodpovedal rozmeru tenzora (povedzme, že pre ďalšiu aplikáciu v príklade, ktorý sme uvažovali, by to bolo číslo 2) a aby bol zodpovedajúci vstupný kanál spárovaný s príslušným filtračným kanálom.

Použitie konvolučného operátora na viackanálové vstupy

Pokiaľ ide o operáciu agregácie, tá sa aplikuje na každý kanál vstupného obrazu. NapríkladampAk má vstupný obraz 3 kanály, operácia agregácie sa použije na každý kanál samostatne. To tiež znamená, že operácia agregácie zachováva počet kanálov v čase nasadenia. Na obrázku nižšie môžete vidieť ilustráciu tohto procesu.

Použitie agregačných operátorov na viackanálové vstupy

Táto sekcia je spárovaná s Jupyter Notebook 09-VGG-16_network_and_classification.ipynb. Ak chcete obsah sledovať ďalej, kliknite na odkaz a potom kliknutím  na tlačidlo otvorte obsah v Google Colab . Ak si poznámkové bloky prezeráte v lokálnom počítači, vyhľadajte poznámkový blok s rovnakým názvom v obsahu a spustite ho. Podrobnejšie pokyny nájdete v  časti Hands-on Zone a lekcii Jupyter Notebooks na precvičenie .

Teraz si vyskúšajme, ako konvolučná sieť VGG-16 skutočne funguje! Pri čítaní lekcie nezabudnite sledovať poznámkový blok s kódom.

 Po natrénovaní je možné model neurónovej siete zdieľať s komunitou rozdelením parametrov, ktoré v ňom figurujú. V tomto príklade použijeme model, ktorý je k dispozícii v knižnici Keras . Knižnica Keras je knižnica s otvoreným zdrojovým kódom široko používaná v komunite strojového učenia. Aby sme mohli využiť výhody sieťového modelu VGG-16 , musíme vykonať nasledujúce dva príkazy:

from tensorflow.keras.applications import VGG16

model = VGG16(weights = 'imagenet')

Informácie o modeli, ktorý sme načítali, si môžeme prečítať pomocou funkcie model.summary(). Jeho výsledkom je popis sieťových vrstiev, za ktorým nasledujú informácie o vstupných veľkostiach, ktoré tieto vrstvy očakávajú. Teraz môžete vykonať príkaz:

model.summary()

Nenechajte sa zmiasť, ak nerozumiete všetkým podrobnostiam, ktoré sa zobrazia po vykonaní tohto príkazu. Je dôležité vedieť, že vstup sa očakáva ako obrázok s rozmermi 224 x 224 pixelov vo farbe (preto je vedľa vstupnej vrstvy uvedené 224, 224, 3) a že na výstupe máte jednu z 1000 tried. Môžete tiež porovnať tlač s obrázkom VGG-16, o ktorom sme hovorili, aby ste odhalili viac informácií.

 Je dôležité zdôrazniť, že  sieť VGG-16 nebudeme trénovať - použijeme iba natrénovaný model. Preto nesmieme počas prevádzky meniť parametre modelu - každý má svoj vlastný príspevok. Celkový počet parametrov modelu, ktoré môžeme prečítať v súhrne siete, je niečo vyše 138 miliónov.

Ide o to, že obrázok, na ktorom budeme model testovať, bude ľubovoľný obrázok z webu. Na tento účel použijeme množstvo štandardných knižníc Pythonu. Ak chcete predvolene nastaviť funkciu URL, ucitaj_sliku nám pomôže presunúť požadovaný obrázok.

def  ucitaj_sliku (url_putanja):

response = request.urlopen(url_putanja).read()

return Image.open(BytesIO(reply))

Na testovanie sme vybrali obrázok zlatého retrievera z adresy https://unsplash.com/photos/x5oPmHmY3kQ  , ktorý je možné voľne používať. Môžete si vybrať požadovaný obrázok! Je dôležité mať na pamäti, že model musí poznať triedu objektu na obrázku. Keďže model VGG-16 bol trénovaný na viac ako 1,2 milióna obrázkov, pozná veľa tried, až 1000 rôznych. Zlatý retriever je jedným z nich. Ak dáme modelu obrázok s objektom, ktorý nepozná, poskytne nám predpovede tried, ktorých obrazy sa najviac podobajú našim. Nakoniec uvidíme, ktoré triedy sa podobajú zlatému retrieverovi.

im16

Hrdina príbehu modelu VGG-16

Pretože obrázok, ktorý je potrebné preposlať modelu, musí byť špeciálne pripravený, urobíme nasledovné:

nastavte jeho rozmery na 224x224 a povedzte mu, aby používal tri farebné kanály RGB:

test_slika = test_slika.resize((224, 224))

test_slika = test_slika.convert('RGB')

Transformujte obrázok do vhodného formátu matice:

matica _oblik _test_slike = image.img_to_array(test_slika)

Vytvorte balenie, ktoré obsahuje náš obrázok:

paket = np.expand_dims(matricni_oblik_test_slike, os = 0)

Vykonajte numerické predbežné spracovanie obrázkov vo forme normalizácie:

testovací _skup _slika = preprocess_input(paket)

Iba tak môžeme odovzdať model klasifikácie. Funkcia, ktorá nám pomôže, sa (očakáva) nazýva predpoveda.

predpovede _modela = model.predict(test_skup_slika)

Premenná predikcije_modela, v ktorej ukladáme predpovede modelu, je pole s dĺžkou 1000 a obsahuje pravdepodobnosti príslušnosti ku každej z 1000 tried, ktoré model rozpoznáva. Na extrakciu triedy, do ktorej patrí náš obrázok, môžeme použiť funkciu decode_predictions, ktorá vráti pravdepodobnosti a názvy pre 5 najpravdepodobnejších tried. Získame tak prehľad o tom, aký bezpečný je model pri klasifikácii. Po vykonaní ďalšieho príkazu získame informácie o najpravdepodobnejších triedach.

najverovatnije_klase = decode_predictions(predikcije_modela)[0]

Keď tieto predpovede graficky znázorníme pomocou nižšie uvedeného kódu, dostaneme graf s pruhmi, ktorý nám umožní ľahšie analyzovať výsledky.

ime_klase = [utorok[1] pre utorok a najverovatnije_klase]

Pravdepodobnosť _pripadnosti = [utorok[2] pre utorok a najverovatnije_klase]

plt .figure(figsize=(10, 4))

plt .bar (názov _klase , verovatnoca_pripadnosti, farba =['modrozelená', 'žltá', 'zelená', 'modrá', 'oranžová'])

plt .title ("Päť najpravdepodobnejších tried")

plt .ylabel ("Pravdepodobnosť pridruženia")

plt.show()

Ako vidíme, model s veľkou istotou predpovedal (pravdepodobnosť je 0,804), že obrázok, ktorý sme vybrali, je obrázok zlatého retrievera. Niektoré z ďalších tried, ktoré model vzal do úvahy, sú niektoré iné typy retrieverov. Napodiv, v zozname výsledkov sa objavila aj tenisová loptička. Pravdepodobne preto, že v tréningovej súprave sú aj obrázky, na ktorých retrievery behajú za tenisovými loptičkami. Toto správanie modelu by sa malo v praxi ďalej skúmať.

Last modified: Wednesday, 11 June 2025, 5:05 AM