深度学习在面部识别中的应用

随着人工智能(AI)和机器学习(ML)技术的飞速发展,不再需要复杂的视网膜扫描仪来实现个性化广告播放。2020年,可以通过深度学习来实现面部识别,并利用神经网络文本到语音(TTS)引擎播放定制广告。本文将介绍如何使用深度学习进行面部识别,并基于识别的面部播放定制广告。

获取数据集

准备解析器

数据集解析器将包含在两个类中——一个抽象的、更通用的类,以及一个处理选定数据集特定细节的类。让来看一下父类的构造函数。

class FaceDataSet(metaclass=abc.ABCMeta): def __init__(self, path, extension_list, n_classes): self.path = path self.ext_list = extension_list self.n_classes = n_classes self.objects = [] self.labels = [] self.obj_validation = [] self.labels_validation = [] self.number_labels = 0

构造函数的参数包括:

  • path: 包含数据集样本(图像)的文件夹路径
  • extension_list: 在path定义的文件夹中查找的文件扩展名(一个或多个)
  • n_classes: 将数据集分类的类别数量;对于耶鲁数据集,这将是15,因为这是数据集中的人数

还创建了以下类对象:

  • objects: 用于CNN训练的图像
  • labels: 对图像(objects)进行分类的标签(主题编号)
  • obj_validation: 用于在训练后验证CNN的图像子集
  • labels_validation: obj_validation列表的分类器(标签)
  • number_labels: 数据集中的标签总数

将在实例化FaceDataSet类后调用get_data()方法。

def get_data(self): img_path_list = os.listdir(self.path) self.objects, self.labels = self.fetch_img_path(img_path_list, self.path, vgg_img_processing) self.process_data(vgg_img_processing) self.print_dataSet()

该方法由两个主要调用组成:从定义的路径获取图像并对其进行处理。为了获取图像,遍历path定义的文件夹中的文件。然后使用SK-Image将这些文件作为灰度图像加载。这个调用返回一个包含图像中每个像素的NumPy数组。

def fetch_img_path(self, img_path_list, path, vgg_img_processing): images = [] labels = [] for img_path in img_path_list: if self.__check_ext(img_path): img_abs_path = os.path.abspath(os.path.join(path, img_path)) image = io.imread(img_abs_path, as_gray=True) label = self.process_label(img_path) images.append(image) labels.append(label) return images, labels

__check_ext()是FaceDataSet类中的一个抽象方法;其实现发生在YaleDataSet类中,在那里解析数据集中图像文件的名称。文件名格式为"subjectXX.*"。该方法从文件名中提取"XX"数字并将其分配给图像。

class YaleFaceDataSet(FaceDataSet): def __init__(self, path, ext_list, n_classes): super().__init__(path, ext_list, n_classes) def process_label(self, img_path): val = int(os.path.split(img_path)[1].split(".")[0].replace("subject", "")) - 1 if val not in self.labels: self.number_labels += 1 return val

最后,process_data()方法如下所示:

def split_training_set(self): return train_test_split(self.objects, self.labels, test_size=0.3, random_state=random.randint(0, 100)) def process_data(self, vgg_img_processing): self.objects, self.img_obj_validation, self.labels, self.img_labels_validation = \ self.split_training_set() self.labels = np_utils.to_categorical(self.labels, self.n_classes) self.labels_validation = np_utils.to_categorical(self.img_labels_validation, self.n_classes) self.objects = Common.reshape_transform_data(self.objects) self.obj_validation = Common.reshape_transform_data(self.img_obj_validation)

在这个方法中,将数据集分成两部分。第二部分包含用于验证训练结果的图像。使用Scikit-Learn中的train_test_split()方法,并将标签转换为分类变量。如果图像的分类为"2"(来自subject02),其分类变量将是[0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0]——一个15维向量(类别数量),在第2个分量处为1。

class Common: @staticmethod def reshape_transform_data(data): data = numpy.array(data) result = Common.reshape_data(data) return Common.to_float(result) @staticmethod def reshape_data(data): return data.reshape(data.shape[0], constant.IMG_WIDTH, constant.IMG_HEIGHT, 1) @staticmethod def to_float(value): return value.astype('float32')/255

reshape_transform_data()方法将数据重塑为适合灰度模式的形状。在图像处理中,彩色图像被视为3通道网格;换句话说,它们被分为3种颜色(RGB)。灰度图像只有一个通道。因此,最初是彩色图像需要在末尾用"1"重塑。

to_float()方法通过将每个像素值除以255(像素值在0到255之间),将整个像素矩阵转换为0-1空间,以获得更好的数值输入和更快的收敛。现在可以在main.py文件中设置数据集,它将作为应用程序的入口点。

ext_list = [ 'gif', 'centerlight', 'glasses', 'happy', 'sad', 'leflight', 'wink', 'noglasses', 'normal', 'sleepy', 'surprised', 'rightlight' ] n_classes = 15 # Set up dataSet dataSet = YaleFaceDataSet(constant.FACE_DATA_PATH, ext_list, n_classes)

分类数据集...

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485