1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 package org.openimaj.demos;
31
32 import java.io.File;
33 import java.io.FileNotFoundException;
34 import java.io.IOException;
35 import java.util.ArrayList;
36 import java.util.List;
37 import java.util.Random;
38 import java.util.Scanner;
39
40 import org.openimaj.feature.FloatFV;
41 import org.openimaj.io.IOUtils;
42 import org.openimaj.ml.linear.projection.LargeMarginDimensionalityReduction;
43
44 import Jama.Matrix;
45
46 import com.jmatio.io.MatFileReader;
47 import com.jmatio.types.MLSingle;
48
49 public class FVFWExperiment {
50
51
52
53 private static final String FOLDER = "matlab-fvs/";
54
55 static class FacePair {
56 boolean same;
57 File firstFV;
58 File secondFV;
59
60 public FacePair(File first, File second, boolean same) {
61 this.firstFV = first;
62 this.secondFV = second;
63 this.same = same;
64 }
65
66 FloatFV loadFirst() throws IOException {
67 return IOUtils.read(firstFV, FloatFV.class);
68 }
69
70 FloatFV loadSecond() throws IOException {
71 return IOUtils.read(secondFV, FloatFV.class);
72 }
73 }
74
75 static class Subset {
76 List<FacePair> testPairs = new ArrayList<FacePair>();
77 List<FacePair> trainingPairs = new ArrayList<FacePair>();
78 }
79
80 static List<Subset> loadSubsets() throws IOException {
81 final List<Subset> subsets = new ArrayList<Subset>();
82
83 for (int i = 0; i < 10; i++)
84 subsets.add(new Subset());
85
86 loadPairs(new File("/Users/jon/Data/lfw/pairs.txt"), subsets);
87 loadPeople(new File("/Users/jon/Data/lfw/people.txt"), subsets);
88
89 return subsets;
90 }
91
92 private static void loadPairs(File file, List<Subset> subsets) throws FileNotFoundException {
93 final Scanner sc = new Scanner(file);
94
95 final int nsets = sc.nextInt();
96 final int nhpairs = sc.nextInt();
97
98 if (nsets != 10 || nhpairs != 300) {
99 sc.close();
100 throw new RuntimeException();
101 }
102
103 for (int s = 0; s < 10; s++) {
104 for (int i = 0; i < 300; i++) {
105 final String name = sc.next();
106 final int firstIdx = sc.nextInt();
107 final int secondIdx = sc.nextInt();
108
109 final File first = new File(file.getParentFile(), FOLDER + name
110 + "/" + name + String.format("_%04d.bin", firstIdx));
111 final File second = new File(file.getParentFile(), FOLDER + name
112 + "/" + name + String.format("_%04d.bin", secondIdx));
113
114 subsets.get(s).testPairs.add(new FacePair(first, second, true));
115 }
116
117 for (int i = 0; i < 300; i++) {
118 final String firstName = sc.next();
119 final int firstIdx = sc.nextInt();
120 final String secondName = sc.next();
121 final int secondIdx = sc.nextInt();
122
123 final File first = new File(file.getParentFile(), FOLDER
124 + firstName
125 + "/" + firstName + String.format("_%04d.bin", firstIdx));
126 final File second = new File(file.getParentFile(), FOLDER
127 + secondName
128 + "/" + secondName + String.format("_%04d.bin", secondIdx));
129
130 subsets.get(s).testPairs.add(new FacePair(first, second, false));
131 }
132 }
133
134 sc.close();
135 }
136
137 private static void loadPeople(File file, List<Subset> subsets) throws FileNotFoundException {
138 final Scanner sc = new Scanner(file);
139
140 final int nsets = sc.nextInt();
141
142 if (nsets != 10) {
143 sc.close();
144 throw new RuntimeException();
145 }
146
147 for (int s = 0; s < 10; s++) {
148 final int nnames = sc.nextInt();
149 final List<File> files = new ArrayList<File>(nnames);
150 for (int i = 0; i < nnames; i++) {
151 final String name = sc.next();
152 final int numPeople = sc.nextInt();
153 for (int j = 1; j <= numPeople; j++) {
154 final File f = new File(file.getParentFile(), FOLDER + name
155 + "/" + name + String.format("_%04d.bin", j));
156
157 files.add(f);
158 }
159 }
160
161 for (int i = 0; i < files.size(); i++) {
162 final File first = files.get(i);
163 for (int j = i + 1; j < files.size(); j++) {
164 final File second = files.get(j);
165
166 final boolean same = first.getName().substring(0, first.getName().lastIndexOf("_"))
167 .equals(second.getName().substring(0, second.getName().lastIndexOf("_")));
168
169 subsets.get(s).trainingPairs.add(new FacePair(first, second, same));
170 subsets.get(s).trainingPairs.add(new FacePair(second, first, same));
171 }
172 }
173 }
174
175 sc.close();
176 }
177
178 static Subset createExperimentalFold(List<Subset> subsets, int foldIdx) {
179 final Subset subset = new Subset();
180
181 subset.testPairs = subsets.get(foldIdx).testPairs;
182
183
184 final List<FacePair> training = new ArrayList<FacePair>();
185 for (int i = 0; i < foldIdx; i++)
186 training.addAll(subsets.get(i).trainingPairs);
187 for (int i = foldIdx + 1; i < subsets.size(); i++)
188 training.addAll(subsets.get(i).trainingPairs);
189
190 subset.trainingPairs = reorder(training);
191
192 return subset;
193 }
194
195 private static List<FacePair> reorder(List<FacePair> training) {
196 final List<FacePair> trainingTrue = new ArrayList<FacePair>();
197 final List<FacePair> trainingFalse = new ArrayList<FacePair>();
198
199 for (final FacePair fp : training) {
200 if (fp.same)
201 trainingTrue.add(fp);
202 else
203 trainingFalse.add(fp);
204 }
205
206 resample(trainingTrue, 4000000);
207 resample(trainingFalse, 4000000);
208
209 final List<FacePair> trainingResorted = new ArrayList<FacePair>();
210 for (int i = 0; i < trainingTrue.size(); i++) {
211 trainingResorted.add(trainingTrue.get(i));
212 trainingResorted.add(trainingFalse.get(i));
213 }
214
215 return trainingResorted;
216 }
217
218 private static void resample(List<FacePair> pairs, int sz) {
219 final List<FacePair> oldPairs = new ArrayList<FVFWExperiment.FacePair>(sz);
220 oldPairs.addAll(pairs);
221 pairs.clear();
222
223 final Random r = new Random();
224
225 for (int i = 0; i < sz; i++) {
226 pairs.add(oldPairs.get(r.nextInt(oldPairs.size())));
227 }
228 }
229
230 public static void main(String[] args) throws IOException {
231 final List<Subset> subsets = loadSubsets();
232 final Subset fold = createExperimentalFold(subsets, 1);
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274 final LargeMarginDimensionalityReduction lmdr =
275 IOUtils.readFromFile(new
276 File("/Users/jon/Data/lfw/lmdr-matlabfvs-pcaw.bin"));
277
278
279
280 final double[][] first = new double[fold.testPairs.size()][];
281 final double[][] second = new double[fold.testPairs.size()][];
282 final boolean[] same = new boolean[fold.testPairs.size()];
283 for (int j = 0; j < same.length; j++) {
284 final FacePair p = fold.testPairs.get(j);
285 first[j] = p.loadFirst().asDoubleVector();
286 second[j] = p.loadSecond().asDoubleVector();
287 same[j] = p.same;
288 }
289
290
291
292
293 double correct = 0;
294 double count = 0;
295 for (int j = 0; j < same.length; j++) {
296 final boolean pred = lmdr.classify(first[j],
297 second[j]);
298
299 if (pred == same[j])
300 correct++;
301 count++;
302 }
303 System.out.println(lmdr.getBias() + " " + (correct / count));
304 }
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319 private static LargeMarginDimensionalityReduction loadMatlabLMDR() throws IOException {
320 final LargeMarginDimensionalityReduction lmdr = new LargeMarginDimensionalityReduction(128);
321
322 final MatFileReader reader = new MatFileReader(new File("/Users/jon/lmdr.mat"));
323 final MLSingle W = (MLSingle) reader.getContent().get("W");
324 final MLSingle b = (MLSingle) reader.getContent().get("b");
325
326 lmdr.setBias(b.get(0, 0));
327
328 final Matrix proj = new Matrix(W.getM(), W.getN());
329 for (int j = 0; j < W.getN(); j++) {
330 for (int i = 0; i < W.getM(); i++) {
331 proj.set(i, j, W.get(i, j));
332 }
333 }
334
335 lmdr.setTransform(proj);
336
337 return lmdr;
338 }
339
340 private static LargeMarginDimensionalityReduction loadMatlabPCAW() throws IOException {
341 final LargeMarginDimensionalityReduction lmdr = new LargeMarginDimensionalityReduction(128);
342
343 final MatFileReader reader = new MatFileReader(new File("/Users/jon/pcaw.mat"));
344 final MLSingle W = (MLSingle) reader.getContent().get("proj");
345
346 lmdr.setBias(169.6264190673828);
347
348 final Matrix proj = new Matrix(W.getM(), W.getN());
349 for (int j = 0; j < W.getN(); j++) {
350 for (int i = 0; i < W.getM(); i++) {
351 proj.set(i, j, W.get(i, j));
352 }
353 }
354
355 lmdr.setTransform(proj);
356
357 return lmdr;
358 }
359 }