Polkadot árelemzés 13. szept

Konvolúciós neurális hálózat – PyTorch megvalósítás a CIFAR-10 adatkészleten

Forrás csomópont: 1866263

Ez a cikk részeként jelent meg Adattudományi Blogaton

Bevezetés

Cifar 10 | Konvolúciós neurális hálózatok pytorch
                                    Kép 1

A konvolúciós neurális hálózatokat, más néven ConvNeteket, az 1980-as években Yann LeCun, a háttérben dolgozó számítástechnikai kutató vezette be először. A LeCun Kunihiko Fukushima, egy japán tudós munkájára épített, a képfelismerés alaphálózatára.

A CNN régi verziója, a LeNet (LeCun után), láthatja a kézzel írt számjegyeket. A CNN segít megtalálni a postai PIN-kódokat. Szakértelmük ellenére azonban a ConvNets közel maradt a számítógépes látáshoz és a mesterséges intelligenciához, mert egy nagy problémával kellett szembenézniük: nem tudtak sokat skálázni. A CNN-ek sok adatot és erőforrásokat igényelnek ahhoz, hogy jól működjenek a nagy képekhez.

Akkoriban ez a módszer csak kis felbontású képekre volt alkalmazható. A Pytorch egy olyan könyvtár, amely képes mély tanulási műveletekre. Ezt használhatjuk konvolúciós neurális hálózatok végrehajtására. A konvolúciós neurális hálózatok mesterséges neuronok sok rétegét tartalmazzák. A szintetikus neuronok, a biológiai megfelelők komplex szimulációi, matematikai függvények, amelyek kiszámítják a többszörös bemenet súlyozott tömegét és a termékérték aktiválását.

Konvolúciós neurális hálózatok pytorch
Kép 2

A fenti képen egy CNN-modell látható, amely a 2-es számjegyszerű képét veszi fel, és számként adja meg a képen szereplő számjegy eredményét. Ebben a cikkben részletesen megvitatjuk, hogyan kapjuk ezt meg.

A CIFAR-10 egy adatkészlet, amely 10 különböző osztály képeinek gyűjteményét tartalmazza. Ezt az adatkészletet széles körben használják kutatási célokra különböző gépi tanulási modellek tesztelésére, és különösen számítógépes látási problémákra. Ebben a cikkben megpróbálunk felépíteni egy neurális hálózati modellt Pytorch segítségével, és tesztelni a CIFAR-10 adatkészleten, hogy ellenőrizzük, milyen pontosságú előrejelzés érhető el.

A PyTorch Library importálása 

import numpy as np import panda as pd
import torch import torch.nn.functional as F from torchvision import datasets,transforms from torch import nn import matplotlib.pyplot as plt import numpy as np import seaborn as sns #from tqdm.notebook import tqdm from tqdm import tqdm

Ebben a lépésben importáljuk a szükséges könyvtárakat. Láthatjuk, hogy a NumPy-t használjuk a numerikus műveletekhez, a pandákat pedig az adatkeret-műveletekhez. A torch könyvtár a Pytorch importálására szolgál.

A Pytorch rendelkezik egy nn komponenssel, amelyet a gépi tanulási műveletek és funkciók absztrakciójára használnak. Ez F-ként van importálva. A torchvision könyvtárat arra használjuk, hogy importálhassuk a CIFAR-10 adatkészletet. Ez a könyvtár számos képadatkészlettel rendelkezik, és széles körben használják kutatásra. Az átalakítások importálhatók, így a képet minden képre azonos méretűre tudjuk méretezni. A tqdm-et arra használjuk, hogy az edzés során nyomon tudjuk követni az előrehaladást, és vizualizációra használják.

Olvassa el a szükséges adatkészletet

trainData = pd.read_csv('cifar-10/trainLabels.csv') trainData.head()

Miután elolvastuk az adatkészletet, különféle címkéket láthatunk, mint például a béka, teherautó, szarvas, autó stb.

Az adatok elemzése PyTorch segítségével

print("Pontok száma:",trainData.shape[0]) print("Jellemzők száma:",trainData.shape[1]) print("Features:",trainData.columns.values) print("Number of Egyedi értékek") a col-hoz a trainData-ban: print(col,":",len(trainData[col].unique())) plt.figure(figsize=(12,8))

output:

Pontok száma: 50000 Jellemzők száma: 2 Jellemzők: ['id' 'label'] Egyedi értékek száma id : 50000 címke: 10

Ebben a lépésben elemezzük az adatkészletet, és azt látjuk, hogy vonatadataink körülbelül 50000 10 sorból állnak az azonosítójukkal és a kapcsolódó címkével. Összesen 10 osztály van, mint a CIFAR-XNUMX névben.

Az érvényesítési készlet lekérése PyTorch segítségével

from torch.utils.data import random_split val_size = 5000 train_size = len(adatkészlet) - val_size train_ds, val_ds = random_split(dataset, [train_size, val_size]) len(train_ds), len(val_ds)

Ez a lépés megegyezik a betanítási lépéssel, de az adatokat betanítási és érvényesítési készletekre szeretnénk felosztani.

(45000, 5000)
from torch.utils.data.dataloader import DataLoader batch_size=64 train_dl = DataLoader(train_ds, batch_size, shuffle=True, num_workers=4, pin_memory=True) val_dl = DataLoader(val_ds, num_workersmize=4, pin_workersmize)

A torch.utils rendelkezik egy adatbetöltővel, amely segíthet a szükséges adatok betöltésében, megkerülve a különféle paramétereket, például a dolgozók számát vagy a kötegméretet.

A szükséges funkciók meghatározása

@torch.no_grad() def pontosság(kimenetek, címkék): _, preds = torch.max(outputs, dim=1) return torch.tensor(torch.sum(preds == labels).item() / len(preds) )) class ImageClassificationBase(nn.Module): def training_step(self, batch): images, labels = batch out = self(images) # Előrejelzések generálása loss = F.cross_entropy(out, labels) # Veszteség számítása accu = pontosság(out ,labels) return loss,accu def validation_step(self, batch): images, labels = batch out = self(images) # Előrejelzések generálása loss = F.cross_entropy(out, labels) # Veszteség számítása acc = pontosság(ki, címkék) # Pontossági visszatérés kiszámítása {'Loss': loss.detach(), 'Pontosság': acc} def validation_epoch_end(self, outputs): batch_losses = [x['Loss'] x-hez a kimenetekben] epoch_loss = torch.stack(batch_losses) ).mean() # Veszteségek kombinálása batch_accs = [x['Pontosság'] x-hez a kimenetekben] epoch_acc = torch.stack(batch_accs).mean() # Pontosságok kombinálása return {'Veszteség': epoch_loss.item(), ' Pontosság': epoch_acc.item()} def epoch_end(self, epoch, result): print("Epoch :",epoch + 1) print(f'Train Accuracy:{result["train_accuracy"]*100:.2f} % Ellenőrzési pontosság:{eredmény["Pontosság"]*100:.2f}%') print(f'Vonatvesztés:{eredmény["vonatvesztés"]:.4f} Ellenőrzési veszteség:{eredmény["Veszteség"]:. 4f}')

Amint itt láthatjuk, az ImageClassification osztálymegvalósítását használtuk, és ehhez egy paraméterre van szükség, ami az nn.Module. Ezen az osztályon belül különféle funkciókat, vagy különféle lépéseket, például képzést, érvényesítést stb. valósíthatunk meg. A függvények itt egyszerű python implementációk.

A képzési lépésben a képeket és a címkéket kötegekben készítik el. keresztentrópiát használunk a veszteségfüggvényhez, és kiszámítjuk a veszteséget és visszaadjuk a veszteséget. Ez hasonló az érvényesítési lépéshez, amint azt a függvényben láthatjuk. A korszak végei egyesítik a veszteségeket és a pontosságokat, végül kinyomtatjuk a pontosságokat és veszteségeket.

Konvolúciós neurális hálózati modul megvalósítása

class Cifar10CnnModel(ImageClassificationBase): def __init__(self): super().__init__() self.network = nn.Sequential( nn.Conv2d(3, 32, kernel_size=3, padding=1), nn.ReLU(), nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1), nn.ReLU(), nn.MaxPool2d(2, 2), # kimenet: 64 x 16 x 16 nn.BatchNorm2d(64) , nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1), nn.ReLU(), nn.Conv2d(128, 128, kernel_size=3, stride=1, padding=1), nn .ReLU(), nn.MaxPool2d(2, 2), # kimenet: 128 x 8 x 8 nn.BatchNorm2d(128), nn.Conv2d(128, 256, kernel_size=3, stride=1, padding=1), nn.ReLU(), nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1), nn.ReLU(), nn.MaxPool2d(2, 2), # kimenet: 256 x 4 x 4 nn.BatchNorm2d(256), nn.Flatten(), nn.Linear(256*4*4, 1024), nn.ReLU(), nn.Linear(1024, 512), nn.ReLU(), nn.Lineáris (512, 10)) def forward(self, xb): return self.network(xb)

Ez a neurális hálózat megvalósításának legfontosabb része. Mindvégig a fáklyából importált nn modult használjuk. Amint az első sorban láthatjuk, a Conv2d egy olyan modul, amely segít egy konvolúciós neurális hálózat megvalósításában. Az első 3-as paraméter itt azt jelenti, hogy a kép színes és RGB formátumú. Ha szürkeárnyalatos kép lenne, akkor az 1-et választottuk volna.

A 32 a kezdeti kimeneti csatorna mérete, és amikor a következő conv2d rétegre megyünk, ez a 32 lesz a bemeneti csatorna és a 64 a kimeneti csatorna.

Az első sorban lévő 3. paramétert kernelméretnek nevezzük, és ez segít nekünk gondoskodni a használt szűrőkről. A kitöltési művelet az utolsó paraméter.

A konvolúciós művelet egy aktiválási réteghez kapcsolódik, és itt a Relu. Két Conv2d réteg után 2 * 2 méretű max-pooling műveletünk van. Az ebből kilépő érték a stabilitás és a belső kovariáns eltolódás elkerülése érdekében kötegelt normalizált. Ezeket a műveleteket több réteggel megismétlik a hálózat elmélyítése és a méret csökkentése érdekében. Végül lesimítjuk a réteget, hogy egy lineáris réteget építhessünk az értékek 10 értékre való leképezésére. A 10 neuron közül mindegyik neuron valószínűsége határozza meg, hogy egy adott kép melyik osztályba tartozik a maximális valószínűség alapján.

Tanítsd meg a modellt

@torch.no_grad() def assessment(modell, data_loader): model.eval() outputs = [modell.validation_step(batch) for batch in data_loader] return model.validation_epoch_end(outputs) def fit(modell, train_loader, val_loader,epochs) =10,learning_rate=0.001): best_valid = Nincs előzmények = [] optimalizáló = torch.optim.Adam(modell.parameters(), learning_rate,weight_decay=0.0005) a korszakhoz a következő tartományban(korszakok): # Képzési fázis model.train( ) train_losses = [] train_accuracy = [] köteghez in tqdm(train_loader): loss,accu = model.training_step(batch) train_losses.append(loss) train_accuracy.append(accu) loss.backward() optimizer.step() optimalizáló .zero_grad() # Validation phase result = kiértékel(modell, val_loader) result['train_loss'] = torch.stack(train_losses).mean().item() result['train_accuracy'] = torch.stack(train_accuracy). mean().item() model.epoch_end(epoch, result) if(best_valid == None vagy best_valid
előzmények = fit(modell, train_dl, val_dl)

Ez egy alapvető lépés a modellünk betanításához, hogy elérjük a kívánt eredményt. az itt található illesztési függvény illeszkedik a vonat és a Val adatokhoz az általunk létrehozott modellhez. Az illesztési függvény kezdetben egy listát vesz fel, amelyet történelemnek hívnak, és amely gondoskodik minden korszak iterációs adatairól. Futtatunk egy for ciklust, hogy minden korszakon keresztül iterálhassunk. Minden kötegnél gondoskodunk arról, hogy a tqdm segítségével mutassuk meg az előrehaladást. Nevezzük a korábban végrehajtott képzési lépést, és kiszámítjuk a pontosságot és a veszteséget. A visszafelé terjedés és az optimalizáló futtatása, amelyet korábban definiáltunk. Miután ezt megtettük, nyomon követjük a listánkat, és a funkciók segítenek kinyomtatni a részleteket és az előrehaladást.

Az értékelő függvény viszont az eval függvényt használja, és minden lépéshez vesszük az adatbetöltőből betöltött köteget, és kiszámoljuk a kimenetet. Az érték ezután átkerül a korábban meghatározott érvényesítési korszak végére, és a megfelelő érték kerül visszaadásra.

Az eredmények ábrázolása

Ebben a lépésben vizualizáljuk a pontosságot az egyes korszakok függvényében. Megfigyelhető, hogy a korszak növekedésével a rendszer pontossága folyamatosan nő és a veszteség is folyamatosan csökken. A piros vonal az edzési adatok előrehaladását jelzi, a kék pedig az érvényesítést. Láthatjuk, hogy az eredményeinkben jókora túlillesztés történt, mivel a képzési adatok jóval jobban teljesítenek, mint a validálási eredmény, és hasonlóképpen veszteség esetén is. 10 epocha után a vonatadatok megkerülik a 90%-os pontosságot, de a veszteség körülbelül 0.5. A tesztadatok 81% körüliek, a veszteségek pedig közel 0.2.

def plot_accuracies(history): Validation_accuracies = [x['Accuracy'] for x in history] Training_Accuracies = [x['train_accuracy'] for x in History] plt.plot(Training_accuracies, '-rx') plt.plot(Validation_accura , '-bx') plt.xlabel('korszak') plt.ylabel('pontosság') plt.legend(['Képzés', 'Érvényesítés']) plt.title('Pontosság vs. korszakok száma') ; plot_accuracies(előzmények)
Pontossági diagramok
def plot_losses(history): train_losses = [x.get('train_loss') for x in history] val_losses = [x['Loss'] for x in History] plt.plot(train_losses, '-bx') plt.plot (val_losses, '-rx') plt.xlabel('korszak') plt.ylabel('veszteség') plt.legend(['Képzés', 'Érvényesítés']) plt.title('Veszteség vs. korszakok száma '); plot_losses(előzmények)

test_dataset = ImageFolder(data_dir+'/test', transform=ToTensor()) test_loader = DeviceDataLoader(DataLoader(test_dataset, batch_size), device) result = értékel(végleges_modell, teszt_betöltő) print(f'Teszt pontossága:{eredmény"["A ]*100:.2f}%')
Teszt pontossága: 81.07%

Láthatjuk, hogy végül 81.07%-os pontossággal értünk el.

Következtetés:

Kép:https://unsplash.com/photos/5L0R8ZqPZHk

Magamról: Kutatóhallgató vagyok, akit érdekel a mélytanulás és a természetes nyelvfeldolgozás, és jelenleg a mesterséges intelligencia szakon szerezek diplomát.

Képforrás

  1. Image 1: https://becominghuman.ai/cifar-10-image-classification-fd2ace47c5e8
  2. 2. kép: https://www.analyticsvidhya.com/blog/2021/05/convolutional-neural-networks-cnn/

Bátran lépj kapcsolatba velem:

  1.  Linkedin: https://www.linkedin.com/in/siddharth-m-426a9614a/
  2.  Github: https://github.com/Siddharth1698

Az ebben a cikkben bemutatott médiák nem az Analytics Vidhya tulajdonát képezik, és a Szerző belátása szerint használják azokat.

Forrás: https://www.analyticsvidhya.com/blog/2021/09/convolutional-neural-network-pytorch-implementation-on-cifar10-dataset/

Időbélyeg:

Még több Analytics Vidhya