当前位置:首页 > 安卓源码 > 技术博客 >

使用Keras和CNN进行自定义AI人脸识别

时间:2020-08-09 22:05 来源:互联网 作者:源码搜藏 浏览: 收藏 挑错 推荐 打印

在这里,我们将讨论CNN,然后设计一个并使用Keras在Python中实现它。 下载源8.4 KB 介绍 如果您看过《 少数派报告》 电影,您可能还记得汤姆克鲁斯(Tom Cruise)走进一家Gap商店的场景。 视网膜扫描仪读取他的眼睛,并为他播放定制的广告。 好吧,这是2020
在这里,我们将讨论CNN,然后设计一个并使用Keras在Python中实现它。

介绍

如果您看过《少数派报告》电影,您可能还记得汤姆·克鲁斯(Tom Cruise)走进一家Gap商店的场景。视网膜扫描仪读取他的眼睛,并为他播放定制的广告。好吧,这是2020年。我们不需要视网膜扫描仪,因为我们拥有人工智能(AI)和机器学习(ML)!

在本系列中,我们将向您展示如何使用深度学习进行面部识别,然后基于被识别的面部,使用神经网络语音合成(TTS)引擎播放自定义广告。欢迎您在CodeProject上浏览此处的代码,或下载.zip文件以在自己的计算机上浏览代码。

我们假定您熟悉AI / ML的基本概念,并且可以找到使用Python的方法。

在本文中,我们将讨论CNN,然后设计一个并使用Keras在Python中实现它。

什么是CNN?

CNN是一种神经网络(NN),通常用于图像分类任务(例如人脸识别)以及输入具有网格状拓扑的任何其他问题。在CNN中,并非每个节点都连接到下一层的所有节点。换句话说,它们不是完全连接的NN。这有助于防止完全连接的NN中出现过拟合问题,更不用说由NN中过多的连接导致的超慢收敛。

CNN的概念依赖于称为卷积的数学运算,这在数字信号处理领域非常普遍。卷积被定义为两个函数(第三个函数)的乘积,表示前两个函数之间的重叠量。在CNN区域,通过在图像中滑动滤镜(即内核)来实现卷积。

在人脸识别中,卷积操作使我们能够检测图像中的不同特征。不同的滤镜可以检测垂直和水平边缘,纹理,曲线和其他图像特征。这就是为什么任何CNN中的第一层都是卷积层的原因。

CNN中另一个常见的层是池化层。池化用于减小图像表示的大小,这意味着减少了参数数量,并最终减少了计算量。最常见的池化类型是“ max”,它使用滑动窗口(类似于卷积操作中的窗口)在每个位置从匹配的单元格组中获取最大值。最后,它根据收获的最大值构建图像的新表示形式。

最常见的CNN架构通常从卷积层开始,然后是激活层,然后是池化层,最后以传统的全连接网络(例如多层NN)结束。这种类型的将一层一层接一层的模型称为顺序模型。为什么最后要建立全连接网络?要学习变换图像中特征的非线性组合(在卷积和合并之后)。

设计CNN

这是我们将在CNN中实现的架构:

  • 输入层– NumPy数组(img_width,img_height,1);“ 1”,因为我们正在处理灰度图像;对于RGB图像,应该是(img_width,img_height,3)
  • Conv2D层– 32个滤镜,滤镜大小为3
  • 激活层–必须使用非线性函数进行学习,在这种情况下,该函数为ReLU
  • Conv2D层– 32个滤镜,滤镜大小为3,步幅为3
  • 使用ReLU功能的激活层
  • MaxPooling2D层–应用(2,2)合并窗口
  • 25%的DropOut层–通过从前一层中随机删除一些值(将它们设置为0)来防止过度拟合;又名稀释技术
  • Conv2D层– 64个滤镜,滤镜大小为3
  • 使用ReLU功能的激活层
  • Conv2D层– 64个滤镜,滤镜大小为3,步幅为3
  • 使用ReLU功能的激活层
  • MaxPooling2D层–应用(2,2)合并窗口
  • DropOut层,占25%
  • 展平层–转换要在下一层使用的数据
  • 致密层–代表完全连接的传统NN
  • 使用ReLU功能的激活层
  • DropOut层,占25%
  • 密集层,节点数与问题中的类数匹配–耶鲁数据集为15
  • 使用ReLU功能的激活层

上面的架构很常见;层参数已通过实验进行了微调。

实施CNN

现在,让我们在代码中实现我们的CNN架构-我们选择的一组图层。为了创建易于扩展的解决方案,我们将ML模型与一组抽象方法结合使用:

class MLModel(metaclass=abc.ABCMeta):

    def __init__(self, dataSet=None):
        if dataSet is not None:
            self.objects = dataSet.objects
            self.labels = dataSet.labels
            self.obj_validation = dataSet.obj_validation
            self.labels_validation = dataSet.labels_validation
            self.number_labels = dataSet.number_labels
            self.n_classes = dataSet.n_classes
        self.init_model()

    @abstractmethod
    def init_model(self):
        pass

    @abstractmethod
    def train(self):
        pass

    @abstractmethod
    def predict(self, object):
        pass

    @abstractmethod
    def evaluate(self):
        score = self.get_model().evaluate(self.obj_validation, self.labels_validation, verbose=0)
        print("%s: %.2f%%" % (self.get_model().metrics_names[1], score[1] * 100))

    @abstractmethod
    def get_model(self):
        pass

在我们的例子中,dataset是本系列上一篇文章中FaceDataSet描述的类的实例。在类,从中继承和实现其所有的抽象方法,是一个将包含我们的CNN架构。这里是:ConvolutionalModelMLModel

class ConvolutionalModel(MLModel):

    def __init__(self, dataSet=None):
        if dataSet is None:
            raise Exception("DataSet is required in this model")
        self.shape = numpy.array([constant.IMG_WIDTH, constant.IMG_HEIGHT, 1])
        super().__init__(dataSet)
        self.cnn.compile(loss=constant.LOSS_FUNCTION,
                         optimizer=Common.get_sgd_optimizer(),
                         metrics=[constant.METRIC_ACCURACY])

    def init_model(self):
        self.cnn = Sequential()

        self.cnn.add(Convolution2D(32, 3, padding=constant.PADDING_SAME, input_shape=self.shape))
        self.cnn.add(Activation(constant.RELU_ACTIVATION_FUNCTION))
        self.cnn.add(Convolution2D(32, 3, 3))
        self.cnn.add(Activation(constant.RELU_ACTIVATION_FUNCTION))
        self.cnn.add(MaxPooling2D(pool_size=(2, 2)))
        self.cnn.add(Dropout(constant.DROP_OUT_O_25))

        self.cnn.add(Convolution2D(64, 3, padding=constant.PADDING_SAME))
        self.cnn.add(Activation(constant.RELU_ACTIVATION_FUNCTION))
        self.cnn.add(Convolution2D(64, 3, 3))
        self.cnn.add(Activation(constant.RELU_ACTIVATION_FUNCTION))
        self.cnn.add(MaxPooling2D(pool_size=(2, 2)))
        self.cnn.add(Dropout(constant.DROP_OUT_O_25))

        self.cnn.add(Flatten())
        self.cnn.add(Dense(constant.NUMBER_FULLY_CONNECTED))
        self.cnn.add(Activation(constant.RELU_ACTIVATION_FUNCTION))
        self.cnn.add(Dropout(constant.DROP_OUT_0_50))
        self.cnn.add(Dense(self.n_classes))
        self.cnn.add(Activation(constant.SOFTMAX_ACTIVATION_FUNCTION))
        self.cnn.summary()

    def train(self, n_epochs=20, batch=32):
        self.cnn.fit(self.objects, self.labels,
                       batch_size=batch,
                       epochs=n_epochs, shuffle=True)

    def get_model(self):
        return self.cnn

    def predict(self, image):
        image = Common.to_float(image)
        result = self.cnn.predict(image)
        print(result)

    def evaluate(self):
       super(ConvolutionalModel, self).evaluate()

在构造函数中,我们设置self.shape变量,该变量定义输入层的形状。在我们的情况下,对于耶鲁数据集,图像高度为320像素,宽度为243像素,self.shape =(320,243,1)。

然后super(),我们调用从父构造函数获取所有与数据集相关的变量集,并调用init_model()初始化模型的方法。

最后,我们调用该compile方法,该方法配置用于训练的模型并设置要在loss参数中使用的目标函数。在训练过程中,目标功能得到了优化(最小化或最大化)。该accuracy参数定义在训练中评估模型的度量。该optimizer参数定义权重的计算方式。最常见的优化器是“梯度下降”。

我们的CNN模型定义为顺序的,并根据体系结构要求添加了所有层。该train()方法使用表示层排列fit的sequential类的方法来训练CNN。此方法接收训练CNN的数据作为输入,该数据的正确分类以及一些可选参数,例如要运行的时期数。

训练CNN

现在,代码已经准备就绪,可以开始训练我们的CNN了。让我们实例化ConvolutionalModel该类,在耶鲁大学数据集上进行训练,然后调用评估方法。

cnn = ConvolutionalModel(dataSet)
cnn.train(n_epochs=50)
cnn.evaluate()

在进行了50个时期的训练后,我们在测试图像上的准确性达到了近85%。

 

这意味着我们的CNN现在将以85%的概率识别出数据集中15个主题中的每个主题。简短的练习还不错吧?

现在,我们已经训练了CNN,如果我们想预测新的传入数据(意味着来自图像的新面孔),则可以使用之前详细介绍的ConvolutionalModel类中的predict(image)方法来进行。如何运作?该呼叫看起来像下一个呼叫,它应符合某些假设。

cnn.predict(np.expand_dims(image, axis=0))

首先,输入图像必须具有与先前训练的CNN输入层相同的尺寸或形状。其次,在predict()我们归一化数据的方法中,它应该是相同类型的输入,即像素值矩阵,因此不需要提供归一化的图像像素矩阵。第三,我们可能需要为输入的面部图像添加一个维度,因为在经过训练的CNN中,我们考虑了数据集中样本数量的第4个维度。这可以使用expand_dims()numpy方法来实现。第四,假定将提供面部图像,在较大图片的情况下,先前文章中提供的面部检测方法可证明是有用的。

 

最后,该predict()方法的输出可以在上图中看到。此方法将输出脸部属于每个可能类别或个人的概率(对于训练后的数据集为15)。在这种情况下,我们可以看到类别4的可能性最高,这正是输入的面部图像所指的类别或人物。


使用Keras和CNN进行自定义AI人脸识别 转载https://www.codesocang.com/appboke/48992.html

技术博客阅读排行

最新文章