Переносное обучение (TL) – это исследовательская проблема в области машинного обучения (ML), которая фокусируется на сохранении знаний, полученных при решении одной задачи, и применении их к другой, но связанной проблеме.
Например, знания, полученные при обучении распознаванию автомобилей, можно применить при попытке распознать грузовики.
VGG16 — модель сверточной нейронной сети, предложенная К. Симоняном и А. Зиссерманом из Оксфордского университета в статье Очень глубокие сверточные сети для крупномасштабного распознавания изображений. Точность модели достигает 92,7 % в тестах Top-5 в ImageNet, который представляет собой набор данных из более чем 14 миллионов изображений, принадлежащих к 1000 классам. Это была одна из известных моделей, представленных на ILSVRC-2014. Это улучшение по сравнению с AlexNet за счет замены больших фильтров размером с ядро (11 и 5 в первом и втором сверточных слоях соответственно) несколькими фильтрами размера ядра 3 × 3 один за другим.
Проект:
- Соберите набор данных образцов лиц разных лиц в папках поезда и теста с разными папками для каждого лица.
- Используйте любую модель для обучения набора данных с помощью Transfer Learning.
- Распознавайте лица, используя свою модель
Предварительное условие до практического применения:
Список библиотек Python, которые необходимо установить:
- тензорный поток
- Керас
- opencv
- подушка
- пустышка
conda install tensorflow keras opencv-python pillow numpy
Выполнение:
Перейдите в свой блокнот Jupyter и напишите код:
ШАГ 1.Сбор набора данных для лиц
# Assuming for collecting the dataset of images directories are already created under test and train directory as n0,n1,n1.... # acoording to the data of number of persons # Load functions def face_extractor(img): # Function detects faces and returns the cropped face # If no face detected, it returns the input image gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) faces = face_classifier.detectMultiScale(gray, 3, 5) if faces is (): return None # Crop all faces found for (x,y,w,h) in faces: cropped_face = img[y:y+h, x:x+w] return cropped_face def capture_images(t,name): # Initialize Webcam cap = cv2.VideoCapture(0) count = 1 # Collect 100 samples of your face from webcam input while True: ret, frame = cap.read() if face_extractor(frame) is not None: count += 1 face = cv2.resize(face_extractor(frame), (200, 200)) #face = cv2.cvtColor(face, cv2.COLOR_BGR2GRAY) # Save file in specified directory with unique name file_name_path = t+"image" + str(count) + '.jpg' cv2.imwrite(file_name_path, face) # Put count on images and display live count cv2.putText(face, str(count), (50, 50), cv2.FONT_HERSHEY_COMPLEX, 1, (0,255,0), 2) cv2.imshow(name, face) else: print("Face not found") pass if cv2.waitKey(1) == 13 or count == 100: #13 is the Enter Key break cap.release() cv2.destroyAllWindows() return "Collecting Samples Complete"
Укажите количество людей, для которых вы хотите собрать набор данных об их лицах для обучения и тестирования.
import cv2 import numpy as np import time # Load HAAR face classifier face_classifier = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') file_path='C://Users//500060783//Desktop//MLOPS-WS//Projects//Face Recognizer Transfer Learning//Family//' train_path=file_path+"train//" test_path=file_path+"test//" c=int(input("Enter the number of persons you want to capture image dataset")) for i in range(c): print(f"Provide your images for testing dataset for person {i+1}") time.sleep(2) t=train_path+"n"+str(i)+"//" name="train images" out=capture_images(t,name)+f" for train set of person{i+1}" time.sleep(1) print(out) time.sleep(2) t=test_path+"n"+str(i)+"//" name="test images" out=capture_images(t,name)+f" for test set of person{i+1}" time.sleep(1) print(out) time.sleep(2) print("Data Set completed successfully")
ШАГ 2.Загрузка модели VGG-16 и заморозка всех слоев
from keras.applications import vgg16 # VGG-16 was designed to work on 224 x 224 pixel input images sizes img_rows, img_cols = 224, 224 # Re-loads the VGG-16 model without the top or FC layers Vgg16 = vgg16.VGG16(weights = 'imagenet', include_top = False, input_shape = (img_rows, img_cols, 3)) # Here we freeze the last 4 layers # Layers are set to trainable as True by default for layer in Vgg16.layers: layer.trainable = False # Let's print our layers for (i,layer) in enumerate(Vgg16.layers): print(str(i) + " "+ layer.__class__.__name__, layer.trainable)
ШАГ 3.Добавьте полностью подключенную головку обратно на VGG-16.
def add_fc(bottom_model, num_classes): """creates the top or head of the model that will be placed ontop of the bottom layers""" top_model = bottom_model.output top_model = GlobalAveragePooling2D()(top_model) top_model = Dense(1024,activation='relu')(top_model) top_model = Dense(1024,activation='relu')(top_model) top_model = Dense(512,activation='relu')(top_model) top_model = Dense(num_classes,activation='softmax')(top_model) return top_model
Добавление полностью подключенной головы обратно в модель
from keras.models import Sequential from keras.layers import Dense, Dropout, Activation, Flatten, GlobalAveragePooling2D from keras.layers import Conv2D, MaxPooling2D, ZeroPadding2D from keras.layers.normalization import BatchNormalization from keras.models import Model # Set our class number to 3 (Young, Middle, Old) num_classes = 3 FC_Head = add_fc(Vgg16, num_classes) model = Model(inputs = Vgg16.input, outputs = FC_Head) print(model.summary())
ШАГ 4. Загрузка нашего набора данных о лицах
from keras.preprocessing.image import ImageDataGenerator train_data_dir = 'Family/train' validation_data_dir = 'Family/test' # Let's use some data augmentaiton train_datagen = ImageDataGenerator( rescale=1./255, rotation_range=45, width_shift_range=0.3, height_shift_range=0.3, horizontal_flip=True, fill_mode='nearest') validation_datagen = ImageDataGenerator(rescale=1./255) # set our batch size (typically on most mid tier systems we'll use 16-32) batch_size = 32 train_generator = train_datagen.flow_from_directory( train_data_dir, target_size=(img_rows, img_cols), batch_size=batch_size, class_mode='categorical') validation_generator = validation_datagen.flow_from_directory( validation_data_dir, target_size=(img_rows, img_cols), batch_size=batch_size, class_mode='categorical')
ШАГ 5. Модель обучения
from keras.optimizers import RMSprop from keras.callbacks import ModelCheckpoint, EarlyStopping checkpoint = ModelCheckpoint("face_recognize_vgg16.h5", monitor="val_loss", mode="min", save_best_only = True, verbose=1) earlystop = EarlyStopping(monitor = 'val_loss', min_delta = 0, patience = 3, verbose = 1, restore_best_weights = True) # we put our call backs into a callback list callbacks = [earlystop, checkpoint] # We use a very small learning rate model.compile(loss = 'categorical_crossentropy', optimizer = RMSprop(lr = 0.001), metrics = ['accuracy']) # Enter the number of training and validation samples here nb_train_samples = 605 nb_validation_samples = 255 # We only train 5 EPOCHS epochs = 5 batch_size = 16 history = model.fit_generator( train_generator, steps_per_epoch = nb_train_samples // batch_size, epochs = epochs, callbacks = callbacks, validation_data = validation_generator, validation_steps = nb_validation_samples // batch_size)
ШАГ 6. Загрузка нашего классификатора
from keras.models import load_model classifier = load_model('face_recognize_vgg16.h5')
ШАГ 7. Проверка нашего классификатора на нескольких тестовых изображениях.
import os import cv2 import numpy as np from os import listdir from os.path import isfile, join face_recognize_dict = {"[0]": "Saurabh ", "[1]": "Piyush", "[2]": "Aditya"} face_recognize_dict_n = {"n0": "Saurabh ", "n1": "Piyush", "n2": "Aditya"} def draw_test(name, pred, im): face = face_recognize_dict[str(pred)] BLACK = [0,0,0] expanded_image = cv2.copyMakeBorder(im, 80, 0, 0, 100 ,cv2.BORDER_CONSTANT,value=BLACK) cv2.putText(expanded_image, face, (20, 60) , cv2.FONT_HERSHEY_SIMPLEX,1, (0,0,255), 2) cv2.imshow(name, expanded_image) def getRandomImage(path): """function loads a random images from a random folder in our test path """ folders = list(filter(lambda x: os.path.isdir(os.path.join(path, x)), os.listdir(path))) random_directory = np.random.randint(0,len(folders)) path_class = folders[random_directory] print("Class - " + face_recognize_dict_n[str(path_class)]) file_path = path + path_class file_names = [f for f in listdir(file_path) if isfile(join(file_path, f))] random_file_index = np.random.randint(0,len(file_names)) image_name = file_names[random_file_index] return cv2.imread(file_path+"/"+image_name) for i in range(0,10): input_im = getRandomImage("Family/test/") input_original = input_im.copy() input_original = cv2.resize(input_original, None, fx=0.5, fy=0.5, interpolation = cv2.INTER_LINEAR) input_im = cv2.resize(input_im, (224, 224), interpolation = cv2.INTER_LINEAR) input_im = input_im / 255. input_im = input_im.reshape(1,224,224,3) # Get Prediction res = np.argmax(classifier.predict(input_im, 1, verbose = 0), axis=1) # Show image with predicted class draw_test("Prediction", res, input_original) cv2.waitKey(0) cv2.destroyAllWindows()
Наша модель правильно предсказала 9/10 изображений, что делает нашу модель приблизительной с точностью 90%.
БОНУС: прогнозирование в прямом эфире
import cv2 cap=cv2.VideoCapture(0) while True: status,photo=cap.read() input_im=photo input_original = input_im.copy() input_original = cv2.resize(input_original, None, fx=0.5, fy=0.5, interpolation = cv2.INTER_LINEAR) input_im = cv2.resize(input_im, (224, 224), interpolation = cv2.INTER_LINEAR) input_im = input_im / 255. input_im = input_im.reshape(1,224,224,3) # Get Prediction res = np.argmax(classifier.predict(input_im, 1, verbose = 0), axis=1) # Show image with predicted class draw_test("Prediction", res, input_original) if cv2.waitKey(1)==13: break cv2.destroyAllWindows() cap.release()
После исследования и обучения моделей из RESNET, Inception, MobileNet и VGG, VGG дает наилучшую точность и прогнозы в моем наборе данных.
Вы можете просмотреть код в моей учетной записи Github: https://github.com/saurabhagarwal43800/Face-Recognition-using-VGG-16.git