新建apn是怎么建的,新建apn文件夹

  

     

  

  什么是人脸验证?这可以认为是一个分类问题,用匹配分数来验证人的身份。如果两幅图像属于同一个人,那么它们应该有很高的匹配度;如果两幅图像属于两个不同的人,则匹配度应该较低。   

  

  你可能想到的第一件事就是,为什么不把拍摄的图像和另一个像素一一对应起来呢?如果捕获图像的像素值和另一个图像的像素值之间的距离(均方或绝对值)很小,则它们应该对应于同一个人。但由于光线、位置或方向的轻微变化,图像中的像素值也会发生较大变化,所以这种方法的效果其实并不好。   

  

  那我们现在怎么办?这就是卷积神经网络(俗称CNN)发挥作用的地方。通过将每个图像嵌入到D维向量空间中,这种网络可以帮助我们更好地表示图像。然后评价图像嵌入的相似性。   

  

  解决问题的一些方法SVM:这里的想法是为训练集中的每个例子训练一个线性SVM分类器。深:这里把验证任务看成人脸识别的一个子问题(给每个人分配标签)。暹罗网:这是基于以下思路:个体内部的距离要比人与人之间的距离小得多。在研究暹罗网之前,我们先讨论一下暹罗网所基于的一个非常重要的概念。这是一次性学习。   

  

  “一击学习”是一个物体分类问题,主要出现在计算机视觉中。它试图从一个或几个训练样本中学习关于对象分类的信息。通常在深度学习中,我们需要大量的机器学习数据。我们获得的机器学习数据越多,机器学习模型就越好。但是在人脸验证的情况下,一个人是不可能得到上千张照片的。实际上,我们的大脑不需要几千个人的照片来识别一个人。   

  

  对于人脸验证任务,我们希望系统能够从一张/几张图像中判断一个人的身份。   

  

  如前所述,卷积神经网络(CNN)有助于图像的矢量化表示。但是卷积神经网络(CNN)确实需要用很多例子来训练。此外,机器学习数据集中每增加一个新用户的图像,都给机器学习模型的训练带来不便。那么,为什么不建立一个模型来学习两个不同人之间的距离呢?这正是暹罗网络要做的。   

  

     

  

  图像x(1)馈入卷积神经网络(CNN),由卷积层和全连接层组成。卷积层提供了一个特征空间,而附着于卷积层的全连通层在这个空间中学习一个函数(大多是非线性的)。我们最终得到的是一个特征向量(softmax激活没有添加到特征向量中,因为它在这个阶段不会用于分类)。图像x(2)被输入到卷积神经网络(CNN ),该网络与上述完全相同。在我们的例子中,我们将第三个图像x(3)提供给同一个CNN。   

  

  我们选择x(1)作为锚图像,x(2)作为正图像,x(3)作为负图像。主播和正面形象属于同一个人,负面形象是另一个人。因此,我们的目标是使正面形象与主播的距离最小化,同时使主播与负面形象的距离最大化。   

  

     

  

  这个目标可以写成:   

  

     

  

  我们可以添加一个超级参数。   

  

     

  

  这里,A=x(1),P=x(2),N=x(3)   

  

  现在,我们如何把它构造成损失函数。   

  

     

  

  这就是所谓的三重损失函数。我们可以看到,这个损失函数可以保证max函数中的第一项不超过0。   

  

  Python实现了创建数据   

  

  这是用于创建机器学习数据集的Python代码。它使用一种预先训练好的分类器,称为哈尔正面人脸分类器,以级联方式识别人脸。下面的代码存储了20张由网络摄像头拍摄的人脸图像,并将它们存储在一个文件夹中。   

  

  导入osimport cv2#此函数可在注册用户定义create_dataset()期间使用: #包含预训练分类器的文件Haar _ file=' Haar scade _ front face _ default。XML ' #所有人脸数据都将出现在此文件夹中   

dataset = './dataset' if not os.path.exists(dataset): os.mkdir(dataset) sub_data = input("Enter your username: ") # Use the username as path name path = os.path.join(dataset, sub_data) # Add a verfication for this step if not os.path.exists(path): os.mkdir(path) # Image to be resized to this shape (width, height) = (224, 224) # Make the cascade classifier object face_cascade = cv2.CascadeClassifier(haar_file) webcam = cv2.VideoCapture(0) # The program loops until it has 30 images of the face. count = 0 while count < 20: # Read from the webcam (_, im) = webcam.read() # Convert to grayscale gray = cv2.cvtColor(im, cv2.COLOR_BGR2RGB) # Detect the face faces = face_cascade.detectMultiScale(gray, 1.3, 4) face_resize = None for (x, y, w, h) in faces: # The classifier seemed to scrap the chin and hair. Adjustments made to accomodate those. face = im face_resize = cv2.resize(face, (width, height)) cv2.imwrite('% s/% s.png' % (path, count), face_resize) count += 1 cv2.imshow('OpenCV', im) key = cv2.waitKey(100) if key == 27: break

  

创建模型并进行训练

  

创建数据集时,您可以看到我在现有图像上填充了一些值(此处宽度为22,高度为12)。之所以如此,是因为使用了在ImageNet数据集上预训练的VGG16模型,该神经网络模型期望输入图像的尺寸为(224、224、3),而我们使用的数据集的每个图像都为(200、180、3)。

  

对于每个人(由数据集文件夹内的文件夹标识的人),我们存储5个(A,P,N)的triplets。然后对它们进行训练,该模型本身包含三个VGG16模型,并由一个实现三重损失函数的Lambda层连接。

  

# Importing the required modulesfrom keras import backend as K, modelsfrom keras.models import *from keras.layers import *from keras.layers.normalization import BatchNormalizationfrom keras.applications import VGG16from keras.regularizers import l2from keras.activations import reluimport osimport os.path import join as join_import numpy as npfrom PIL import Image# Setting up the datasetSET_DIR = 'dataset'NUM_CLASSES = len(os.listdir('dataset'))# The shape which VGG19 accepts as input and thus each image is resized toimage_shape = (224, 224, 3)# NUM_EXAMPLES is the number of (A,P,N) triplets chosen for the same class (N belongs to a different class of course)NUM_EXAMPLES = 5# Triplets list will contain anchor(A), positive(P) and negative(N) triplets.triplets = <>A = P = N = <># creating anchor, positive, negative tripletsfor _ in range(NUM_EXAMPLES): for direc in os.listdir(SET_DIR): dir_path = SET_DIR + direc dir_contents = os.listdir(dir_path) length = len(dir_contents) anchor = np.asarray(Image.open(join_(dir_path, dir_contents)))/255 # anchor.shape = (200, 180, 3) # Padding with zeros for each channel in RGB anchor = np.array().T positive = np.asarray(Image.open(join_(dir_path, dir_contents)))/255 positive = np.array().T neg_dir = os.listdir(SET_DIR) while neg_dir == direc: neg_dir = os.listdir(SET_DIR) length_negative = len(os.listdir(SET_DIR + neg_dir)) negative = np.asarray(Image.open( join_(SET_DIR + neg_dir, os.listdir(SET_DIR + neg_dir))))/255 negative = np.array().T # append triplet triplets.append() A.append(anchor) P.append(positive) N.append(negative)def triplet_function(vects, alpha=0.2): x, y, z = vects sum_square_xy = K.sum(K.square(x - y), axis=1, keepdims=True) sum_square_xz = K.sum(K.square(x - z), axis=1, keepdims=True) return K.sum(K.maximum(sum_square_xy - sum_square_xz + alpha, 0), axis=0)# Using the VGG16 model defined in keras.applicationsdef VGG(): image_input = Input(shape=(224, 224, 3)) model = VGG16(input_tensor=image_input, weights='imagenet', include_top=True) model.layers<-1>.activation = relu x_out = Dense(64)(model.layers<-1>.output) new_model = Model(inputs=image_input, outputs=x_out) return new_modeldef get_model(): anchor = Input(shape=image_shape, name='anchor') positive = Input(shape=image_shape, name='positive') negative = Input(shape=image_shape, name='negative') # Passing each image through the VGG model anchor_encoding = VGG()(anchor) positive_encoding = VGG()(positive) negative_encoding = VGG()(negative) # Incorporating the triplet loss in the SimVecLayer SimVecLayer = Lambda(triplet_function, output_shape=(1,)) sim_APN = SimVecLayer() return Model(inputs=, outputs=sim_APN)model = get_model()# Compile the model with a loss and optimizermodel.compile(loss='mean_squared_error', optimizer='adam', metrics=<'mae'>) model.summary()from IPython.display import SVGfrom keras.utils.vis_utils import model_to_dotSVG(model_to_dot(model).create(prog='dot', format='svg'))# Train the model (done over the intel cloud) model.fit(x = , y = np.zeros((len(triplets),1)), epochs=100, verbose=1, batch_size=64, validation_split=0.3, callbacks=)model.save('model.h5')

  

  

使用模型进行验证

  

接收图像img(使用网络摄像头捕获的人的图像)的detect_face函数查找面部并将其裁剪。用验证如下:

  

a)我们在数据集文件夹中找到命名的文件夹。我们从该文件夹中选择一个图像。

  

b)我们随机选择另外三个文件夹,并从每个文件夹中选择一个图像。这些将作为negative images。

  

c)我们找到每个图像的编码,由detect_face返回,一个来自步骤a),三个来自步骤b)。

  

d)我们求出步骤a)和步骤b中每个图像编码的均方误差。

  

e)如果从步骤b)获得的任何图像的误差小于从步骤a)获得的图像的误差,我们说该人已被授权,否则就没有授权。

  

import osfrom os.path import join as jimport numpy as npimport matplotlib.pyplot as pltdef detect_face(img): # The file containing the pretrained classifier haar_file = 'haarcascade_frontalface_default.xml' # Image to be resized to this shape (width, height) = (224, 224) # Make the cascade classifier object face_cascade = cv2.CascadeClassifier(haar_file) # Convert to grayscale gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # Detect the face faces = face_cascade.detectMultiScale(gray, 1.3, 4) face_resize = None for (x, y, w, h) in faces: # The classifier seemed to scrap the chin and hair. Adjustments made to accomodate those. face = img face_resize = cv2.resize(face, (width, height)) return face_resizedef mean_squared_error(y_true, y_pred): return K.mean(K.square(y_true - y_pred))def verify_face(img, username): dir_ = 'dataset' NUM_CLASSES = len(os.listdir(dir_)) # The directory containing the user's photos pos_dir = username P = os.listdir(os.path.join(dir_, pos_dir))<-1> neg_dirs = <> #os.listdir(dir_) for i in range(3): neg_dir = os.listdir(dir_) while neg_dir == pos_dir or neg_dir in neg_dirs: neg_dir = os.listdir(dir_) neg_dirs.append(neg_dir) P = plt.imread(j(dir_, pos_dir, os.listdir(j(dir_, pos_dir)))<-1>) N1 = plt.imread(dir_ +'/'+ neg_dirs<0> +'/'+ os.listdir(dir_+'/'+neg_dirs<0>)<-1>) N2 = plt.imread(dir_ +'/'+ neg_dirs<1> +'/'+ os.listdir(dir_+'/'+neg_dirs<1>)<-1>) N3 = plt.imread(dir_ +'/'+ neg_dirs<2> +'/'+ os.listdir(dir_+'/'+neg_dirs<2>)<-1>) P = cv2.resize(P, (224,224)) N1 = cv2.resize(N1, (224,224)) N2 = cv2.resize(N2, (224,224)) N3 = cv2.resize(N3, (224,224)) A = np.reshape(img, (1,224,224,3)) P = np.reshape(P, (1,224,224,3)) N1, N2, N3 = > req_model = load_req_model('<path to model.h5>') enc_anc = req_model.predict(A) enc_pos = req_model.predict(P) enc_neg_1 = req_model.predict(N1) enc_neg_2 = req_model.predict(N2) enc_neg_3 = req_model.predict(N3) # Normalizing the encodings to avoid large values maxm = np.max(enc_anc) enc_anc = enc_anc/maxm enc_pos = enc_pos/maxm enc_neg_1, enc_neg_2, enc_neg_3 = > positive_loss = mean_squared_error(enc_anc, enc_pos).numpy() negative_losses = > flag = True for neg_loss in negative_losses: if positive_loss > neg_loss: flag = False return flag

  

相关文章