Analiza cen Polkadot 13 wrz

Konwolucyjna sieć neuronowa – implementacja PyTorch na zbiorze danych CIFAR-10

Węzeł źródłowy: 1866263

Ten artykuł został opublikowany jako część Blogathon Data Science

Wprowadzenie

Cifar 10 | Splotowe sieci neuronowe pytorch
                                    1 Obraz

Konwolucyjne sieci neuronowe, zwane również ConvNets, zostały po raz pierwszy wprowadzone w latach 1980. przez Yanna LeCuna, informatyka, który pracował w tle. LeCun zbudował na pracy japońskiego naukowca Kunihiko Fukushimy podstawową sieć do rozpoznawania obrazów.

Stara wersja CNN, zwana LeNet (od LeCun), może widzieć odręcznie pisane cyfry. CNN pomaga znaleźć kody PIN z poczty. Ale pomimo swojej wiedzy ConvNets trzymali się blisko wizji komputerowej i sztucznej inteligencji, ponieważ stanęli przed poważnym problemem: nie mogli zbytnio skalować. CNN wymaga dużej ilości danych i integruje zasoby, aby dobrze pracować z dużymi obrazami.

W tamtym czasie ta metoda miała zastosowanie tylko do obrazów o niskiej rozdzielczości. Pytorch to biblioteka, która może wykonywać operacje uczenia głębokiego. Możemy to wykorzystać do wykonania splotowych sieci neuronowych. Konwolucyjne sieci neuronowe zawierają wiele warstw sztucznych neuronów. Neurony syntetyczne, złożone symulacje biologicznych odpowiedników, to funkcje matematyczne, które obliczają masę ważoną wielu danych wejściowych i aktywację wartości produktu.

Splotowe sieci neuronowe pytorch
2 Obraz

Powyższy obrazek pokazuje nam model CNN, który przyjmuje obraz podobny do cyfry 2 i daje nam wynik, jaka cyfra została pokazana na obrazie jako liczba. Omówimy szczegółowo, w jaki sposób to uzyskujemy w tym artykule.

CIFAR-10 to zbiór danych, który zawiera kolekcję obrazów 10 różnych klas. Ten zestaw danych jest szeroko stosowany do celów badawczych do testowania różnych modeli uczenia maszynowego, a zwłaszcza do problemów z widzeniem komputerowym. W tym artykule spróbujemy zbudować model sieci neuronowej za pomocą Pytorcha i przetestujemy go na zbiorze danych CIFAR-10, aby sprawdzić, jaką dokładność predykcji można uzyskać.

Importowanie biblioteki PyTorch 

importuj numpy jako np importuj pandy jako pd
import torch import torch.nn.functional as F from torchvision import dataset,transforms from torch import nn import matplotlib.pyplot as plt import numpy as np import seaborn as sns #from tqdm.notebook import tqdm z tqdm import tqdm

W tym kroku importujemy wymagane biblioteki. Widzimy, że używamy NumPy do operacji numerycznych i pand do operacji na ramkach danych. Biblioteka pochodni służy do importowania Pytorcha.

Pytorch ma komponent nn, który służy do abstrakcji operacji i funkcji uczenia maszynowego. Jest to importowane jako F. Używana jest biblioteka torchvision, abyśmy mogli zaimportować zestaw danych CIFAR-10. Ta biblioteka zawiera wiele zbiorów danych obrazów i jest szeroko wykorzystywana do badań. Przekształcenia można importować, dzięki czemu możemy zmienić rozmiar obrazu do równego rozmiaru dla wszystkich obrazów. Tqdm służy do śledzenia postępów podczas treningu i służy do wizualizacji.

Przeczytaj wymagany zbiór danych

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

Po odczytaniu zestawu danych możemy zobaczyć różne etykiety, takie jak żaba, ciężarówka, jeleń, samochód itp.

Analiza danych za pomocą PyTorch

print("Liczba punktów:",trainData.shape[0]) print("Liczba funkcji:",trainData.shape[1]) print("Cechy:",trainData.columns.values) print("Liczba Unikalne wartości") dla col w trainData: print(col,":",len(trainData[col].unique())) plt.figure(figsize=(12,8))

Wyjście:

Liczba punktów: 50000 Liczba cech: 2 Cechy: ['id' 'label'] Liczba unikalnych wartości id : 50000 label : 10

W tym kroku analizujemy zestaw danych i widzimy, że nasze dane pociągu zawierają około 50000 wierszy z ich identyfikatorem i powiązaną etykietą. Jest w sumie 10 klas jak w nazwie CIFAR-10.

Pobieranie zestawu sprawdzania poprawności za pomocą 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)

Ten krok jest taki sam jak krok uczenia, ale chcemy podzielić dane na zestawy do trenowania i walidacji.

(45000, 5000)
z 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,Truem)

Torch.utils posiada ładowarkę danych, która może pomóc nam załadować wymagane dane z pominięciem różnych parametrów, takich jak numer pracownika czy wielkość partii.

Definiowanie wymaganych funkcji

@latarka.no_grad() def dokładność(wyjścia, etykiety): _, preds = torch.max(wyjścia, dim=1) return torch.tensor(torch.sum(preds == etykiety).item() / len(preds )) class ImageClassificationBase(nn.Module): def training_step(self, batch): images, labels = batch out = self(images) # Generuj prognozy loss = F.cross_entropy(out, labels) # Oblicz stratę accu = dokładność(out ,etykiety) strata zwrotów,accu def validation_step(self, batch): obrazy, etykiety = wyjście partii = self(obrazy) # Generuj prognozy strata = F.cross_entropy(wyj, etykiety) # Oblicz stratę acc = dokładność(wyjście, etykiety) # Oblicz dokładność return {'Strata': loss.detach(), 'Accuracy': acc} def validation_epoch_end(self, outputs): batch_losses = [x['Loss'] for x in outputs] epoch_loss = torch.stack(batch_losses ).mean() # Połącz straty batch_accs = [x['Dokładność'] dla x na wyjściach] epoch_acc = torch.stack(batch_accs).mean() # Połącz dokładności return {'Strata': epoch_loss.item(), ' Dokładność': epoch_acc.item()} def epoch_end(self, epoch, result): pr int("Epoka :",epoch + 1) print(f'Dokładność pociągu:{result["train_accuracy"]*100:.2f}% Dokładność walidacji:{result["Dokładność"]*100:.2f}%' ) print(f'Utrata pociągu:{wynik["train_loss"]:.4f} Utrata walidacji:{wynik["Strata"]:.4f}')

Jak widać, użyliśmy klasowej implementacji ImageClassification i przyjmuje ona jeden parametr, którym jest nn.Module. W ramach tej klasy możemy zaimplementować różne funkcje lub różne kroki, takie jak szkolenie, walidacja itp. Funkcje tutaj są prostymi implementacjami Pythona.

Etap uczenia obejmuje obrazy i etykiety w partiach. używamy entropii krzyżowej dla funkcji straty i obliczamy stratę i zwracamy stratę. Jest to podobne do kroku walidacji, który widzimy w funkcji. Końce epok łączą ubytki i dokładności, a na koniec drukujemy dokładność i ubytki.

Wdrożenie konwolucyjnego modułu sieci neuronowej

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), # wyjście: 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), # wyjście: 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), # wyjście: 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.Linear (512, 10)) def forward(self, xb): return self.network(xb)

Jest to najważniejsza część implementacji sieci neuronowej. Przez cały czas używamy modułu nn, który zaimportowaliśmy z latarki. Jak widać w pierwszym wierszu, Conv2d to moduł, który pomaga zaimplementować splotową sieć neuronową. Pierwszy parametr 3 oznacza tutaj, że obraz jest kolorowy iw formacie RGB. Gdyby był to obraz w skali szarości, wybralibyśmy 1.

32 to rozmiar początkowego kanału wyjściowego, a kiedy przejdziemy do następnej warstwy conv2d, to 32 jako kanał wejściowy i 64 jako kanał wyjściowy.

Trzeci parametr w pierwszym wierszu nazywa się rozmiarem jądra i pomaga nam zadbać o używane filtry. Ostatnim parametrem jest operacja dopełniania.

Operacja konwolucji jest połączona z warstwą aktywacyjną i Relu tutaj. Po dwóch warstwach Conv2d mamy operację maksymalnej puli o rozmiarze 2 * 2. Wartość wychodząca z tego jest znormalizowana wsadowo pod kątem stabilności i uniknięcia wewnętrznego przesunięcia współzmiennej. Operacje te są powtarzane z większą liczbą warstw, aby pogłębić sieć i zmniejszyć rozmiar. Na koniec spłaszczamy warstwę, dzięki czemu możemy zbudować warstwę liniową, aby odwzorować wartości na 10 wartości. Prawdopodobieństwo każdego neuronu z tych 10 neuronów określi, do której klasy należy dany obraz na podstawie maksymalnego prawdopodobieństwa.

Trenuj model

@torch.no_grad() def assessment(model, data_loader): model.eval() outputs = [model.validation_step(batch) for batch in data_loader] return model.validation_epoch_end(wyjścia) def fit(model, train_loader, val_loader,epochs =10,learning_rate=0.001): best_valid = None history = [] Optimizer = torch.optim.Adam(model.parameters(), learning_rate,weight_decay=0.0005) dla epoki w zakresie(epok): # Faza uczenia model.train( ) train_losses = [] train_accuracy = [] dla partii w tqdm(train_loader): loss,accu = model.training_step(batch) train_losses.append(loss) train_accuracy.append(accu) loss.backward()Optimizer.step() Optimizer .zero_grad() # Wynik fazy walidacji = assessment(model, val_loader) wynik['train_loss'] = torch.stack(train_losses).mean().item() wynik['train_accuracy'] = torch.stack(train_accuracy). mean().item() model.epoch_end(epoka, wynik) if(best_valid == Brak lub best_valid
historia = fit(model, train_dl, val_dl)

Jest to podstawowy krok do wytrenowania naszego modelu, aby uzyskać wymagany wynik. funkcja dopasowania tutaj dopasuje dane pociągu i Val do utworzonego przez nas modelu. Funkcja fit pobiera początkowo listę zwaną historią, która zajmuje się danymi iteracyjnymi każdej epoki. Uruchamiamy pętlę for, aby móc iterować w każdej epoce. Dla każdej partii upewniamy się, że pokazujemy postęp za pomocą tqdm. Nazywamy etap szkolenia, który wdrożyliśmy wcześniej i obliczamy dokładność i stratę. Przejdź do wstecznej propagacji i uruchom optymalizator, który zdefiniowaliśmy wcześniej. Gdy to zrobimy, śledzimy naszą listę, a funkcje pomagają nam drukować szczegóły i postęp.

Z drugiej strony funkcja oceniania korzysta z funkcji eval, a dla każdego kroku pobieramy wsad załadowany z programu ładującego dane i obliczamy dane wyjściowe. Wartość jest następnie przekazywana do zdefiniowanego wcześniej końca epoki walidacji i zwracana jest odpowiednia wartość.

Wykreślanie wyników

W tym kroku zwizualizujemy dokładność względem każdej epoki. Możemy zaobserwować, że wraz ze wzrostem epoki dokładność systemu rośnie i podobnie straty maleją. Czerwona linia wskazuje postęp danych treningowych, a niebieska oznacza walidację. Widzimy, że w naszych wynikach wystąpiła duża ilość overfittingu, ponieważ dane treningowe znacznie przewyższają wynik walidacji i podobnie w przypadku przegranej. Po 10 epokach dane pociągu wydają się omijać dokładność 90%, ale mają stratę około 0.5. Dane testowe sięgają około 81%, a straty są bliskie 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 , '-bx') plt.xlabel('epoka') plt.ylabel('dokładność') plt.legend(['Szkolenie', 'Walidacja']) plt.title('Dokładność a liczba epok') ; plot_accuracy(historia)
Wykresy dokładności
def plot_straty(historia): train_losses = [x.get('train_loss') for x w historii] val_losses = [x['Strata'] for x in history] plt.plot(train_losses, '-bx') plt.plot (val_losses, '-rx') plt.xlabel('epoka') plt.ylabel('strata') plt.legend(['Szkolenie', 'Walidacja']) plt.title('Strata a liczba epok '); straty_działki(historia)

test_dataset = ImageFolder(data_dir+'/test', transform=ToTensor()) test_loader = DeviceDataLoader(DataLoader(test_dataset, batch_size), device) result = Evaluation(final_model, test_loader) print(f'Test Accuracy:{result["Dokładność" ]*100:.2f}%')
Dokładność testu: 81.07%

Widzimy, że kończymy z dokładnością 81.07%.

Wnioski:

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

O mnie: Jestem studentem naukowym zainteresowanym dziedziną Deep Learning i Przetwarzania Języka Naturalnego, a obecnie kończę studia podyplomowe w zakresie Sztucznej Inteligencji.

Image Source

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

Zapraszam do kontaktu ze mną na:

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

Media pokazane w tym artykule nie są własnością Analytics Vidhya i są używane według uznania Autora.

Źródło: https://www.analyticsvidhya.com/blog/2021/09/convolutional-neural-network-pytorch-implementation-on-cifar10-dataset/

Znak czasu:

Więcej z Analityka Widhja