Analiza cen Polkadot 13. sep

Konvolucijska nevronska mreža – implementacija PyTorcha na naboru podatkov CIFAR-10

Izvorno vozlišče: 1866263

Ta članek je bil objavljen kot del Blogathon o znanosti o podatkih

Predstavitev

Cifar 10 | Konvolucijske nevronske mreže pytorch
                                    Image 1

Konvolucijske nevronske mreže, imenovane tudi ConvNets, je v osemdesetih letih prvič predstavil Yann LeCun, raziskovalec računalništva, ki je delal v ozadju. LeCun je gradil na podlagi dela japonskega znanstvenika Kunihika Fukushime, osnovnega omrežja za prepoznavanje slik.

V stari različici CNN, imenovani LeNet (po LeCun), so prikazane ročno napisane številke. CNN pomaga pri iskanju pin kod iz pošte. Kljub svojemu strokovnemu znanju pa je ConvNets ostal blizu računalniškega vida in umetne inteligence, ker so se soočili z veliko težavo: niso mogli veliko povečati obsega. CNN -ji potrebujejo veliko podatkov in integrirajo vire za dobro delo pri velikih slikah.

Takrat je bila ta metoda uporabna samo za slike z nizko ločljivostjo. Pytorch je knjižnica, ki lahko izvaja operacije globokega učenja. To lahko uporabimo za izvajanje konvolucijskih nevronskih omrežij. Konvolucijske nevronske mreže vsebujejo veliko plasti umetnih nevronov. Sintetični nevroni, kompleksne simulacije bioloških primerkov, so matematične funkcije, ki izračunajo tehtano maso več vhodov in aktiviranje vrednosti izdelka.

Konvolucijske nevronske mreže pytorch
Image 2

Zgornja slika prikazuje model CNN, ki vzame številsko sliko 2 in nam daje rezultat, kakšna številka je bila na sliki prikazana kot številka. Kako do tega pridemo, bomo podrobno razpravljali v tem članku.

CIFAR-10 je nabor podatkov, ki ima zbirko slik 10 različnih razredov. Ta niz podatkov se pogosto uporablja v raziskovalne namene za preizkušanje različnih modelov strojnega učenja in zlasti pri težavah z računalniškim vidom. V tem članku bomo s pomočjo Pytorcha poskušali zgraditi model nevronskega omrežja in ga preizkusiti na naboru podatkov CIFAR-10, da preverimo, kakšno natančnost napovedi je mogoče doseči.

Uvažanje knjižnice PyTorch 

uvoz numpy kot np uvoz pand kot pd
uvoziti svetilko uvoziti svetilko.nn.funkcionalno kot F iz uvoznih nizov podatkov torchvision, preoblikovati iz svetilke uvoziti nn uvoz matplotlib.pyplot kot plt uvoz numpy kot np uvoz morsko kot sns #iz tqdm.notebook uvoz tqdm iz tqdm uvoz tqdm

V tem koraku uvozimo potrebne knjižnice. Vidimo, da za numerične operacije uporabljamo NumPy, za operacije okvirjev podatkov pande. Knjižnica gorilnika se uporablja za uvoz Pytorcha.

Pytorch ima komponento nn, ki se uporablja za odvzem operacij in funkcij strojnega učenja. To je uvoženo kot F. Knjižnica torchvision se uporablja za uvoz podatkovnega nabora CIFAR-10. Ta knjižnica ima veliko slikovnih podatkovnih nizov in se pogosto uporablja za raziskave. Pretvorbe lahko uvozimo, tako da lahko za vse slike spremenimo velikost slike na enako velikost. Tqdm se uporablja za spremljanje napredka med usposabljanjem in se uporablja za vizualizacijo.

Preberite zahtevani nabor podatkov

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

Ko preberemo nabor podatkov, lahko vidimo različne oznake, kot so žaba, tovornjak, jelen, avtomobil itd.

Analiza podatkov s PyTorch

print ("Število točk:", trainData.shape [0]) print ("Število funkcij:", trainData.shape [1]) print ("Lastnosti:", trainData.columns.values) print ("Število Edinstvene vrednosti ") za col v trainData: print (col,": ", len (trainData [col] .unique ())) plt.figure (figsize = (12,8))

izhod:

Število točk: 50000 Število funkcij: 2 Značilnosti: ['id' 'label'] Število edinstvenih vrednosti id: 50000 oznaka: 10

V tem koraku analiziramo nabor podatkov in vidimo, da imajo naši podatki o vlaku okoli 50000 vrstic z njihovim ID -jem in z njimi povezano oznako. V imenu CIFAR-10 je skupaj 10 razredov.

Pridobivanje potrditvenega niza s pomočjo PyTorcha

from torch.utils.data import random_split val_size = 5000 train_size = len (niz podatkov) - val_size train_ds, val_ds = random_split (nabor podatkov, [vlak_size, val_size]) len (vlak_ds), len (val_ds)

Ta korak je enak koraku usposabljanja, vendar želimo razdeliti podatke v sklope usposabljanja in preverjanja.

(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, batch_size = num_workers)

Torch.utils ima nalagalnik podatkov, ki nam lahko pomaga naložiti zahtevane podatke, mimo različnih parametrov, kot sta številka delavca ali velikost serije.

Določitev zahtevanih funkcij

@torch.no_grad () def natančnost (izhodi, oznake): _, preds = torch.max (izhodi, dim = 1) vrni gorilnik.tensor (gorilnik.sum (preds == oznake) .item () / len (preds )) class ImageClassificationBase (nn.Module): def training_step (self, batch): images, labels = batch out = self (images) # Ustvari izgube napovedi = F.cross_entropy (out, labels) # Izračunaj izgubo accu = natančnost (out , nalepke) vrnitev izgube, accu def validation_step (samostojno, paketno): slike, nalepke = paketno = lastno (slike) # Ustvari izgubo napovedi = F.cross_entropy (ven, oznake) # Izračunajte izgubo acc = natančnost (ven, oznake) # Izračunaj vrnitev natančnosti {'Izguba': loss.detach (), 'Natančnost': acc} def validation_epoch_end (self, outputs): batch_losses = [x ['Loss'] za x v izhodih] epoch_loss = torch.stack (batch_losses . Natančnost ': epoch_acc.item ()} def epoch_end (self, epoch, result): pr int ("Epoha:", epoha + 1) print (f'Tračnost vlaka: {result ["train_accuracy"]*100: .2f}% Natančnost preverjanja: {result ["Natančnost"]*100: .2f}% ' ) print (f'Train Loss: {result ["train_loss"] :. 4f} Izguba pri preverjanju: {result ["Loss"] :. 4f} ')

Kot lahko vidimo tukaj, smo uporabili razredno izvedbo ImageClassification in potrebuje en parameter, ki je nn.Module. V tem razredu lahko izvajamo različne funkcije ali različne korake, kot so usposabljanje, preverjanje itd. Tu so preproste implementacije pythona.

Korak usposabljanja posname slike in oznake v serijah. uporabljamo navzkrižno entropijo za funkcijo izgube in izračunamo izgubo ter izgub vrnemo. To je podobno koraku preverjanja, kot ga lahko vidimo v funkciji. Konec epohe združuje izgube in natančnosti in na koncu natisnemo točnosti in izgube.

Izvedba konvolucijskega modula nevronskega omrežja

razred 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, velikost jedra = 3, korak = 1, oblazinjenje = 1), nn.ReLU (), nn.MaxPool2d (2, 2), # izhod: 64 x 16 x 16 nn.BatchNorm2d (64) , nn.Conv2d (64, 128, velikost jedra = 3, korak = 1, padding = 1), nn.ReLU (), nn.Conv2d (128, 128, velikost jedra = 3, korak = 1, oblazinjenje = 1), nn .ReLU (), nn.MaxPool2d (2, 2), # izhod: 128 x 8 x 8 nn.BatchNorm2d (128), nn.Conv2d (128, 256, velikost jedra = 3, korak = 1, oblazinjenje = 1), nn.ReLU (), nn.Conv2d (256, 256, kernel_size = 3, korak = 1, padding = 1), nn.ReLU (), nn.MaxPool2d (2, 2), # izhod: 256 x 4 x 4 nn.BatchNorm2d (256), nn.Flatten (), nn.Linearno (256*4*4, 1024), nn.ReLU (), nn.Linearno (1024, 512), nn.ReLU (), nn.Linearno (512, 10)) def forward (self, xb): return self.network (xb)

To je najpomembnejši del implementacije nevronskih omrežij. Vseskozi uporabljamo modul nn, ki smo ga uvozili iz svetilke. Kot lahko vidimo v prvi vrstici, je Conv2d modul, ki pomaga pri implementaciji konvolucijskega nevronskega omrežja. Prvi parameter 3 tukaj pomeni, da je slika obarvana in v formatu RGB. Če bi bila slika v sivinah, bi se odločili za 1.

32 je velikost začetnega izhodnega kanala in ko gremo za naslednjo plast conv2d, bi imeli to 32 kot vhodni kanal in 64 kot izhodni kanal.

Tretji parameter v prvi vrstici se imenuje velikost jedra in nam pomaga skrbeti za uporabljene filtre. Operacija padding je zadnji parameter.

Operacija zvijanja je povezana z aktivacijsko plastjo in tukaj Relu. Po dveh slojih Conv2d imamo operacijo največjega združevanja velikosti 2 * 2. Vrednost, ki izhaja iz tega, je serija normalizirana za stabilnost in izogibanje notranjemu kovarijantnemu premiku. Te operacije se ponovijo z več plastmi za globlje omrežje in zmanjšanje velikosti. Na koncu plast poravnamo, tako da lahko sestavimo linearno plast za preslikavo vrednosti na 10 vrednosti. Verjetnost vsakega nevrona od teh 10 nevronov bo na podlagi največje verjetnosti določila, kateremu razredu pripada določena slika.

Trenirajte model

@torch.no_grad () def vrednotenje (model, nalagalnik podatkov): model.eval () izhodi = [model.validation_step (paket) za paket v podatkovnem nalagalniku] vrnitev modela. = 10, stopnja učenja = 0.001): best_valid = Brez zgodovine = [] optimizer = torch.optim.Adam (model.parameters (), learning_rate, weight_decay = 0.0005) za obdobje v razponu (epohe): # Faza usposabljanja model.train ( ) train_losses = [] train_accuracy = [] za paket v tqdm (train_loader): izguba, accu = model.training_step (paket) train_losses.append (izguba) train_accuracy.append (accu) loss.backward () optimizer.step () optimizer .zero_grad () # Rezultat faze preverjanja = oceni (model, val_loader) rezultat ['train_loss'] = torch.stack (train_losses) .mean (). item () result ['train_accuracy'] = torch.stack (train_accuracy). mean (). item () model.epoch_end (epoha, rezultat) if (best_valid == Brez ali best_valid
zgodovina = fit (model, train_dl, val_dl)

To je osnovni korak za usposabljanje našega modela, da doseže želeni rezultat. tukaj bo funkcija fit ustrezala podatkom o vlaku in Valu z modelom, ki smo ga ustvarili. Funkcija fit najprej vzame seznam, imenovan zgodovina, ki skrbi za podatke iteracije vsake dobe. Zaženemo zanko for, tako da se lahko ponavljamo skozi vsako obdobje. Za vsako serijo s tqdm pokažemo napredek. Imenujemo korak usposabljanja, ki smo ga izvedli prej, in izračunamo natančnost in izgubo. Pojdite nazaj in razširite optimizator, ki smo ga opredelili prej. Ko to storimo, sledimo našemu seznamu, funkcije pa nam pomagajo natisniti podrobnosti in napredovati.

Funkcija vrednotenja pa uporablja funkcijo eval in za vsak korak vzamemo paket, naložen iz nalagalnika podatkov, in rezultat se izračuna. Vrednost se nato posreduje na konec obdobja preverjanja, ki smo ga definirali prej, in vrne se ustrezna vrednost.

Izris rezultatov

V tem koraku bomo predstavili natančnost v primerjavi z vsako epoho. Opazimo lahko, da se z naraščanjem obdobja natančnost sistema povečuje, podobno pa se izguba zmanjšuje. Rdeča črta tukaj označuje napredek podatkov o usposabljanju, modra pa za potrditev. Vidimo lahko, da je bilo v naših rezultatih veliko pretiravanja, saj podatki o usposabljanju precej presegajo rezultate validacije in podobno v primeru izgube. Po desetih obdobjih se zdi, da podatki o vlaku zaobidejo 10 -odstotno natančnost, vendar imajo izgubo okoli 90. Testni podatki so okoli 0.5%, izgube pa so blizu 81.

def plot_accuracies (zgodovina): Validation_accuracies = [x ['Accuracy'] za x v zgodovini] Training_Accuracies = [x ['train_accuracy'] za x v zgodovini] plt.plot (Training_Accuracies, '-rx') plt.plot (Validation_accuracies , '-bx') plt.xlabel ('epoha') plt.ylabel ('natančnost') plt.legend (['Usposabljanje', 'Potrditev']) plt.title ('Natančnost v primerjavi s številom epoh') ; plot_accuracies (zgodovina)
Natančne ploskve
def plot_losses (history): train_losses = [x.get ('train_loss') za x v zgodovini] val_losses = [x ['Loss'] za x v zgodovini] plt.plot (train_losses, '-bx') plt.plot (val_losses, '-rx') plt.xlabel ('epoch') plt.ylabel ('loss') plt.legend (['Training', 'Validation']) plt.title ('Izguba v primerjavi s številom obdobij '); plot_losses (zgodovina)

test_dataset = ImageFolder (data_dir+'/test', transform = ToTensor ()) test_loader = DeviceDataLoader (DataLoader (test_dataset, batch_size), device) result = evaluate (final_model, test_loader) print (f'Test Accuracy: {result ["Accuracy" ]*100: .2f}%')
Natančnost testa: 81.07%

Vidimo lahko, da smo na koncu z natančnostjo 81.07%.

ugotovitev:

Image: https: //unsplash.com/photos/5L0R8ZqPZHk

O meni: Sem študentka raziskovalka, ki se zanima za področje poglobljenega učenja in obdelave naravnega jezika in trenutno opravlja podiplomski študij umetne inteligence.

Vir slike

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

Lahko se povežete z mano na:

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

Mediji, prikazani v tem članku, niso v lasti Analytics Vidhya in se uporabljajo po presoji avtorja.

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

Časovni žig:

Več od Analitika Vidhya