目录

前言

一、本文采用的数据库

二、数据读取部分

1.训练部分

         2.预测部分

3.训练部分数据读取

三、hog特征提取部分

1.训练部分的hog特征提取

2.预测部分单张图像的hog特征提取

四、各类算法(SVM,KNN,随机森林等)

1.训练部分(训练集和测试集的划分)

2.各类算法:

(1)SVM支持向量机

(2) KNN

(3)随机森林

(4)朴素贝叶斯

(5)逻辑回归分类

(6)决策树

五、准确度,召回率以及混淆矩阵

六、表情预测

七:完整代码

八:参考

总结



前言

(本文为本人初入机器学习领域第一项实践,代码和文章若存在纰漏,敬请指正。)

主要应用python中部分库,实现了jaffe表情库的表情分类

一、本文采用的数据库

本文采用的数据库为The Japanese Female Facial Expression (JAFFE) Database,该数据库共含有213张图像,10位日本女性在实验环境下根据指示做出7种表情,再由照相机拍摄获取人脸表情图像,这7种表情分别是: sad, happy, angry, disgust, surprise, fear, neutral. 每人每种表情大概有3,4张样图。

百度云链接:百度网盘 请输入提取码

提取码:ixtu

二、数据读取部分

本文将数据集分为用来构建模型的训练部分和预测部分

1.训练部分

训练部分已提前做好分类,如下图所示

2.预测部分

预测部分为乱序的图像,方便后面模型训练出来后用作预测,如下图所示:

3.训练部分数据读取

def read_data(label2id):       #label2id为定义的标签
    X = []
    Y = []
    path =r'F:\python_task1\jaffe_training\traning_set'
    for label in os.listdir(path):                 #os.listdir用于返回指定的文件夹包含的文件或文件夹的名字的列表,此处遍历每个文件夹
        for img_file in os.listdir(os.path.join(path, label)):             #遍历每个表情文件夹下的图像
            image = cv2.imread(os.path.join(path, label, img_file))        #读取图像
            result = image/255.0                                           #图像归一化
            cv2.waitKey(0)
            cv2.destroyAllWindows()
            X.append(result)                                    #将读取到的所有图像的矩阵形式拼接在一起
            Y.append(label2id[label])                          #将读取到的所有图像的标签拼接在一起
    return X, Y                                               #返回的X,Y分别是图像的矩阵表达和图像的标签

label2id = {'angry':0, 'disgust':1, 'fear': 2,'happy':3,'neutral':4,'sad':5,'surprise':6}
X, Y = read_data(label2id)

三、hog特征提取部分

因为Jaffe数据集里的所有图像都是灰度化的像素尺度相同的256×256的图像,故不需要做resize处理,相关参数可见hog特征提取的其他推荐文章

1.训练部分的hog特征提取

def extract_hog_features(X):
    image_descriptors = []
    for i in range(len(X)):     #此处的X为之前训练部分所有图像的矩阵形式拼接而来,所以len(X)实为X中矩阵的个数,即训练部分图像的个数
        print(i)               #方便了解程序进程
        fd, _ = hog(X[i], orientations=9, pixels_per_cell=(16, 16), cells_per_block=(16, 16),
                            block_norm='L2-Hys', visualize=True)                 #此处的参数细节详见其他文章
        image_descriptors.append(fd)                                            #拼接得到所有图像的hog特征
    return image_descriptors        #返回的是训练部分所有图像的hog特征

2.预测部分单张图像的hog特征提取

def extract_hog_features_single(X):
    image_descriptors_single = []
    print(len(X))                #此处X为一张单一图像的矩阵
    fd, _ = hog(X, orientations=9, pixels_per_cell=(16, 16), cells_per_block=(16, 16),
                            block_norm='L2-Hys', visualize=True)
    image_descriptors_single.append(fd)
    return image_descriptors_single

四、各类算法(SVM,KNN,随机森林等)

1.训练部分(训练集和测试集的划分)

将训练部分按照3:1的比例划分为训练集和测试集。

X_features = extract_hog_features(X)
X_train, X_test, Y_train, Y_test = train_test_split(X_features, Y, test_size=0.25, random_state=42)

2.各类算法:

因为python的sklearn库已经具备很多分类算法,所以大家伙儿只需要引用并根据自己的数据库调参即可

(1)SVM支持向量机

该算法有多个核函数,可自行选择,本数据集调参后使用rbf高斯核函数其精准度最高

#svm算法
#svm = sklearn.svm.SVC(C = 10, kernel='linear') # acc = 0.9
svm =sklearn.svm.SVC(C=2, kernel='rbf', gamma=10, decision_function_shape='ovr')      #acc=0.9534
svm.fit(X_train, Y_train)
Y_predict = svm.predict(X_test)

(2) KNN

#knn算法
knn = KNeighborsClassifier(n_neighbors=1)     #0.93
knn.fit(X_train,Y_train)
print(knn)
print('测试数据集得分:{:.2f}'.format(knn.score(X_test,Y_test)))
Y_predict = knn.predict(X_test)

(3)随机森林

#随机森林    0.87
Forest = RandomForestClassifier(n_estimators=180,random_state=0)
Forest.fit(X_train, Y_train)
Y_predict = Forest.predict(X_test)

(4)朴素贝叶斯

#朴素贝叶斯分类   0.67+
mlt=GaussianNB()
mlt.fit(X_train, Y_train)
Y_predict = mlt.predict(X_test)

(5)逻辑回归分类

#逻辑回归分类  0.488
logistic = LogisticRegression()
logistic.fit(X_train, Y_train)
Y_predict = logistic.predict(X_test)

(6)决策树

#决策树算法   0.3+
tree_D = DecisionTreeClassifier()
tree_D.fit(X_train, Y_train)
Y_predict = tree_D.predict(X_test)

五、准确度,召回率以及混淆矩阵

acc = accuracy_score(Y_test, Y_predict)
precision = precision_score(Y_test, Y_predict, average='macro')
recall = recall_score(Y_test, Y_predict, average='macro')
cm = confusion_matrix(Y_test, Y_predict)
print(cm)
print('Acc: ', acc)
print('Precision: ', precision)
print('Recall: ', recall)

xtick=['angry','disgust','fear','happy','neutral','sad','surprise']
ytick=xtick

f, ax= plt.subplots(figsize = (7, 5))
ax.tick_params(axis='y',labelsize=15)
ax.tick_params(axis='x',labelsize=15)

seaborn.set(font_scale=1.2)
plt.rc('font',family='Times New Roman',size=15)

seaborn.heatmap(cm,fmt='g', cmap='Blues', annot=True, cbar=True,xticklabels=xtick, yticklabels=ytick, ax=ax)

plt.title('Confusion Matrix', fontsize='x-large')

plt.show()

采用随机森林算法得到的混淆矩阵以及精准度等数据:

混淆矩阵:

六、表情预测

在模型构建完成后,即可输入需要预测的表情图像进行处理,进而预测得到该表情的分类

#下面为同一文件夹下多张图片的表情识别
path=r'F:\python_task1\jaffe_training\prediction'
for image_file in os.listdir(path):
    image = cv2.imread(os.path.join(path,image_file))
    result = image/255.0
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    X_Single = extract_hog_features_single(result)
    predict=Forest.predict(X_Single)         #可以在这里选择分类器的类别
    if predict==0:                    #奈何本人刚开始学Python,功力有限只能if大法
        print('angry')
    elif predict ==1:
        print('disgust')
    elif predict ==2:
        print('fear')
    elif predict == 3:
        print('happy')
    elif predict==4:
        print('neutral')
    elif predict==5:
        print('sad')
    elif predict==6:
        print('surprise')

需要预测的图像集合,即预测部分的所有图像

分类结果:

七:完整代码

import os
import numpy as np
import cv2
import matplotlib.pyplot as plt
import pickle
import sklearn
import seaborn

from skimage.feature import hog
from sklearn.tree import DecisionTreeClassifier
from sklearn.cluster import KMeans
from scipy.spatial.distance import cdist
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score, precision_score, recall_score, confusion_matrix
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from skimage import io
from PIL import Image
from sklearn.naive_bayes import GaussianNB


def extract_hog_features(X):
    image_descriptors = []
    for i in range(len(X)):     #此处的X为之前训练部分所有图像的矩阵形式拼接而来,所以len(X)实为X中矩阵的个数,即训练部分图像的个数
        print(i)               #方便了解程序进程
        fd, _ = hog(X[i], orientations=9, pixels_per_cell=(16, 16), cells_per_block=(16, 16),
                            block_norm='L2-Hys', visualize=True)                 #此处的参数细节详见其他文章
        image_descriptors.append(fd)                                            #拼接得到所有图像的hog特征
    return image_descriptors        #返回的是训练部分所有图像的hog特征

def extract_hog_features_single(X):
    image_descriptors_single = []
    fd, _ = hog(X, orientations=9, pixels_per_cell=(16, 16), cells_per_block=(16, 16),
                            block_norm='L2-Hys', visualize=True)
    image_descriptors_single.append(fd)
    return image_descriptors_single



def read_data(label2id):       #label2id为定义的标签
    X = []
    Y = []
    path =r'F:\python_task1\jaffe_training\traning_set'
    for label in os.listdir(path):                 #os.listdir用于返回指定的文件夹包含的文件或文件夹的名字的列表,此处遍历每个文件夹
        for img_file in os.listdir(os.path.join(path, label)):             #遍历每个表情文件夹下的图像
            image = cv2.imread(os.path.join(path, label, img_file))        #读取图像
            result = image/255.0                                           #图像归一化
            cv2.waitKey(0)
            cv2.destroyAllWindows()
            X.append(result)                                    #将读取到的所有图像的矩阵形式拼接在一起
            Y.append(label2id[label])                          #将读取到的所有图像的标签拼接在一起
    return X, Y                                               #返回的X,Y分别是图像的矩阵表达和图像的标签


label2id = {'angry':0, 'disgust':1, 'fear': 2,'happy':3,'neutral':4,'sad':5,'surprise':6}
X, Y = read_data(label2id)
X_features = extract_hog_features(X)
X_train, X_test, Y_train, Y_test = train_test_split(X_features, Y, test_size=0.25, random_state=42)



'''
#svm算法
#svm = sklearn.svm.SVC(C = 10, kernel='linear') # acc = 0.9
svm =sklearn.svm.SVC(C=2, kernel='rbf', gamma=10, decision_function_shape='ovr')      #acc=0.9534
svm.fit(X_train, Y_train)
Y_predict = svm.predict(X_test)
'''

'''
#knn算法
knn = KNeighborsClassifier(n_neighbors=1)     #0.93
knn.fit(X_train,Y_train)
print(knn)
print('测试数据集得分:{:.2f}'.format(knn.score(X_test,Y_test)))
Y_predict = knn.predict(X_test)
'''

'''
#决策树算法   0.3+
tree_D = DecisionTreeClassifier()
tree_D.fit(X_train, Y_train)
Y_predict = tree_D.predict(X_test)
'''
'''
#朴素贝叶斯分类   0.67+
mlt=GaussianNB()
mlt.fit(X_train, Y_train)
Y_predict = mlt.predict(X_test)
'''
'''
#逻辑回归分类  0.488
logistic = LogisticRegression()
logistic.fit(X_train, Y_train)
Y_predict = logistic.predict(X_test)
'''

#随机森林    0.87
Forest = RandomForestClassifier(n_estimators=180,random_state=0)
Forest.fit(X_train, Y_train)
Y_predict = Forest.predict(X_test)

acc = accuracy_score(Y_test, Y_predict)
precision = precision_score(Y_test, Y_predict, average='macro')
recall = recall_score(Y_test, Y_predict, average='macro')
cm = confusion_matrix(Y_test, Y_predict)
print(cm)
print('Acc: ', acc)
print('Precision: ', precision)
print('Recall: ', recall)

xtick=['angry','disgust','fear','happy','neutral','sad','surprise']
ytick=xtick

f, ax= plt.subplots(figsize = (7, 5))
ax.tick_params(axis='y',labelsize=15)
ax.tick_params(axis='x',labelsize=15)

seaborn.set(font_scale=1.2)
plt.rc('font',family='Times New Roman',size=15)

seaborn.heatmap(cm,fmt='g', cmap='Blues', annot=True, cbar=True,xticklabels=xtick, yticklabels=ytick, ax=ax)

plt.title('Confusion Matrix', fontsize='x-large')

plt.show()




#下面为同一文件夹下多张图片的表情识别
#labelid2 = {0:'angry',1: 'disgust',2: 'fear',3:'happy',4:'neutral',5:'sad',6:'surprise'}
path=r'F:\python_task1\jaffe_training\prediction'
i = 1
for image_file in os.listdir(path):
    image = cv2.imread(os.path.join(path,image_file))
    result = image/255.0
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    X_Single = extract_hog_features_single(result)
    predict=Forest.predict(X_Single)         #可以在这里选择分类器的类别
    print(i)
    i+=1
    if predict==0:
        print('angry')
    elif predict ==1:
        print('disgust')
    elif predict ==2:
        print('fear')
    elif predict == 3:
        print('happy')
    elif predict==4:
        print('neutral')
    elif predict==5:
        print('sad')
    elif predict==6:
        print('surprise')

八:参考

特征提取-----HOG

KNN参考

SVM参考


总结

若有错误,敬请指正

分类好的训练集测试集:

链接:https://pan.baidu.com/s/1U7BPG_qFntgA1sgNw1P35Q 
提取码:6qcb

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐