人脸识别(2)

来源:互联网 发布:聚合数据左磊简历 编辑:程序博客网 时间:2024/06/10 01:42

facenet训练代码解析

之前看过facenet的测试代码,还比较简单,原理是将pairs.txt文件中每一对要比较的图片转化为embedding向量(许多图片就得到矩阵),计算得到它们的差值矩阵diff,再平方得到矩阵dist。设置步长和区间,通过迭代选择一个最佳阈值best_threshold,通过numpy.less函数比较dist矩阵和best_threshold,返回true则表示是同一人,false则不是同一人。其中还用到了k折交叉验证,用它得到的准确率取平均值,这个方法是为了使模型的验证结果更加具有一般性。

快速浏览了一下训练代码

facenet_train_classifier.py

  • 动态加载模块network = nn4.py,这个模块包含inference graph
  • 定义Graph:
    – 设置learning_rate, batch_size, phase_train, image_paths, labels等占位符。
    – 创建一个算子data_flow_ops.FIFOQueue,会生成一个先进先出队列的句柄;
    – 创建一个入队算子enqueue_op,让image_paths和labels入队。
    – 预处理线程数量设为4,循环4次,处理图片:

    • random_crop和flip是指随机剪切/翻转图片,这是data augmentation的方法(所谓data augmentation就是在使用CNN处理图片时,由于数据集不够多,采用平移,翻转,加噪声等方法从已有数据中创造出一批”新”的数据)
    • 设置图片的形状,image.set_shape((args.image_size, args.image_size, 3))
    • 添加到 images_and_labels.append([images, label]) ,形成了(处理后的图片, 标签)的向量

    – 最后使用tf.train.batch_join得到image_batch和label_batch
    – 建立inference graph(反映网络的依赖关系):

    • 调用nn4.inference ,这个函数建立了一个包括卷积层、池化层和inception的网络,具体的每一层的定义在network函数里,调用了tf.nn定义网络结构的函数,并把最后一层的数据传出来(网络就不需要了)
    • 再连接一个全连接层tf.contrib.slim.fully_connected (查API似乎fully_connected是属于tf.contrib.layers,但slim是提供contrib模块的接口,这里的关系还没弄明白)
    • 然后调用tf.nn.l2_normalize,使用L2范数沿着维度进行归一化得到embedding矩阵

    – 添加center loss,计算learning rate学习率
    – 计算该batch的平均交叉熵,total loss
    – 建立一个图,这个图使用一个batch来训练模型,且更新模型参数
    – 创建一个tf.train.Saver
    – summary算子可以将图里的精简信息提取出来,summary.merge_all则是将默认图里的所有summaries导出
    – 开始跑图里的算子ops,设置一个args.max_nrof_epochs=500,循环500次,每次循环执行sess.run()(这里设置了一个global_step,应该是用来对训练全局计数,用step更新epoch,不是很懂),调用train函数,并保存变量和元图,然后在LFW上进行验证评估evaluate
    – train函数就是训练,看代码里有一个duration = time.time() - start_time的操作,那训练的过程应该就是这个duration对应的代码sess.run(),参数比较多比较麻烦,暂时没有仔细研究

0 0