implementacja Vgg16 Step by step w Keras dla początkujących

vgg16 jest architekturą sieci neuronowej (CNN), która została użyta do wygrania konkursu ILSVR(Imagenet) w 2014 roku. Jest uważany za jeden z doskonałych modeli wizji architektury do tej pory. Najbardziej unikalną rzeczą w VGG16 jest to, że zamiast dużej liczby hiperparametrów skupiali się na warstwach splotu filtra 3×3 z krokiem 1 i zawsze używali tej samej wyściółki i warstwy maxpool filtra 2×2 kroku 2. Konsekwentnie podąża za tym układem splotu i max pool layers w całej architekturze. W końcu ma 2 FC (w pełni połączone Warstwy), a następnie softmax dla wyjścia. 16 w VGG16 odnosi się do niego ma 16 warstw, które mają wagi. Ta sieć jest dość duża i ma około 138 milionów (około) parametrów.

Architektura VGG16

zamierzam zaimplementować pełny vgg16 od podstaw w kerasie. Ta implementacja zostanie wykonana na zestawie danych psy vs koty. Możesz pobrać zbiór danych z poniższego linku.

https://www.kaggle.com/c/dogs-vs-cats/data

Po pobraniu obrazów możesz wykonać poniższe kroki.

import keras,os
from keras.models import Sequential
from keras.layers import Dense, Conv2D, MaxPool2D , Flatten
from keras.preprocessing.image import ImageDataGenerator
import numpy as np

tutaj najpierw importuję wszystkie biblioteki, które będę potrzebował do implementacji VGG16. Będę używał metody sekwencyjnej, ponieważ tworzę model sekwencyjny. Model sekwencyjny oznacza, że wszystkie warstwy modelu będą ułożone w kolejności. Tutaj zaimportowałem ImageDataGenerator z keras.wstępne przetwarzanie. Celem ImageDataGenerator jest łatwe importowanie danych z etykietami do modelu. Jest to bardzo przydatna Klasa, ponieważ ma wiele funkcji do przeskalowania, obracania, powiększania, odwracania itp. Najbardziej użyteczną rzeczą w tej klasie jest to, że nie wpływa na dane przechowywane na dysku. Ta klasa zmienia dane w podróży, przekazując je do modelu.

trdata = ImageDataGenerator()
traindata = trdata.flow_from_directory(directory="data",target_size=(224,224))
tsdata = ImageDataGenerator()
testdata = tsdata.flow_from_directory(directory="test", target_size=(224,224))

tutaj tworzę i obiekt ImageDataGenerator dla danych treningowych i testowych oraz przekazuję folder z danymi treningowymi do obiektu trdata i podobnie przekazuję folder z danymi testowymi do obiektu tsdata. Struktura folderów danych będzie następująca –

struktura folderów danych przekazywanych do imagedatagenerator

imagedatagenerator automatycznie oznaczyć wszystkie dane w folderze Cat jako Cat i vis-à-vis dla folderu dla psa. W ten sposób dane są łatwo gotowe do przekazania do sieci neuronowej.

model = Sequential()model.add(Conv2D(input_shape=(224,224,3),filters=64,kernel_size=(3,3),padding="same", activation="relu"))model.add(Conv2D(filters=64,kernel_size=(3,3),padding="same", activation="relu"))model.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))model.add(Conv2D(filters=128, kernel_size=(3,3), padding="same", activation="relu"))model.add(Conv2D(filters=128, kernel_size=(3,3), padding="same", activation="relu"))model.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))model.add(Conv2D(filters=256, kernel_size=(3,3), padding="same", activation="relu"))model.add(Conv2D(filters=256, kernel_size=(3,3), padding="same", activation="relu"))model.add(Conv2D(filters=256, kernel_size=(3,3), padding="same", activation="relu"))model.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))model.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))model.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))

tutaj zacząłem od inicjalizacji modelu, określając, że model jest modelem sekwencyjnym. Po zainicjowaniu modelu dodaję

→ 2 x warstwa splotu 64 kanałów 3×3 kernal i tej samej wyściółki

→ 1 x warstwa maxpool o rozmiarze basenu 2×2 i kroku 2×2

→ 2 x warstwa splotu 128 kanałów 3×3 kernal i tej samej wyściółki

→ 1 x warstwa maxpool o rozmiarze basenu 2×2 i kroku 2×2

→ 3 x warstwa splotu 128 kanałów 3×3 kernal i tej samej wyściółki

→ 256 kanał 3×3 kernal i tej samej wyściółki

→ 1 x maxpool warstwa 2×2 wielkości basenu i kroku 2×2

→ 3 x warstwa splotu 512 Kanał 3×3 Kernal i tej samej wyściółki

→ 1 x maxpool warstwa 2×2 wielkości basenu i kroku 2×2

→ 3 x warstwa splotu 512 kanałów 3×3 kernal i ta sama wyściółka

→ 1 x warstwa maxpool o wielkości basenu 2×2 i kroku 2×2

dodaję również aktywację relu(Rektyfikowanej jednostki liniowej) do każdej warstwy, aby wszystkie wartości ujemne nie były przekazywane do następnej warstwy.

model.add(Flatten())model.add(Dense(units=4096,activation="relu"))model.add(Dense(units=4096,activation="relu"))model.add(Dense(units=2, activation="softmax"))

Po utworzeniu wszystkich splotu przekazuję dane do gęstej warstwy, aby spłaścić wektor, który wychodzi z splotu i dodać

→ 1 x gęsta warstwa 4096 jednostek

→ 1 x gęsta warstwa 4096 jednostek

→ 1 x gęsta warstwa Softmax 2 jednostek

użyję aktywacji RELU zarówno dla gęstej warstwy jednostek 4096, tak aby przestać przekazywać ujemne wartości przez sieć. Używam gęstej warstwy 2 jednostki na końcu z aktywacją softmax, ponieważ mam 2 klasy do przewidzenia na końcu, które są pies i kot. Warstwa softmax wyświetli wartość od 0 do 1 w oparciu o pewność modelu, do której klasy należą obrazy.

Po utworzeniu warstwy softmax model jest w końcu przygotowany. Teraz muszę skompilować model.

from keras.optimizers import Adam
opt = Adam(lr=0.001)model.compile(optimizer=opt, loss=keras.losses.categorical_crossentropy, metrics=)

tutaj będę używał Adam optimisera, aby osiągnąć globalne minima podczas treningu. Jeśli podczas treningu utknąłem w lokalnych minimach, adam optimiser pomoże nam wyjść z lokalnych minimów i osiągnąć globalne minima. Określimy również szybkość uczenia się optymalizatora, w tym przypadku jest on ustawiony na 0.001. Jeśli nasz trening odbija się na epokach, musimy zmniejszyć tempo uczenia się, abyśmy mogli osiągnąć globalne minima.

mogę sprawdzić podsumowanie modelu, który stworzyłem, korzystając z poniższego kodu.

model.summary()

wynikiem tego będzie podsumowanie modelu, który właśnie stworzyłem.

podsumowanie modelu
from keras.callbacks import ModelCheckpoint, EarlyStoppingcheckpoint = ModelCheckpoint("vgg16_1.h5", monitor='val_acc', verbose=1, save_best_only=True, save_weights_only=False, mode='auto', period=1)early = EarlyStopping(monitor='val_acc', min_delta=0, patience=20, verbose=1, mode='auto')hist = model.fit_generator(steps_per_epoch=100,generator=traindata, validation_data= testdata, validation_steps=10,epochs=100,callbacks=)

Po utworzeniu modelu zaimportuję metodę modelcheckpoint i earlystopping z keras. Utworzę obiekt obu i przekażę go jako funkcje zwrotne do fit_generator.

ModelCheckpoint pomaga nam zapisać model poprzez monitorowanie określonego parametru modelu. W tym przypadku monitoruję poprawność walidacji przekazując val_acc do ModelCheckpoint. Model zostanie zapisany na dysku tylko wtedy, gdy dokładność walidacji modelu w bieżącej epoce jest większa niż w poprzedniej epoce.

EarlyStopping pomaga nam wcześnie przerwać trening modelu, jeśli nie ma wzrostu parametru, który ustawiłem do monitorowania w EarlyStopping. W tym przypadku monitoruję poprawność walidacji, przekazując val_acc do EarlyStopping. Ustawiłem tutaj cierpliwość na 20, co oznacza, że model zatrzyma się, aby trenować, jeśli nie zauważy wzrostu dokładności walidacji w 20 epokach.

używam modelu.fit_generator ponieważ używam ImageDataGenerator do przekazywania danych do modelu. Przekażę dane dotyczące pociągu i testów do fit_generator. W fit_generator steps_per_epoch ustawi rozmiar partii, aby przekazać dane treningowe do modelu, a validation_steps zrobi to samo dla danych testowych. Możesz go dostosować na podstawie specyfikacji systemu.

Po wykonaniu powyższej linii model zacznie trenować, a ty zaczniesz widzieć dokładność treningu / walidacji i utratę.

model

po przeszkoleniu modelu można wizualizować dokładność treningu/walidacji i utratę. Jak być może zauważyłeś, przekazuję wyjście mode.fit_generator do zmiennej hist. Cała dokładność i strata treningu/walidacji są zapisywane w hist, a ja zwizualizuję je stamtąd.

import matplotlib.pyplot as plt
plt.plot(hist.history)
plt.plot(hist.history)
plt.plot(hist.history)
plt.plot(hist.history)
plt.title("model accuracy")
plt.ylabel("Accuracy")
plt.xlabel("Epoch")
plt.legend()
plt.show()

tutaj wizualizuję dokładność i stratę treningu / walidacji za pomocą matplotlib.

szkolenie/Walidacja dokładność i utrata

aby wykonać prognozy dla wytrenowanego modelu, muszę załadować najlepiej zapisany model i wstępnie przetworzyć obraz i przekazać obraz do modelu w celu wyjścia.

from keras.preprocessing import imageimg = image.load_img("image.jpeg",target_size=(224,224))
img = np.asarray(img)
plt.imshow(img)
img = np.expand_dims(img, axis=0)from keras.models import load_model
saved_model = load_model("vgg16_1.h5")output = saved_model.predict(img)
if output > output:
print("cat")
else:
print('dog')

wyjście modelu

tutaj załadowałem obraz za pomocą metody image w keras i przekonwertowałem go do tablicy numpy i dodałem dodatkowy wymiar do obrazu do obrazu, aby pasował do formatu nhwc (numer, wysokość, szerokość, kanał) kerasa.

jest to kompletna implementacja VGG16 w keras przy użyciu ImageDataGenerator. Możemy sprawić, że ten model będzie działał dla dowolnej liczby klas, zmieniając jednostkę ostatniej gęstej warstwy softmax na dowolną liczbę w oparciu o klasy, które musimy sklasyfikować

Github repo link:https://github.com/1297rohit/VGG16-In-Keras

Jeśli masz mniejszą ilość danych, to zamiast trenować swój model od podstaw możesz spróbować Transfer Learning. Napisałem również przewodnik krok po kroku dla początkujących na temat wykonywania nauki transferu na VGG16 przy użyciu Keras. Możesz to sprawdzić na : https://medium.com/@1297rohit/transfer-learning-from-scratch-using-keras-339834b153b9

Jeśli chcesz dowiedzieć się krok po kroku o wykrywaniu twarzy i rozpoznawaniu twarzy od zera, możesz przejść do mojego artykułu na ten temat pod linkiem:https://medium.com/@1297rohit/step-by-step-face-recognition-code-implementation-from-scratch-in-python-cc95fa041120

ciesz się klasyfikacją !

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.