基于 Keras 和 dlib 的人脸识别实践

2019-03-27 17:30:34 浏览数 (1)

这次的实践是基于很小的数据集,搭建的系统也比较粗糙,只是个toy implementation。主要用来练手和熟悉流程的。

1. 数据集准备

  • 安装 dlibpip install dlib会提示安装失败,只能从dlib官网 下载whl文件,再用pip install dlib-18.17.100-cp35-none-win_amd64.whl命令安装。
  • 利用dlib截取自己的图片和别人的图片 参考写个神经网络,让她认得我(๑•ᴗ•๑),参考里面的代码截取了200张自己的图片和200张别人的图片,截取的图片宽高为64*64.
  • 训练集和验证集划分
    • 训练集:分别取自己和别人前160张图片作为训练集
    • 验证集:分别取自己和别人后40张图片作为验证集

2. 数据预处理

  • 转换图片形状 将输入的图片的形状转换为符合(None, width, height, channels)的形状,None是为batch_size预留的参数。不这么做的话,后面应用Keras写代码就会报错,因为Keras的CNN需要一个4D阵列(或者说张量)作为输入。 以下代码参考udacity深度学习项目二,不妥删。
代码语言:javascript复制
from keras.preprocessing import image                  
from tqdm import tqdm   # tqdm是显示进度条的包

def path_to_tensor(img_path):
    # loads RGB image as PIL.Image.Image type
    img = image.load_img(img_path, target_size=(64, 64))
    # convert PIL.Image.Image type to 3D tensor with shape (64, 64, 3)
    x = image.img_to_array(img)
    # convert 3D tensor to 4D tensor with shape (1, 64, 64, 3) and return 4D tensor
    return np.expand_dims(x, axis=0)

def paths_to_tensor(img_paths):
    list_of_tensors = [path_to_tensor(img_path) for img_path in tqdm(img_paths)]
    return np.vstack(list_of_tensors)
  • 添加标签 给训练集,验证集分别添加标签,0为自己的脸,1为别人的脸。
代码语言:javascript复制
from PIL import ImageFile                                      
ImageFile.LOAD_TRUNCATED_IMAGES = True  
  
# load the train files 
train_files = np.array(glob('faces/train/*/*'))
# set my face label is 0, the other face labels is 1
train_labels = np.array([0] * int(320/ 2)   [1] *int(320/2)) 

# load the validation files 
valid_files = np.array(glob('faces/validation/*/*'))
# set my face label is 0, the other face labels is 1
valid_labels = np.array([0] * int(80/ 2)   [1] *int(80/2)) 
## load the test files
#test_files = np.array(glob('faces/test/*/*'))
#test_labels = np.array([0] * int(8/ 2)   [1] *int(8/2)) 

# pre-process the data for Keras
train_data = paths_to_tensor(train_files).astype('float32')/64
valid_data = paths_to_tensor(valid_files).astype('float32')/64
#test_data = paths_to_tensor(test_files).astype('float32')/64

3. 搭建并训练CNN模型

代码语言:javascript复制
from keras.models import Sequential
from keras.layers import Dropout, Flatten, Dense,  Conv2D, MaxPooling2D

# bulid the CNN model 
model = Sequential()
model.add(Conv2D(filters=16, kernel_size=2, padding='same', activation='relu', input_shape=input_shape))
model.add(MaxPooling2D(pool_size=2))
model.add(Conv2D(filters=64, kernel_size=2, padding='same', activation='relu'))
model.add(MaxPooling2D(pool_size=2))
model.add(Flatten())
model.add(Dropout(0.5))
model.add(Dense(100, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))
model.summary()
    
# compile the model 
model.compile(optimizer='adam',
                        loss='binary_crossentropy', metrics=['accuracy'])
    
# fit the model 
model.fit(train_data, train_labels,
                 epochs=10,
                 batch_size=320,
                 validation_data=(valid_data, valid_labels))

训练结果:

4. 测试模型

  • 建立face_predict()用于测试
代码语言:javascript复制
def face_predict(img_path):  
   
    image = path_to_tensor(img_path)
    
    # 给出输入属于各个类别的概率,这里是二元分类,则该函数会给出输入图像属于0和1的概率各为多少  
   # result = model.predict(image)  
   # print('result:', result)  
  
    # 给出分类预测:0或者1  
    result = model.predict_classes(image)  
    print('result:', result)  
    # 返回分类预测结果
    if result == 0:
        return "Hi,cao!"
    else:
        return "Stranger !"
  • 测试结果:
代码语言:javascript复制
In [184]: 
images = np.array(glob('E:/faces/test/*/*'))
face_predict(images[2])  # 测试自己的图片

result: [[0]]
Out[184]:
'Hi,cao!'


In [185]:
face_predict(images[5])  # 测试别人的图片

result: [[1]]
Out[185]:
'Stranger !'

0 人点赞