Polkadot-prijsanalyse 13 sep

Convolutioneel neuraal netwerk - PyTorch-implementatie op CIFAR-10-gegevensset

Bronknooppunt: 1866263

Dit artikel is gepubliceerd als onderdeel van het Data Science-blogathon

Introductie

Cifar 10 | Convolutionele neurale netwerken pytorch
                                    Afbeelding 1

Convolutionele neurale netwerken, ook wel ConvNets genoemd, werden voor het eerst geïntroduceerd in de jaren tachtig door Yann LeCun, een computerwetenschappelijk onderzoeker die op de achtergrond werkte. LeCun bouwde op het werk van Kunihiko Fukushima, een Japanse wetenschapper, een basisnetwerk voor beeldherkenning.

De oude versie van CNN, genaamd LeNet (naar LeCun), kan handgeschreven cijfers zien. CNN helpt bij het vinden van pincodes van de post. Maar ondanks hun expertise bleef ConvNets dicht bij computervisie en kunstmatige intelligentie omdat ze met een groot probleem werden geconfronteerd: ze konden niet veel schalen. CNN's vereisen veel gegevens en integreren bronnen om goed te werken voor grote afbeeldingen.

Destijds was deze methode alleen van toepassing op afbeeldingen met een lage resolutie. Pytorch is een bibliotheek die deep learning-bewerkingen kan uitvoeren. We kunnen dit gebruiken om convolutionele neurale netwerken uit te voeren. Convolutionele neurale netwerken bevatten vele lagen kunstmatige neuronen. Synthetische neuronen, complexe simulaties van biologische tegenhangers, zijn wiskundige functies die de gewogen massa van meerdere inputs en productwaarde-activering berekenen.

Convolutionele neurale netwerken pytorch
Afbeelding 2

De bovenstaande afbeelding toont ons een CNN-model dat een cijferachtige afbeelding van 2 inneemt en ons het resultaat geeft van welk cijfer in de afbeelding als een getal werd weergegeven. Hoe we hieraan komen, zullen we in dit artikel uitgebreid bespreken.

CIFAR-10 is een dataset met een verzameling afbeeldingen van 10 verschillende klassen. Deze dataset wordt veel gebruikt voor onderzoeksdoeleinden om verschillende machine learning-modellen te testen en vooral voor computervisieproblemen. In dit artikel zullen we proberen een neuraal netwerkmodel te bouwen met behulp van Pytorch en dit te testen op de CIFAR-10-dataset om te controleren welke voorspellingsnauwkeurigheid kan worden verkregen.

De PyTorch-bibliotheek importeren 

importeer numpy als np importeer panda's als pd
import torch import torch.nn.functioneel als F uit torchvision importeer datasets, transformeert van torch import nn import matplotlib.pyplot als plt import numpy als np import seaborn als sns #from tqdm.notebook import tqdm uit tqdm import tqdm

In deze stap importeren we de benodigde bibliotheken. We kunnen zien dat we NumPy gebruiken voor numerieke bewerkingen en panda's voor gegevensframebewerkingen. De fakkelbibliotheek wordt gebruikt om Pytorch te importeren.

Pytorch heeft een nn-component die wordt gebruikt voor de abstractie van machine learning-bewerkingen en -functies. Dit wordt geïmporteerd als F. De torchvision bibliotheek wordt gebruikt zodat we de CIFAR-10 dataset kunnen importeren. Deze bibliotheek heeft veel beelddatasets en wordt veel gebruikt voor onderzoek. De transformaties kunnen worden geïmporteerd, zodat we het formaat van de afbeelding voor alle afbeeldingen gelijk kunnen maken. De tqdm wordt gebruikt zodat we de voortgang tijdens de training kunnen bijhouden en wordt gebruikt voor visualisatie.

Lees de benodigde dataset

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

Zodra we de dataset hebben gelezen, kunnen we verschillende labels zien, zoals de kikker, vrachtwagen, hert, auto, enz.

Gegevens analyseren met PyTorch

print("Aantal punten:",trainData.shape[0]) print("Aantal features:",trainData.shape[1]) print("Features:",trainData.columns.values) print("Aantal Unieke waarden") voor col in trainData: print(col,":",len(trainData[col].unique())) plt.figure(figsize=(12,8))

Output:

Aantal punten: 50000 Aantal kenmerken: 2 Kenmerken: ['id' 'label'] Aantal unieke waarden id: 50000 label: 10

In deze stap analyseren we de dataset en zien we dat onze treingegevens ongeveer 50000 rijen hebben met hun id en bijbehorend label. Er zijn in totaal 10 klassen zoals in de naam CIFAR-10.

De validatieset verkrijgen met PyTorch

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

Deze stap is hetzelfde als de trainingsstap, maar we willen de gegevens opsplitsen in trein- en validatiesets.

(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=4, pin_memory=True)

De torch.utils hebben een gegevenslader die ons kan helpen de vereiste gegevens te laden, waarbij verschillende parameters zoals het aantal werknemers of de batchgrootte worden omzeild.

De vereiste functies definiëren

@torch.no_grad() def nauwkeurigheid (outputs, labels): _, 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) # Genereer voorspellingen verlies = F.cross_entropy(out, labels) # Bereken verlies accu = nauwkeurigheid(out ,labels) return loss,accu def validation_step(self, batch): images, labels = batch out = self(images) # Genereer voorspellingen loss = F.cross_entropy(out, labels) # Bereken verlies acc = nauwkeurigheid (out, labels) # Bereken nauwkeurigheidsretour {'Loss': loss.detach(), 'Nauwkeurigheid': acc} def validation_epoch_end(self, outputs): batch_losses = [x['Loss'] for x in outputs] epoch_loss = torch.stack(batch_losses ).mean() # Combineer verliezen batch_accs = [x['Nauwkeurigheid'] voor x in outputs] epoch_acc = torch.stack(batch_accs).mean() # Combineer nauwkeurigheden return {'Loss': epoch_loss.item(), ' Nauwkeurigheid': epoch_acc.item()} def epoch_end(zelf, tijdperk, resultaat): pr int("Epoch :",epoch + 1) print(f'Trein Nauwkeurigheid:{result["train_accuracy"]*100:.2f}% Validatie Nauwkeurigheid:{result["Nauwkeurigheid"]*100:.2f}%' ) print(f'Treinverlies:{result["train_loss"]:.4f} Validatieverlies:{result["Verlies"]:.4f}')

Zoals we hier kunnen zien, hebben we de class-implementatie van ImageClassification gebruikt en er is één parameter voor nodig, namelijk nn.Module. Binnen deze klasse kunnen we de verschillende functies of verschillende stappen implementeren, zoals training, validatie, enz. De functies hier zijn eenvoudige python-implementaties.

De trainingsstap neemt afbeeldingen en labels in batches. we gebruiken kruis-entropie voor de verliesfunctie en berekenen het verlies en retourneren het verlies. Dit is vergelijkbaar met de validatiestap zoals we kunnen zien in de functie. De einden van het tijdperk combineren verliezen en nauwkeurigheden en ten slotte drukken we de nauwkeurigheden en verliezen af.

Implementatie van convolutionele neurale netwerkmodule

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), # output: 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), # output: 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), # output: 256 x 4 x 4 nn.BatchNorm2d(256), nn.Flatten(), nn.Lineair(256*4*4, 1024), nn.ReLU(), nn.Lineair(1024, 512), nn.ReLU(), nn.Lineair (512, 10)) def forward(self, xb): return self.network(xb)

Dit is het belangrijkste onderdeel van de implementatie van neurale netwerken. We gebruiken overal de nn-module die we uit torch hebben geïmporteerd. Zoals we in de eerste regel kunnen zien, is de Conv2d een module die helpt bij het implementeren van een convolutief neuraal netwerk. De eerste parameter 3 geeft hier aan dat de afbeelding gekleurd is en in RGB-formaat. Als het een grijswaardenafbeelding was, zouden we voor 1 zijn gegaan.

32 is de grootte van het initiële uitvoerkanaal en als we voor de volgende conv2d-laag gaan, zouden we deze 32 hebben als het invoerkanaal en 64 als het uitvoerkanaal.

De derde parameter in de eerste regel heet kernelgrootte en helpt ons om de gebruikte filters te beheren. Opvulbewerking is de laatste parameter.

De convolutiebewerking is hier verbonden met een activatielaag en Relu. Na twee Conv2d-lagen hebben we een max-pooling-bewerking van grootte 2 * 2. De waarde die hieruit voortkomt, is batchgewijs genormaliseerd voor stabiliteit en om interne covariabele verschuiving te voorkomen. Deze bewerkingen worden herhaald met meer lagen om het netwerk dieper te maken en de omvang te verkleinen. Ten slotte maken we de laag plat zodat we een lineaire laag kunnen bouwen om de waarden toe te wijzen aan 10 waarden. De waarschijnlijkheid van elk neuron van deze 10 neuronen zal bepalen tot welke klasse een bepaald beeld behoort op basis van de maximale waarschijnlijkheid.

Train het model

@torch.no_grad() def Evaluation(model, data_loader): model.eval() outputs = [model.validation_step(batch) for batch in data_loader] return model.validation_epoch_end(outputs) def fit(model, train_loader, val_loader,epochs =10,learning_rate=0.001): best_valid = Geen history = [] optimizer = torch.optim.Adam(model.parameters(), learning_rate,weight_decay=0.0005) voor epoch in range(epochs): # Training Phase model.train( ) train_losses = [] train_accuracy = [] voor batch in tqdm(train_loader): loss,accu = model.training_step(batch) train_losses.append(loss) train_accuracy.append(accu) loss.backward() optimizer.step() optimizer .zero_grad() # Validatiefase resultaat = evalueren(model, val_loader) resultaat['train_loss'] = torch.stack(train_losses).mean().item() resultaat['train_accuracy'] = torch.stack(train_accuracy). mean().item() model.epoch_end(epoch, result) if(best_valid == Geen of best_valid
geschiedenis = fit(model, train_dl, val_dl)

Dit is een basisstap om ons model te trainen om het vereiste resultaat te krijgen. de fit-functie hier past bij de trein- en Val-gegevens met het model dat we hebben gemaakt. De fit-functie neemt in eerste instantie een lijst met de naam geschiedenis die zorgt voor de iteratiegegevens van elk tijdperk. We voeren een for-lus uit, zodat we elk tijdperk kunnen herhalen. Voor elke batch zorgen we ervoor dat we de voortgang laten zien met tqdm. We noemen de trainingsstap die we eerder hebben geïmplementeerd en berekenen nauwkeurigheid en verlies. De keuze voor achterwaartse propagatie en run-optimizer die we eerder hebben gedefinieerd. Zodra we dit hebben gedaan, houden we onze lijst bij en de functies helpen ons de details en voortgang af te drukken.

De evaluatiefunctie daarentegen gebruikt de eval-functie en voor elke stap nemen we de batch die is geladen uit de gegevenslader en wordt de uitvoer berekend. De waarde wordt vervolgens doorgegeven aan het validatie-tijdperk dat we eerder hebben gedefinieerd en de respectieve waarde wordt geretourneerd.

De resultaten plotten

In deze stap zullen we de nauwkeurigheid versus elk tijdperk visualiseren. We kunnen zien dat naarmate het tijdperk toeneemt, de nauwkeurigheid van het systeem blijft toenemen en op dezelfde manier blijft het verlies afnemen. De rode lijn hier geeft de voortgang van de trainingsgegevens aan en blauw voor de validatie. We kunnen zien dat er een behoorlijke hoeveelheid overfitting is geweest in onze resultaten, aangezien de trainingsgegevens behoorlijk beter presteren dan het validatieresultaat en op dezelfde manier in geval van verlies. Na 10 tijdperken lijken de treingegevens de nauwkeurigheid van 90% te omzeilen, maar hebben ze een verlies van ongeveer 0.5. De testgegevens bedragen ongeveer 81% en de verliezen zijn bijna 0.2.

def plot_accuracies(history): Validation_accuracies = [x['Nauwkeurigheid'] voor x in geschiedenis] Training_Accuracies = [x['train_accuracy'] voor x in geschiedenis] plt.plot(Training_Accuracies, '-rx') plt.plot(Validation_accuracies , '-bx') plt.xlabel('epoch') plt.ylabel('nauwkeurigheid') plt.legend(['Training', 'Validatie']) plt.title('Nauwkeurigheid vs. aantal tijdperken') ; plot_accuracy(geschiedenis)
nauwkeurigheid plots
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('epoch') plt.ylabel('loss') plt.legend(['Training', 'Validation']) plt.title('Verlies vs. aantal tijdperken '); plot_losses(geschiedenis)

test_dataset = ImageFolder(data_dir+'/test', transform=ToTensor()) test_loader = DeviceDataLoader(DataLoader(test_dataset, batch_size), device) result = evaluatie(final_model, test_loader) print(f'Test Nauwkeurigheid:{result["Nauwkeurigheid" ]*100:.2f}%')
Testnauwkeurigheid: 81.07%

We kunnen zien dat we eindigen met een nauwkeurigheid van 81.07%.

Conclusie:

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

Over mij: Ik ben een onderzoeksstudent die geïnteresseerd is in diep leren en natuurlijke taalverwerking en momenteel bezig is met een postgraduaat in kunstmatige intelligentie.

Image Source

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

Voel je vrij om contact met mij op te nemen op:

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

De media die in dit artikel worden getoond, zijn geen eigendom van Analytics Vidhya en worden naar goeddunken van de auteur gebruikt.

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

Tijdstempel:

Meer van Analytics Vidhya