毕业设计-人脸表情识别系统、人工智能
人臉表情識別系統
1. 前言
????在這個人工智能成為超級大熱門的時代,人臉表情識別已成為其中的一項研究熱點,而卷積神經網絡、深度信念網絡和多層感知器等相關算法在人臉面部表情識別領域的運用最為廣泛。面部的表情中包含了太多的信息,輕微的表情變化都會反映出人心理的變化,可想而知如果機器能敏銳地識別人臉中表達的情感該是多么令人興奮的事。
????學習和研究了挺久的深度學習,偶然看到IEEE上面一篇質量很高的文章,里面介紹的是利用深度神經網絡實現的面部表情識別,研讀下來讓我深受啟發。于是自己動手做了這個項目,如今SCI論文已投稿,這里特此將前期工作作個總結,希望能給類似工作的朋友帶來一點幫助。由于論文尚未公開,這里使用的是已有的模型——如今CNN的主流框架之mini_XCEPTION,該模型性能也已是不錯的了,論文中改進的更高性能模型尚不便給出,后面會分享給大家,敬請關注。
2. 表情識別數據集
????目前,現有的公開的人臉表情數據集比較少,并且數量級比較小。比較有名的廣泛用于人臉表情識別系統的數據集Extended Cohn-Kanada (CK+)是由P.Lucy收集的。CK+數據集包含123?個對象的327?個被標記的表情圖片序列,共分為正常、生氣、蔑視、厭惡、恐懼、開心和傷心七種表情。對于每一個圖片序列,只有最后一幀被提供了表情標簽,所以共有327?個圖像被標記。為了增加數據,我們把每個視頻序列的最后三幀圖像作為訓練樣本。這樣CK+數據總共被標記的有981?張圖片。這個數據庫是人臉表情識別中比較流行的一個數據庫,很多文章都會用到這個數據做測試,可通過下面的鏈接下載。
官網鏈接:The Extended Cohn-Kanade Dataset(CK+)
網盤鏈接:百度網盤下載(提取碼:8r15)
????Kaggle是Kaggle人臉表情分析比賽提供的一個數據集。該數據集含28709?張訓練樣本,3859?張驗證數據集和3859?張測試樣本,共35887?張包含生氣、厭惡、恐懼、高興、悲傷、驚訝和正常七種類別的圖像,圖像分辨率為48×48。該數據集中的圖像大都在平面和非平面上有旋轉,并且很多圖像都有手、頭發和圍巾等的遮擋物的遮擋。該數據庫是2013年Kaggle比賽的數據,由于這個數據庫大多是從網絡爬蟲下載的,存在一定的誤差性。這個數據庫的人為準確率是65%±5%。
官網鏈接:FER2013
網盤鏈接:百度網盤下載(提取碼:t7xj)
????由于FER2013數據集數據更加齊全,同時更加符合實際生活的場景,所以這里主要選取FER2013訓練和測試模型。為了防止網絡過快地過擬合,可以人為的做一些圖像變換,例如翻轉,旋轉,切割等。上述操作稱為數據增強。數據操作還有另一大好處是擴大數據庫的數據量,使得訓練的網絡魯棒性更強。下載數據集保存在fer2013的文件夾下,為了對數據集進行處理,采用如下代碼載入和進行圖片預處理:
import pandas as pd import cv2 import numpy as npdataset_path = 'fer2013/fer2013/fer2013.csv' # 文件保存位置 image_size=(48,48) # 圖片大小# 載入數據 def load_fer2013():data = pd.read_csv(dataset_path)pixels = data['pixels'].tolist()width, height = 48, 48faces = []for pixel_sequence in pixels:face = [int(pixel) for pixel in pixel_sequence.split(' ')]face = np.asarray(face).reshape(width, height)face = cv2.resize(face.astype('uint8'),image_size)faces.append(face.astype('float32'))faces = np.asarray(faces)faces = np.expand_dims(faces, -1)emotions = pd.get_dummies(data['emotion']).as_matrix()return faces, emotions# 將數據歸一化 def preprocess_input(x, v2=True):x = x.astype('float32')x = x / 255.0if v2:x = x - 0.5x = x * 2.0return x載入數據后將數據集劃分為訓練集和測試集,在程序中調用上面的函數代碼如下:
from load_and_process import load_fer2013 from load_and_process import preprocess_input from sklearn.model_selection import train_test_split# 載入數據集 faces, emotions = load_fer2013() faces = preprocess_input(faces) num_samples, num_classes = emotions.shape# 劃分訓練、測試集 xtrain, xtest,ytrain,ytest = train_test_split(faces, emotions,test_size=0.2,shuffle=True)3. 搭建表情識別的模型
????接下來就是搭建表情識別的模型了,這里用到的是CNN的主流框架之mini_XCEPTION。XCEPTION是Google繼Inception后提出的對Inception v3的另一種改進,主要是采用深度可分離的卷積(depthwise separable convolution)來替換原來Inception v3中的卷積操作。XCEPTION的網絡結構在ImageNet數據集(Inception v3的設計解決目標)上略優于Inception v3,并且在包含3.5億個圖像甚至更大的圖像分類數據集上明顯優于Inception v3,而兩個結構保持了相同數目的參數,性能增益來自于更加有效地使用模型參數,詳細可參考論文:Xception: Deep Learning with Depthwise Separable Convolutions,論文Real-time Convolutional Neural Networks for Emotion and Gender Classification等。
????既然這樣的網絡能獲得更好結果又是主流,那當然有必要作為對比算法實現以下了,這里博主模型這部分的代碼引用了GitHub:https://github.com/oarriaga/face_classification中的模型(其他地方也能找到這個模型的類似代碼),模型框圖如上圖所示,其代碼如下:
def mini_XCEPTION(input_shape, num_classes, l2_regularization=0.01):regularization = l2(l2_regularization)# baseimg_input = Input(input_shape)x = Conv2D(8, (3, 3), strides=(1, 1), kernel_regularizer=regularization,use_bias=False)(img_input)x = BatchNormalization()(x)x = Activation('relu')(x)x = Conv2D(8, (3, 3), strides=(1, 1), kernel_regularizer=regularization,use_bias=False)(x)x = BatchNormalization()(x)x = Activation('relu')(x)# module 1residual = Conv2D(16, (1, 1), strides=(2, 2),padding='same', use_bias=False)(x)residual = BatchNormalization()(residual)x = SeparableConv2D(16, (3, 3), padding='same',kernel_regularizer=regularization,use_bias=False)(x)x = BatchNormalization()(x)x = Activation('relu')(x)x = SeparableConv2D(16, (3, 3), padding='same',kernel_regularizer=regularization,use_bias=False)(x)x = BatchNormalization()(x)x = MaxPooling2D((3, 3), strides=(2, 2), padding='same')(x)x = layers.add([x, residual])# module 2residual = Conv2D(32, (1, 1), strides=(2, 2),padding='same', use_bias=False)(x)residual = BatchNormalization()(residual)x = SeparableConv2D(32, (3, 3), padding='same',kernel_regularizer=regularization,use_bias=False)(x)x = BatchNormalization()(x)x = Activation('relu')(x)x = SeparableConv2D(32, (3, 3), padding='same',kernel_regularizer=regularization,use_bias=False)(x)x = BatchNormalization()(x)x = MaxPooling2D((3, 3), strides=(2, 2), padding='same')(x)x = layers.add([x, residual])# module 3residual = Conv2D(64, (1, 1), strides=(2, 2),padding='same', use_bias=False)(x)residual = BatchNormalization()(residual)x = SeparableConv2D(64, (3, 3), padding='same',kernel_regularizer=regularization,use_bias=False)(x)x = BatchNormalization()(x)x = Activation('relu')(x)x = SeparableConv2D(64, (3, 3), padding='same',kernel_regularizer=regularization,use_bias=False)(x)x = BatchNormalization()(x)x = MaxPooling2D((3, 3), strides=(2, 2), padding='same')(x)x = layers.add([x, residual])# module 4residual = Conv2D(128, (1, 1), strides=(2, 2),padding='same', use_bias=False)(x)residual = BatchNormalization()(residual)x = SeparableConv2D(128, (3, 3), padding='same',kernel_regularizer=regularization,use_bias=False)(x)x = BatchNormalization()(x)x = Activation('relu')(x)x = SeparableConv2D(128, (3, 3), padding='same',kernel_regularizer=regularization,use_bias=False)(x)x = BatchNormalization()(x)x = MaxPooling2D((3, 3), strides=(2, 2), padding='same')(x)x = layers.add([x, residual])x = Conv2D(num_classes, (3, 3),#kernel_regularizer=regularization,padding='same')(x)x = GlobalAveragePooling2D()(x)output = Activation('softmax',name='predictions')(x)model = Model(img_input, output)return model4. 數據增強的批量訓練
????神經網絡的訓練需要大量的數據,數據的量決定了網絡模型可以達到的高度,網絡模型盡量地逼近這個高度。然而對于人臉表情的數據來說,都只存在少量的數據Extended Cohn-Kanada (CK+)的數據量是遠遠不夠的,并且CK+多是比較夸張的數據。Kaggle Fer2013數據集也不過只有3萬多數據量,而且有很多遮擋、角度等外界影響因素。既然收集數據要花費很大的人力物力,那么我們就用技術解決這個問題,為避免重復開發首先還是看看有沒有寫好的庫。博主又通讀了遍Keras官方文檔,其中ImageDataGenerator的圖片生成器就可完成這一目標。
為了盡量利用我們有限的訓練數據,我們將通過一系列隨機變換堆數據進行提升,這樣我們的模型將看不到任何兩張完全相同的圖片,這有利于我們抑制過擬合,使得模型的泛化能力更好。在Keras中,這個步驟可以通過keras.preprocessing.image.ImageGenerator來實現,這個類使你可以:在訓練過程中,設置要施行的隨機變換通過.flow或.flow_from_directory(directory)方法實例化一個針對圖像batch的生成器,這些生成器可以被用作keras模型相關方法的輸入,如fit_generator,evaluate_generator和predict_generator。——Keras官方文檔
????ImageDataGenerator()是一個圖片生成器,同時也可以在batch中對數據進行增強,擴充數據集大小(比如進行旋轉,變形,歸一化等),增強模型的泛化能力。結合前面的模型和數據訓練部分的代碼如下:
""" Description: 訓練人臉表情識別程序 """from keras.callbacks import CSVLogger, ModelCheckpoint, EarlyStopping from keras.callbacks import ReduceLROnPlateau from keras.preprocessing.image import ImageDataGenerator from load_and_process import load_fer2013 from load_and_process import preprocess_input from models.cnn import mini_XCEPTION from sklearn.model_selection import train_test_split# 參數 batch_size = 32 num_epochs = 10000 input_shape = (48, 48, 1) validation_split = .2 verbose = 1 num_classes = 7 patience = 50 base_path = 'models/'# 構建模型 model = mini_XCEPTION(input_shape, num_classes) model.compile(optimizer='adam', # 優化器采用adamloss='categorical_crossentropy', # 多分類的對數損失函數metrics=['accuracy']) model.summary()# 定義回調函數 Callbacks 用于訓練過程 log_file_path = base_path + '_emotion_training.log' csv_logger = CSVLogger(log_file_path, append=False) early_stop = EarlyStopping('val_loss', patience=patience) reduce_lr = ReduceLROnPlateau('val_loss', factor=0.1,patience=int(patience/4),verbose=1) # 模型位置及命名 trained_models_path = base_path + '_mini_XCEPTION' model_names = trained_models_path + '.{epoch:02d}-{val_acc:.2f}.hdf5'# 定義模型權重位置、命名等 model_checkpoint = ModelCheckpoint(model_names,'val_loss', verbose=1,save_best_only=True) callbacks = [model_checkpoint, csv_logger, early_stop, reduce_lr]# 載入數據集 faces, emotions = load_fer2013() faces = preprocess_input(faces) num_samples, num_classes = emotions.shape# 劃分訓練、測試集 xtrain, xtest,ytrain,ytest = train_test_split(faces, emotions,test_size=0.2,shuffle=True)# 圖片產生器,在批量中對數據進行增強,擴充數據集大小 data_generator = ImageDataGenerator(featurewise_center=False,featurewise_std_normalization=False,rotation_range=10,width_shift_range=0.1,height_shift_range=0.1,zoom_range=.1,horizontal_flip=True)# 利用數據增強進行訓練 model.fit_generator(data_generator.flow(xtrain, ytrain, batch_size),steps_per_epoch=len(xtrain) / batch_size,epochs=num_epochs,verbose=1, callbacks=callbacks,validation_data=(xtest,ytest))5. 系統UI界面的實現
????上面的模型訓練好了,但對于我們來說它的作用就只是知道了其準確率還行,其實深度學習的目的最重要還是應用,是時候用上面的模型做點酷酷的東西了。可不可以用上面的模型識別下自己表達的情緒呢?不如做個系統調取攝像頭對實時畫面中的表情進行識別并顯示識別結果,既能可視化的檢測模型的實用性能,同時使得整個項目生動有趣激發自己的創造性,當你向別人介紹你的項目時也顯得高大上。這里采用PyQt5進行設計,首先看一下最后的效果圖,運行后的界面如下:
????設計功能:一、可選擇模型文件后基于該模型進行識別;二、打開攝像頭識別實時畫面中的人臉表情;三、選擇一張人臉圖片,對其中的表情進行識別。選擇一張圖片測試識別效果,如下圖所示:
本文轉載自思緒無限:人臉表情識別系統介紹——上篇(python實現,含UI界面及完整代碼)_思緒無限的博客-CSDN博客_人臉表情識別系統
感謝大家的支持。
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的毕业设计-人脸表情识别系统、人工智能的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: chatbot1_2 RNN简单实现
- 下一篇: 毕业设计-课程设计-Spring+Spr