Реализация проекта…

Введение и обзор

Keras - очень мощная библиотека Python с открытым исходным кодом, которая работает поверх других машинных библиотек с открытым исходным кодом, таких как TensorFlow, Theano и т. Д., Используется для разработки и оценки моделей глубокого обучения и использует различные методы оптимизации.

Функции -

  • Keras полностью поддерживает рекуррентные нейронные сети и сверточные нейронные сети.
  • Keras плавно работает как на процессоре, так и на графическом процессоре
  • Keras NN написаны на Python, который выступает за простоту и большие возможности отладки.
  • Керас известен своей невероятно выразительной, гибкой, минималистичной структурой.
  • Keras - последовательный, простой и расширяемый API
  • Керас также известен своей высокой вычислительной масштабируемостью.
  • Обширная поддержка различных платформ и бэкендов


В этом проекте мы реализуем распознавание мимики с помощью Keras. Наш набор данных (уже разделенный на обучающий и тестовый) состоит из изображений различных выражений лица, загруженных из репозитория Kaggle.

Импортировать библиотеки

import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import utils
import os
%matplotlib inline
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.layers import Dense, Input, Dropout,Flatten, Conv2D
from tensorflow.keras.layers import BatchNormalization, Activation, MaxPooling2D
from tensorflow.keras.models import Model, Sequential
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.callbacks import ModelCheckpoint, ReduceLROnPlateau
from tensorflow.keras.utils import plot_model
from IPython.display import SVG, Image
from livelossplot import PlotLossesTensorFlowKeras
import tensorflow as tf
print("Tensorflow version:", tf.__version__)

Выход -

Tensorflow version: 2.1.0

Постройте изображения выражений

utils.datasets.fer.plot_example_images(plt).show()

Перечислите различные категории экспрессионных изображений



for expression in os.listdir("train/"):
    print(str(len(os.listdir("train/" + expression)))+ " " + expression + " images")

Выход -

3171 surprise images
7215 happy images
4965 neutral images
3995 angry images
4830 sad images
436 disgust images
4097 fear images

Создание пакетов обучения и проверки

Чтобы максимально использовать наши обучающие примеры, мы «расширим» их с помощью номера. случайных преобразований, которые, в свою очередь, помогают предотвратить переоснащение модели и помогают модели лучше обобщать.

keras.preprocessing.image.ImageDataGenerator класс в keras позволяет -

  • Для создания экземпляров генераторов пакетов расширенных изображений (и их меток) через .flow(data, labels) или .flow_from_directory(directory). Его можно использовать с методами модели Keras, которые принимают генераторы данных в качестве входных данных, fit_generator, evaluate_generator & predict_generator.
  • Чтобы настроить случайные преобразования и операции нормализации, которые будут выполняться с данными вашего изображения во время обучения
img_size = 48
batch_size = 64
datagen_train = ImageDataGenerator(horizontal_flip=True)
train_generator = datagen_train.flow_from_directory("train/",
                  target_size = (img_size,img_size),
                  color_mode='grayscale',
                  batch_size=batch_size,
                  class_mode='categorical',shuffle= True)
datagen_validation = ImageDataGenerator(horizontal_flip=True)
validation_generator = datagen_validation.flow_from_directory("test/",
target_size = (img_size,img_size),
color_mode='grayscale',
batch_size=batch_size,                                            class_mode='categorical',shuffle= True)

Выход -

Found 28709 images belonging to 7 classes.
Found 7178 images belonging to 7 classes.

Создать модель CNN

Мы будем использовать convnet для этой задачи. Важно выбрать количество параметров в вашей модели, то есть количество слоев и размер каждого слоя.

model= Sequential()
#1 Conv
model.add(Conv2D(64,(3,3),padding='same',input_shape=(48,48,1)))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.25))
# 2 conv
model.add(Conv2D(128,(5,5), padding = 'same'))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.25))
# 3 conv
model.add(Conv2D(512,(3,3), padding = 'same'))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.25))
# 4 conv
model.add(Conv2D(512,(3,3), padding = 'same'))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(256))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Dropout(0.25))
model.add(Dense(512))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Dropout(0.25))
model.add(Dense(7,activation='softmax'))
opt=Adam(lr=0.0005)
model.compile(optimizer=opt,loss='categorical_crossentropy',metrics=['accuracy'])
model.summary()

Выход -

Model: "sequential_3"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_4 (Conv2D)            (None, 48, 48, 64)        640       
_________________________________________________________________
batch_normalization_6 (Batch (None, 48, 48, 64)        256       
_________________________________________________________________
activation_6 (Activation)    (None, 48, 48, 64)        0         
_________________________________________________________________
max_pooling2d_4 (MaxPooling2 (None, 24, 24, 64)        0         
_________________________________________________________________
dropout_6 (Dropout)          (None, 24, 24, 64)        0         
_________________________________________________________________
conv2d_5 (Conv2D)            (None, 24, 24, 128)       204928    
_________________________________________________________________
batch_normalization_7 (Batch (None, 24, 24, 128)       512       
_________________________________________________________________
activation_7 (Activation)    (None, 24, 24, 128)       0         
_________________________________________________________________
max_pooling2d_5 (MaxPooling2 (None, 12, 12, 128)       0         
_________________________________________________________________
dropout_7 (Dropout)          (None, 12, 12, 128)       0         
_________________________________________________________________
conv2d_6 (Conv2D)            (None, 12, 12, 512)       590336    
_________________________________________________________________
batch_normalization_8 (Batch (None, 12, 12, 512)       2048      
_________________________________________________________________
activation_8 (Activation)    (None, 12, 12, 512)       0         
_________________________________________________________________
max_pooling2d_6 (MaxPooling2 (None, 6, 6, 512)         0         
_________________________________________________________________
dropout_8 (Dropout)          (None, 6, 6, 512)         0         
_________________________________________________________________
conv2d_7 (Conv2D)            (None, 6, 6, 512)         2359808   
_________________________________________________________________
batch_normalization_9 (Batch (None, 6, 6, 512)         2048      
_________________________________________________________________
activation_9 (Activation)    (None, 6, 6, 512)         0         
_________________________________________________________________
max_pooling2d_7 (MaxPooling2 (None, 3, 3, 512)         0         
_________________________________________________________________
dropout_9 (Dropout)          (None, 3, 3, 512)         0         
_________________________________________________________________
flatten_1 (Flatten)          (None, 4608)              0         
_________________________________________________________________
dense_3 (Dense)              (None, 256)               1179904   
_________________________________________________________________
batch_normalization_10 (Batc (None, 256)               1024      
_________________________________________________________________
activation_10 (Activation)   (None, 256)               0         
_________________________________________________________________
dropout_10 (Dropout)         (None, 256)               0         
_________________________________________________________________
dense_4 (Dense)              (None, 512)               131584    
_________________________________________________________________
batch_normalization_11 (Batc (None, 512)               2048      
_________________________________________________________________
activation_11 (Activation)   (None, 512)               0         
_________________________________________________________________
dropout_11 (Dropout)         (None, 512)               0         
_________________________________________________________________
dense_5 (Dense)              (None, 7)                 3591      
=================================================================
Total params: 4,478,727
Trainable params: 4,474,759
Non-trainable params: 3,968
_________________________________________________________________


Обучить и оценить модель

epochs = 15
steps_per_epoch = train_generator.n//train_generator.batch_size
validation_steps= validation_generator.n//validation_generator.batch_size
checkpoint= ModelCheckpoint("model_weights.h5",monitor='val_accuracy',
                           save_weights_only= True,  
                mode='max',verbose=1)
reduce_lr = ReduceLROnPlateau(monitor='val_loss',factor=0.1,patience=2,min_lr=0.00001,model='auto')
callbacks=[PlotLossesTensorFlowKeras(),checkpoint, reduce_lr]
history = model.fit(
          x=train_generator,
          steps_per_epoch=steps_per_epoch,
          epochs =epochs,
          validation_data=validation_generator,
          validation_steps=validation_steps,
          callbacks = callbacks
)

Выход -

Log-loss (cost function):
training   (min:    1.032, max:    1.790, cur:    1.032)
validation (min:    1.041, max:    1.797, cur:    1.041)

accuracy:
training   (min:    0.315, max:    0.608, cur:    0.608)
validation (min:    0.327, max:    0.612, cur:    0.612)

Epoch 00015: saving model to model_weights.h5
448/448 [==============================] - 27s 61ms/step - loss: 1.0317 - accuracy: 0.6082 - val_loss: 1.0407 - val_accuracy: 0.6124


Построить модель как JSON Str

model_json=model.to_json()
with open("model_json","w") as json_file:
    json_file.write(model_json)

Создайте приложение Flask для прогнозирования выражения лица

Мы будем использовать классификатор open cv для автоматического обнаружения лиц на изображениях и рисования ограничивающих рамок для создания приложения и импорта модели выражения лица. OpenCV предоставляет метод обучения Cascade Classifier Training, который можно прочитать с помощью метода cv :: CascadeClassifier :: load. Обнаружение объектов с использованием метода каскадных классификаторов Хаара, предложенного Полом Виолой и Майклом Джонсом, представляет собой подход, основанный на машинном обучении, при котором каскадная функция обучается на большом количестве положительных и отрицательных изображений.

import cv2
from model import FacialExpressionModel
import numpy as np
facec = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
model = FacialExpressionModel("model.json", "model_weights.h5")
font = cv2.FONT_HERSHEY_SIMPLEX
class VideoCamera(object):
    def __init__(self):
        self.video = cv2.VideoCapture("path to video file")
def __del__(self):
        self.video.release()
# returns camera frames along with bounding boxes and predictions
    def get_frame(self):
        _, fr = self.video.read()
        gray_fr = cv2.cvtColor(fr, cv2.COLOR_BGR2GRAY)
        faces = facec.detectMultiScale(gray_fr, 1.3, 5)
for (x, y, w, h) in faces:
            fc = gray_fr[y:y+h, x:x+w]
roi = cv2.resize(fc, (48, 48))
            pred = model.predict_emotion(roi[np.newaxis, :, :, 
                   np.newaxis])
cv2.putText(fr, pred, (x, y), font, 1, (255, 255, 0), 2)
            cv2.rectangle(fr,(x,y),(x+w,y+h),(255,0,0),2)
_, jpeg = cv2.imencode('.jpg', fr)
        return jpeg.tobytes()


Создайте скрипт со списком выражений лица в виде файла model.py

tf.keras.models.model_from_json анализирует строку конфигурации модели JSON, которую мы создали выше, и возвращает экземпляр модели. Распознавание выражения лица - это метод классификации выражений лиц на изображениях лиц по различным категориям, таким как гнев, страх, удивление, печаль, счастье и т. Д.

from tensorflow.keras.models import model_from_json
import numpy as np
import tensorflow as tf
config.tf.compat.v1.ConfigProto()
config.gpu_options.per_process_gpu_memory_fraction =0.15
session = tf.compat.v1.Session(config=config)
class FacialExpressionModel(object):
EMOTIONS_LIST= ["Happy","Neutral","Sad","Surprise","Angry","Disgust","Fear"]
def __init__(self,model_json_file,model_weights_file):
        with open(model_json_file, "r") as json_file:
            loaded_model_json = json_file.read()
            self.loaded_model = model_from_json(loaded_model_json)
self.loaded_model.load_weights(model_weights_file)
        self.loaded_model._make_predict_function()
def predict_emotion(self,img):
        self.preds = self.loaded_model.predict(img)
        return FacialExpressionModel.EMOTIONS_LIST[np.argmax(self.preds)]

Создайте HTML-шаблон для приложения Flask

<html>
  <head>
     <title> Facial Expression Recognition </title>
  </head>
  <body>
     <img id="bg" width=800px height = 640px src="{{url_for('video_feed')}}">
  </body>
</html>


Запустите модель, чтобы распознать выражение лица

from flask import Flask, render_template, Response
from camera import VideoCamera
app = Flask(__name__)
@app.route('/')
def index():
    return render_template('index.html')
def gen(camera):
    while True:
        frame = camera.get_frame()
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')
@app.route('/video_feed')
def video_feed():
    return Response(gen(VideoCamera()),
                    mimetype='multipart/x-mixed-replace; boundary=frame')
if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)

Запускаем main.py и все.

Вы должны увидеть помеченное выражение лица для видео, которое вы использовали в своем коде.



Продолжайте учиться и кодировать;)

Хотите прочитать юмор программистов?









Рекомендуемые статьи -