三、在LFW上验证模型准确率
LFW数据下载地址:http://vis-www.cs.umass.edu/lfw/,我下载之后放在了F:facerecognition目录下 。
构造测试集,分别构造正例和负例,将相同的人脸放一堆,不同的人脸放一堆,代码如下:
import org.Apache.commons.io.FileUtils;import java.io.File;import java.io.IOException;import java.util.Arrays;import java.util.List;import java.util.Random;public class DataTools {private static final String PARENT_PATH = "F:/facerecognition";public static void main(String[] args) throws IOException {File file = new File(PARENT_PATH + "/lfw");List<File> list = Arrays.asList(file.listFiles());for (int i = 0; i < list.size(); i++) {String name = list.get(i).getName();File[] faceFileArray = list.get(i).listFiles();if (null == faceFileArray) {continue;}//构造正例if (faceFileArray.length > 1) {String positiveFilePath = PARENT_PATH + "/pairs/1/" + name;File positiveFileDir = new File(positiveFilePath);if (positiveFileDir.exists()) {positiveFileDir.delete();}positiveFileDir.mkdir();FileUtils.copyFile(faceFileArray[0], new File(positiveFilePath + "/" + faceFileArray[0].getName()));FileUtils.copyFile(faceFileArray[1], new File(positiveFilePath + "/" + faceFileArray[1].getName()));}//构造负例String negativeFilePath = PARENT_PATH + "/pairs/0/" + name;File negativeFileDir = new File(negativeFilePath);if (negativeFileDir.exists()) {negativeFileDir.delete();}negativeFileDir.mkdir();FileUtils.copyFile(faceFileArray[0], new File(negativeFilePath + "/" + faceFileArray[0].getName()));File[] differentFaceArray = list.get(randomInt(list.size(), i)).listFiles();int differentFaceIndex = randomInt(differentFaceArray.length, -1);FileUtils.copyFile(differentFaceArray[differentFaceIndex], new File(negativeFilePath + "/" + differentFaceArray[differentFaceIndex].getName()));}}public static int randomInt(int max, int target) {Random random = new Random();while (true) {int result = random.nextInt(max);if (result != target) {return result;}}}}
测试集构造完成之后,构造迭代器,迭代器中读取图片用了NativeImageLoader,在《如何利用deeplearning4j中datavec对图像进行处理》有相关介绍 。
public class DataSetForEvaluation implements MultiDataSetIterator { private List<FacePair> facePairList; private int batchSize; private int totalBatches; private NativeImageLoader imageLoader; private int currentBatch = 0; public DataSetForEvaluation(List<FacePair> facePairList, int batchSize) {this.facePairList = facePairList;this.batchSize = batchSize;this.totalBatches = (int) Math.ceil((double) facePairList.size() / batchSize);this.imageLoader = new NativeImageLoader(224, 224, 3, new ResizeImageTransform(224, 224)); } @Override public boolean hasNext() {return currentBatch < totalBatches; } @Override public MultiDataSet next() {return next(batchSize); } @Override public MultiDataSet next(int num) {int i = currentBatch * batchSize;int currentBatchSize = Math.min(batchSize, facePairList.size() - i);INDArray input1 = Nd4j.zeros(currentBatchSize, 3,224,224);INDArray input2 =Nd4j.zeros(currentBatchSize, 3,224,224);INDArray label = Nd4j.zeros(currentBatchSize, 1);for (int j = 0; j < currentBatchSize; j++) {try {input1.put(new INDArrayIndex[]{NDArrayIndex.point(j),NDArrayIndex.all(),NDArrayIndex.all(),NDArrayIndex.all()}, imageLoader.asMatrix(facePairList.get(i).getList().get(0)).div(255));input2.put(new INDArrayIndex[]{NDArrayIndex.point(j),NDArrayIndex.all(),NDArrayIndex.all(),NDArrayIndex.all()},imageLoader.asMatrix(facePairList.get(i).getList().get(1)).div(255));} catch (Exception e) {e.printStackTrace();}label.putScalar((long) j, 0, facePairList.get(i).getLabel());++i;}System.out.println(currentBatch);++currentBatch;return new org.nd4j.linalg.dataset.MultiDataSet(new INDArray[] { input1, input2},new INDArray[] { label }); } @Override public void setPreProcessor(MultiDataSetPreProcessor preProcessor) { } @Override public MultiDataSetPreProcessor getPreProcessor() {return null; } @Override public boolean resetSupported() {return true; } @Override public boolean asyncSupported() {return false; } @Override public void reset() {currentBatch = 0; }}
接下来可以评估模型的性能了,准确率和精确率还凑合,但F1值有点低 。
========================Evaluation Metrics======================== # of classes:2 Accuracy:0.8973 Precision:0.9119 Recall:0.6042 F1 Score:0.7268Precision, recall & F1: reported for positive class (class 1 - "1") only=========================Confusion Matrix=========================01----------- 565198 | 0 = 0665 1015 | 1 = 1Confusion matrix format: Actual (rowClass) predicted as (columnClass) N times==================================================================
四、用SpringBoot将模型封装成服务
模型保存之后,就是一堆死参数,怎么变成线上的服务呢?人脸识别服务分为两种1:1和1:N
推荐阅读
- 如何看客厅风水是藏风纳气还是一泻千里?
- 客厅风水:客厅地板如何装饰?
- 如何让客厅风水带动家居运气
- 客厅采光的方向与颜色的搭配
- 客厅的沙发应当如何摆放?
- 客厅风水:如何布置客厅的财位?
- 如果刘备按照隆中对能不能一统天下 诸葛亮在隆中给刘备的策略
- 黄山毛峰茶的冲泡方法,黄山毛峰如何冲泡
- 哪些发达国家是如何养老的?
- 家里有蟑螂怎么办