
ãã®èšäºã§ã¯ãèªè ã«èå¥ã®ã¿ã¹ã¯ã玹ä»ããŸããåºæ¬çãªå®çŸ©ããããã®åéã®æè¿ã®èšäºã®1ã€ãå®è£ ããããšã§ãã çµæã¯ãåçã§åã人ãæ€çŽ¢ã§ããã¢ããªã±ãŒã·ã§ã³ã§ãããæãéèŠãªã®ã¯ããã®ä»çµã¿ãç解ããããšã§ãã
Bourneã®èå¥ïŒBourneã ãã§ãªãïŒ

èå¥åé¡ã¯åé¡åé¡ã«äŒŒãŠãããæŽå²çã«ãã®åé¡ããçããŸããããªããžã§ã¯ãã®ã¯ã©ã¹ã決å®ãã代ããã«ããªããžã§ã¯ãã«å¿ èŠãªããããã£ããããã©ããã決å®ããããšãå¿ èŠã«ãªããŸããã èå¥åé¡ã§ã¯ããã¬ãŒãã³ã°ã»ããã¯ãªããžã§ã¯ãã®ã»ããã§ã

ããšãã°ããµã«ã®é¡ãã人ã®é¡ãåé¢ããå Žåãããã¯åé¡ã¿ã¹ã¯ã§ãã2ã€ã®ã¯ã©ã¹ãããããªããžã§ã¯ãããšã«ã¯ã©ã¹ãæå®ããŠãäž¡æ¹ã®ã¯ã©ã¹ã®ä»£è¡šçãªãµã³ãã«ãäœæã§ããŸãã é¡ç»åãã©ã®äººç©ã«å±ãããã決å®ããå¿ èŠãããããããã®äººç©ãæéã®åºå®ã»ããã§ããå Žåããããåé¡ã¿ã¹ã¯ã§ãã
ä»ãããªãã圌ã®é¡ã®åçãã人ã決å®ããã¢ããªã±ãŒã·ã§ã³ãéçºããŠãããããŒã¿ããŒã¹ã«èšæ¶ãããŠããå€ãã®äººã ã絶ããå€åããŠããããšãæ³åããŠãã ãããåœç¶ã䜿çšäžãã¢ããªã±ãŒã·ã§ã³ã¯ãã¬ãŒãã³ã°ã»ããã«ããªã人ãèŠãã§ããã-å®éã®ã¿ã¹ã¯çŸä»£äžçã¯èª°ãé©ããªãã§ãããã ãã ããåé¡ã®åé¡ã§ã¯ãªããªããŸããã 解決æ¹æ³ã¯ïŒ
人ãèªèã§ããããã«ããã«ã¯ãå°ãªããšãäžåºŠã¯äŒãå¿ èŠããããŸãã ããæ£ç¢ºã«ã¯ãå°ãªããšã圌ã®åçã1ææã£ãŠããããç¹å®ã®ç»åã®åœ¢ã§ãããèŠããŠããã ãã®åŸã圌ãããããŸã§ç¥ãããŠããªãæ°ããåçãèŠããããããããã¹ãŠã®èšæ¶ãããç»åãšæ¯èŒããçããåºãããšãã§ããŸãïŒç§ãã¡ã¯ãã§ã«ãã®äººãèŠãŠã圌ãŸãã¯ç§ãã¡ãäŒã£ãããšããªããã®äººãèå¥ã§ãã圌ã ããèŠããããšãã§ããŸãã ãããã£ãŠãäžèšã®åé¡ã¯æ¬¡ã®ããã«ãªããŸãã2æã®åçãæã€

èå¥åé¡ã®å®çŸ©ã¯æ¬¡ã®ãšããã§ãããã¬ãŒãã³ã°ãµã³ãã«ã«ããïŒäŸã§ã¯ãé¡ã®å€ãã®ãã¢
ãã®äŸã®æåŸã®åé¡ã¯ã arxiv.org ã Python ãããã³Kerasã®å©ããæ±ããããšã§ãããå°ã圢åŒçãã€è±éçã«è§£æ±ºããŸãã é¡åç-ããã®è¡å
ããŒã³ã¹ãã¬ãã·ãŒ

æ©æ¢°åŠç¿ã®åé¡ã解決ããäžã§æãéèŠãªããšã¯äœã§ããïŒ çããæ¢ãèœåããããšæããŸããïŒ ããããäž»ãªããšã¯ãã®çããæ€èšŒããèœåã§ãã æ©èœ
ã¿ãŒã²ããè©Šè¡ãšåœè è©Šè¡ã®æŠå¿µã玹ä»ããŸãããã æåã«ãªããžã§ã¯ããåŒã³åºããŸã
æ§ç¯ãããé¢æ°ãåããŸã
圌女ã¯æ¢ããŸã

åæããŠããã®ãããªèå¥åã«ã¯ã»ãšãã©æå³ããããŸãã-ååã®å Žåã¯çããæšæž¬ããååã¯ééã£ãŠããŸãã
ãã®ãããªååžã¯ãã§ã«ç§ãã¡ã«é©ããŠããŸãïŒ

ã¿ãŒã²ããã®è©Šã¿ã®å Žåããã®ãããªé¢æ°ã¯ããã§ãªããããæ£ç¢ºã§ããããšããã確å®ã«ããŸãã
ããããè©æ¬ºåž«ãé åžããã«ã¿ãŒã²ããã®é åžãèæ ®ããããšã¯ç¡æå³ã§ãã ãããã«å¯ŸããŠåãæäœãå®è¡ããŸãïŒååžå¯åºŠãæ§ç¯ããŸã

è©æ¬ºçãªè©Šã¿ã®å Žåãã»ãšãã©ã®å Žåãç§ãã¡ã®æ©èœã¯æ£ããçãã«åŸããŠããããšãæããã«ãªããŸãã ãããããããã¯ãŸã èŠèŠçãªèŠ³å¯ã«ãããã 客芳çãªè©äŸ¡ãäžãããã®ã§ã¯ãããŸããã
ã·ã¹ãã ãå ¥åã§ç»åã®ãã¢ãåãåããšä»®å®ããŸãã 圌女ã¯åœŒãã®ããã«ãããæšçã®è©Šã¿ã§ããå¯èœæ§ãèšç®ã§ããŸãã ãããã圌女ã«ã¯æ確ãªçããå¿ èŠã§ããããã¯åã人ç©ã§ãããã©ããã圌ãç§å¯ã®ãªããžã§ã¯ãã«å ¥ãããã©ããã§ãã ãããå€ãèšå®ããŸããã

ã¿ãŒã²ããã®è©Šè¡äžã«ã·ã¹ãã ããã¹ãããã±ãŒã¹ã¯ããã€ãããŸããïŒ æ°ããããïŒ
- FRR ïŒFalse Rejection RateïŒ-誀ã£ãŠæåŠãããã¿ãŒã²ããè©Šè¡ã®å²åã
- FAR ïŒFalse Acceptance RateïŒ-äžé©åã«åä¿¡ãããè©æ¬ºã®è©Šã¿ã®å²åã
äžæ©èžã¿åºããŸããã

ããã§ãéžæãããè·é¢ã«ã€ããŠã ã¿ãŒã²ããã®è©Šè¡ã®ã©ã®å²åãæåŠãããã©ã®çšåºŠã®è©æ¬ºã®è©Šè¡ãåãå ¥ããããããèšãããšãã§ããŸãã ãããŠãã®éã«ãããªãã¯éžã¶ããšãã§ããŸã
ã°ã©ãã®äº€ç¹ã«æ³šæããŠãã ããã ãã®äžã®å€ã¯EER ïŒEqual Error RateïŒãšåŒã°ããŸãã
éžæããå Žå
äžèšã®äŸã§ã¯ã EER = 0.067ã§ãã ããã¯ããã¹ãŠã®æšçã®è©Šã¿ã®å¹³å6.7ïŒ ãæåŠããããã¹ãŠã®åœè ã®è©Šã¿ã®6.7ïŒ ãåãå ¥ããããããšãæå³ããŸãã
ãã1ã€ã®éèŠãªæŠå¿µã¯DETæ²ç·ã§ãã察æ°ã¹ã±ãŒã«ã§ã®FRRã®FRRãžã®äŸåæ§ã§ãã ãã®åœ¢åŒã«ãã£ãŠãã·ã¹ãã å šäœã®å質ãå€æãã1ã€ã®åºæºã®å€ãäžå®ã®ç§ã§ååŸã§ããããšãè©äŸ¡ããæãéèŠãªããšã«ã¯ãã·ã¹ãã ãæ¯èŒããã®ãç°¡åã§ãã

ããã§ã®ERRã¯ã DETæ²ç·ãšçŽç·ã®äº€å·®ç¹ã§ãã
Pythonã§ã®çŽ æŽãªå®è£ ïŒ FARãšFRRã次ã®ç¹ã§ã®ã¿å€åãããšèãããšãããæé©ãªå ŽåããããŸã
import numpy as np def calc_metrics(targets_scores, imposter_scores): min_score = np.minimum(np.min(targets_scores), np.min(imposter_scores)) max_score = np.maximum(np.max(targets_scores), np.max(imposter_scores)) n_tars = len(targets_scores) n_imps = len(imposter_scores) N = 100 fars = np.zeros((N,)) frrs = np.zeros((N,)) dists = np.zeros((N,)) mink = float('inf') eer = 0 for i, dist in enumerate(np.linspace(min_score, max_score, N)): far = len(np.where(imposter_scores > dist)[0]) / n_imps frr = len(np.where(targets_scores < dist)[0]) / n_tars fars[i] = far frrs[i] = frr dists[i] = dist k = np.abs(far - frr) if k < mink: mink = k eer = (far + frr) / 2 return eer, fars, frrs, dists
ã³ã³ãããŒã«ãèŠã€ããŸããïŒä»ãã©ããªæ©èœã§ã
éèŠïŒèå¥ã®åé¡ã§ã¯ãäžèšã®æ€èšŒã»ãããšåŒã°ãããã®ãéçºã»ãã ïŒéçºã»ãããdevsetïŒãšåŒã³ãŸãã å°æ¥ããã®è¡šèšæ³ãé å®ããŸãã
éèŠïŒå®è»žã®ééã¯
ããŒã¹æºå
å€ãã®é¡èªèããŒã¿ã»ããããããŸãã äžéšã¯ææã§ãäžéšã¯ãªã¯ãšã¹ãã«å¿ããŠå©çšã§ããŸãã ç §æã«å€§ããªã°ãã€ãããããã®ãããã°ãé¡ã®äœçœ®ã«ãããã®ããããŸãã ããã€ãã¯å®éšå®€ã§æ®åœ±ããããã®ã§ãä»ã¯èªç¶ã®çæ¯å°ã§æ®åœ±ãããåçããç·šéããããã®ã§ãã ããŒã¿èŠä»¶ãæ確ã«å®åŒåãããšãé©åãªããŒã¿ã»ãããç°¡åã«éžæããããè€æ°ã®ããŒã¿ã»ããããçµã¿ç«ãŠããã§ããŸãã ç§ã«ãšã£ãŠããã®æè²ã¿ã¹ã¯ã®ãã¬ãŒã ã¯ãŒã¯å ã§ã®èŠä»¶ã¯æ¬¡ã®ãšããã§ãããããŒã¿ã»ããã¯ããŠã³ããŒãã®ããã«ç°¡åã«ã¢ã¯ã»ã¹ã§ããããŸãå€ãã®ããŒã¿ãå«ãŸããé¡ã®äœçœ®ã«å€åæ§ãå«ãå¿ èŠããããŸãã ç§ã1ã€ã«çµåãã3ã€ã®ããŒã¿ã»ããã¯ãèŠä»¶ãæºãããŸããã
- ã«ã«ããã¯ã®é¡
- FEI FaceããŒã¿ããŒã¹
- ãžã§ãŒãžã¢å·¥ç§å€§åŠã®é¡ããŒã¿ããŒã¹ ã
ãããã¯ãã¹ãŠå€ããªã£ãŠãããé«å質ã®ææ°ã®é¡èªèã·ã¹ãã ãæ§ç¯ããããšã¯ã§ããŸãããããã¬ãŒãã³ã°ã«ã¯çæ³çã§ãã
ãã®ããã«ããŠåŸãããããŒã¿ããŒã¹ã¯ã277人ã®è¢«éšè ãšã4000æã®ç»åã§ããã1人ãããå¹³å14æã®ç»åã§ããã éçºã»ããã®å¯Ÿè±¡ã®5ã10ïŒ ãåããæ®ãã¯ãã¬ãŒãã³ã°ã«äœ¿çšããŸãã ãã¬ãŒãã³ã°äžãã·ã¹ãã ã¯2çªç®ã®ã»ããã®ãµã³ãã«ã®ã¿ã衚瀺ããå¿ èŠããããæåã«ããããã§ãã¯ããŸãïŒ EERãèæ ®ïŒã
ããŒã¿ãå ±æããããã®ã³ãŒãã¯ãã¡ãããå ¥æã§ããŸã ã äžèšã®ã¢ã³ããã¯ãããããŒã¿ã»ãããžã®ãã¹ã瀺ãããšã®ã¿ãå¿ èŠã§ãã
ããã§ãããŒã¿ãååŠçããå¿ èŠããããŸãã ãŸããé¡ããã€ã©ã€ãããŸãã ããã¯èªåã§ã¯è¡ããŸããããdlibã©ã€ãã©ãªã䜿çšããŸãã

import dlib import numpy as np from skimage import io image = io.imread(image_path) detector = dlib.get_frontal_face_detector() face_rects = list(detector(image, 1)) face_rect = face_rects[0]

ã芧ã®ãšããããã®ã©ã€ãã©ãªã䜿çšãããšãæ°è¡ã®ã³ãŒãã§é¡ãå²ãåè§åœ¢ãååŸã§ããŸãã ãŸããdlibæ€åºåšã¯ã OpenCVãšã¯ç°ãªã ãéåžžã«ããŸãæ©èœããŸããããŒã¿ããŒã¹å šäœããããã12人ã®å人ããã圌ã¯æ€åºã§ãããåäžã®èª€æ€åºãäœæããŸããã§ããã
ç§ãã¡ã®ä»äºã®æ£åŒãªå£°æã¯ããã¹ãŠã®äººãåããµã€ãºã§ãªããã°ãªããªãããšãæå³ããŸãã ãã®èŠä»¶ãæºãããåæã«ãã¹ãŠã®é¡ãæããŠãããŒãã€ã³ãïŒç®ã錻ãåïŒãåžžã«ç»åäžã®åãå Žæã«ããããã«ããŸãã éžæãããã¬ãŒãã³ã°æ¹æ³ã«é¢ä¿ãªãããã®ãããªæ段ãç§ãã¡ãå©ãã確ãã«å€§ããªå®³ãäžããªãããšã¯æããã§ãã ã¢ã«ãŽãªãºã ã¯ç°¡åã§ãïŒ
- åäœæ£æ¹åœ¢ã«ã¯ãããŒãã€ã³ãã®å éšçãªäœçœ®ããããŸãã
- éžæããç»åãµã€ãºãç¥ã£ãŠãåçŽãªã¹ã±ãŒãªã³ã°ã«ãã£ãŠç»åäžã®ãããã®ãã€ã³ãã®åº§æšãèšç®ããŸãã
- 次ã®äººã®ããŒãã€ã³ããéžæããŸãã
- 2çªç®ã®ãã€ã³ãã»ãããæåã®ãã€ã³ãã»ããã«ãããã³ã°ããã¢ãã£ã³å€æãäœæããŸãã
- ã¢ãã£ã³å€æãç»åã«é©çšããŠåãåããŸãã
dlibã®äŸïŒface_template.npyã ãã¡ãããããŠã³ããŒãïŒã§ããŒãã€ã³ãã®åç §äœçœ®ãèŠã€ããŸãã
face_template = np.load(face_template_path)
é¡ç»åäžã®ããŒãã€ã³ããæ€çŽ¢ããã«ã¯ãäŸïŒshape_predictor_68_face_landmarks.datã ãã¡ãããããŠã³ããŒãïŒã§èŠã€ããããšãã§ããæ¢ã«èšç·Žãããã¢ãã«ã䜿çšããŠãdlibãå床䜿çšããŸãã
predictor = dlib.shape_predictor(dlib_predictor_path) points = predictor(image, face_rect) landmarks = np.array(list(map(lambda p: [px, py], points.parts())))
ã¢ãã£ã³å€æã¯ã3ã€ã®ãã€ã³ãã«ãã£ãŠäžæã«å®çŸ©ãããŸãã
INNER_EYES_AND_BOTTOM_LIP = [39, 42, 57]

ããã
ãããèŠã€ããïŒ
proper_landmarks = 227 * face_template[INNER_EYES_AND_BOTTOM_LIP] current_landmarks = landmarks[INNER_EYES_AND_BOTTOM_LIP] A = np.hstack([current_landmarks, np.ones((3, 1))]).astype(np.float64) B = np.hstack([proper_landmarks, np.ones((3, 1))]).astype(np.float64) T = np.linalg.solve(A, B).T
ãããŠãscipy-imageã©ã€ãã©ãªã䜿çšããŠç»åã«é©çšããŸãã
import skimage.transform as tr wrapped = tr.warp( image, tr.AffineTransform(T).inverse, output_shape=(227, 227), order=3, mode='constant', cval=0, clip=True, preserve_range=True ) wrapped /= 255.0

䟿å©ãªAPIã«ã©ãããããå®å šãªååŠçã³ãŒãã¯ã preprocessing.pyãã¡ã€ã«ã«ãããŸãã
ããŒã¿æºåã®æåŸã®ã³ãŒãã¯æ£èŠåã§ãããã¬ãŒãã³ã°ããŒã¹ã«åŸã£ãŠå¹³åãšæšæºåå·®ãèšç®ãããããã®åç»åãæ£èŠåããŸãã éçºã»ããã«ã€ããŠå¿ããªãã§ãã ããã ãã¡ãã®ã³ãŒããã芧ãã ãã ã


åéãåå²ãæŽåãããã³æ£èŠåãããããŒã¿ã¯ã ããããããŠã³ããŒãã§ããŸã ã
ããŒã³ã¢ã«ãã£ã¡ã€ã¿ã
ããŒã¿ãèŠã€ããæºåãããã®ã§ããã¹ãæ¹æ³ãæŽçããŸããã æŠãã®ååãçµãã£ããæ®ã£ãŠããæãç°¡åãªããšã¯èŠã€ããããšã§ã
ã³ã€ã³
æªãæ©èœã®ãŸãã«ãã®äŸããæ€çŽ¢ãå§ããŸããã


EER = 49.5ïŒ ã®å Žåããã®ãããªèå¥åã¯ãå決å®ã§æããã³ã€ã³ãããåªããŠããŸããã ãã¡ãããããã¯ã°ã©ãããªããŠãç解ã§ããŸãããç§ãã¡ã®ç®æšã¯ãèå¥åé¡ã解決ããæ¹æ³ãåŠç¿ããæããã«æªãå€æã§ãã£ãŠãã決å®ã客芳çã«è©äŸ¡ã§ããããã«ããããšã§ãã ããã«ãããã·ã¥ãããã®ããããŸãã
è·é¢
ããã®2ã€ã®ãã¯ãã«ã®æ©èœã¯äœã§ãã
ããšãã°ãäœåŒŠè·é¢ãèããŸãã
ãããŠãéçºã»ããã§åãæäœããã¹ãŠè¡ããŸãã
dev_x = np.load('data/dev_x.npy') protocol = np.load('data/dev_protocol.npy') dev_x = dev_x.mean(axis=3).reshape(dev_x.shape[0], -1) dev_x /= np.linalg.norm(dev_x, axis=1)[:, np.newaxis] scores = dev_x @ dev_x.T tsc, isc = scores[protocol], scores[np.logical_not(protocol)] eer, fars, frrs, dists = calc_metrics(tsc, isc)
ãã®ãããªDETæ²ç·ãåŸãããŸãã

EERã¯16ïŒ æžå°ãã34.18ïŒ ã«ãªããŸããã ããè¯ããããŸã é©çšãããªãã ãã¡ããããã¬ãŒãã³ã°ã»ãããšæ©æ¢°åŠç¿ã¡ãœããã䜿çšããã«ãé¢æ°ã®ã¿ãéžæããããã§ãã ãã ããè·é¢ã®æŠå¿µã¯å ç¢ã§ãããã®ãŸãŸã«ããŠãæ©èœã玹ä»ããŸãããã
ã©ãã§
CNN
ããŠãããªããšç§ã¯ã¿ã¹ã¯ãããã«åçŽåããŸããã è¯ãæ©èœãèŠã€ããã ãã§ã

ã±ã©ã¹ã®ã¢ãã«
from keras.layers import Flatten, Dense, Dropout from keras.layers.convolutional import Convolution2D, MaxPooling2D from keras.layers.advanced_activations import PReLU from keras.models import Sequential model = Sequential() model.add(Convolution2D(96, 11, 11, subsample=(4, 4), input_shape=(dim, dim, 3), init='glorot_uniform', border_mode='same')) model.add(PReLU()) model.add(MaxPooling2D((3, 3), strides=(2, 2))) model.add(Convolution2D(256, 5, 5, subsample=(1, 1), init='glorot_uniform', border_mode='same')) model.add(PReLU()) model.add(MaxPooling2D((3, 3), strides=(2, 2))) model.add(Convolution2D(384, 3, 3, subsample=(1, 1), init='glorot_uniform', border_mode='same')) model.add(PReLU()) model.add(Convolution2D(384, 3, 3, subsample=(1, 1), init='glorot_uniform', border_mode='same')) model.add(PReLU()) model.add(Convolution2D(256, 3, 3, subsample=(1, 1), init='glorot_uniform', border_mode='same')) model.add(PReLU()) model.add(MaxPooling2D((3, 3), strides=(2, 2))) model.add(Flatten()) model.add(Dropout(0.5)) model.add(Dense(2048, init='glorot_uniform')) model.add(PReLU()) model.add(Dropout(0.5)) model.add(Dense(256, init='glorot_uniform')) model.add(PReLU()) model.add(Dense(n_classes, init='glorot_uniform', activation='softmax')) model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
ãããŠããã¬ãŒãã³ã°ã»ããã®å€å žçãªåé¡ã®åé¡ã解決ããããšã圌女ã«æããŸãã250人ã®è¢«éšè ã®ã©ããé¡åçãææããŠããããå€æããŸãã äžèšã®ã³ãŒãã«å ããŠã誰ããã±ã©ã§ãã®ãããªç°¡åãªã¿ã¹ã¯ã解決ã§ããŸãããŸãã5ã6è¡ç®ãå¿ èŠã§ãã ãã®èšäºã§èª¬æãããã¬ãŒãã³ã°ããŒã¹ã«ã¯ã æ¡åŒµãé©çšããããšãäžå¯æ¬ ã§ããããããªããšãããŒã¿ãååãªçµæãåŸãããšãã§ããŸããã
ããªãã¯ãåé¡ã¿ã¹ã¯ããããšäœã®é¢ä¿ãããã®ãââããããŠãã®è§£æ±ºçã¯ã©ã®ããã«ç§ãã¡ãå©ããã®ã§ããããïŒ æ£ããããïŒ ä»¥äžã§èª¬æããã¢ã¯ã·ã§ã³ãç解ããããã«ã¯ãéåžžã«éèŠãªä»®å®ãç«ãŠãå¿ èŠããããŸã ïŒ ãããã¯ãŒã¯ãéããéåã®åé¡åé¡ãããŸã解決ããããšãåŠç¿ããå Žåã次å 256ã®æåŸãã2çªç®ã®ã¬ã€ã€ãŒã«ã察象ããã¬ãŒãã³ã°ã»ããã«å«ãŸããŠããªããŠããé¡ç»åã«é¢ãããã¹ãŠã®éèŠãªæ å ±ãéäžããŸãã
èšç·Žããããããã¯ãŒã¯ã®æåŸã®å±€ããäœæ¬¡å ã®ç¹åŸŽãæœåºãããã®ææ³ã¯åºãæ®åããŠããã ããã«ããã¯ãšåŒã°ããŠããŸãã ã¡ãªã¿ã«ãkerasã®ããã«ããã¯ãåŠçããããã®ã³ãŒãã¯ãã¡ãã«ãããŸã ã
ãããã¯ãŒã¯ã¯ãã¬ãŒãã³ã°ããã256次å ã®å±æ§ãéçºã»ããããæœåºãããŸããã DETæ²ç·ãèŠãŠã¿ãŸãããã

ä»®å®ã¯çå®ã§ããããšãå€æãã EERãããã«13ïŒ æžå°ããçµæã¯21.6ïŒ ã«éããŸããã ã³ã€ã³ãæããããã2åè¯ãã ããã¯ããã«è¯ãã§ããïŒ ãã¡ããããã倧ããããå€æ§ãªããŒã¹ãæ§ç¯ããããæ·±ãCNNãæ§ç¯ããããŸããŸãªæ£ååææ³ãé©çšã§ããŸã...ããããé«å質ã®æŠå¿µçã¢ãããŒããæ€èšããŠããŸãã ãããŠãéã¯ãã€ã§ãå¢ããããšãã§ããŸãã è¢ã«ã¯ãŸã ãã1ã€ã®åãæããããŸãããããŒãã«ã«çœ®ãåã«å°ãæ°ãæ£ãããªããã°ãªããŸããã
ããŒã³ãšããªã¥ãŒã·ã§ã³

çµæãæ¹åããéµã¯ãæé©åã®å®çŸã«ãããŸã
圌ããææ¡ããã¢ãããŒãã¯TDE ïŒTriplet Distance EmbeddingïŒãšåŒã°ãã以äžããæ§æãããŠããŸããã

ããªãã«ã䜿çšããŠãã®ãããªãããã¯ãŒã¯ãæããããšãææ¡ãããŸããã
ã€ãŸããç¹å®ã®ã¢ã³ã«ãŒã«ã€ããŠãããžãã£ããšãã¬ãã£ããååšãããšãªã¢éã«ã®ã£ãããããããšãæå³ããŸã
ãã®ã¢ãããŒãã䜿çšããŠãèè ã¯WildãšYouTube Faces DB ããŒã¿ã»ããã®Labeled Facesã®ãšã©ãŒã30ïŒ åæžããŸãããããã¯ééããªãéåžžã«ã¯ãŒã«ã§ãã ãã ãããã®ã¢ãããŒãã«ã¯åé¡ããããŸãã
- å€ãã®ããŒã¿ãå¿ èŠã§ãã
- é ãåŠç¿
- ãªãã·ã§ã³ãã©ã¡ãŒã¿
éžææ¹æ³ã¯æ確ã§ã¯ãããŸããã
- å€ãã®å ŽåïŒäž»ã«å°éã®ããŒã¿ã§ïŒã softmax + bottleneckãããåäœãæªããªããŸãã
ããã«ãã·ãŒã³TPE ïŒTriplet確ççåã蟌ã¿ïŒããããŸããããã¯ãé¡æ€èšŒãšã¯ã©ã¹ã¿ãªã³ã°ã®ããã®ããªãã¬ãã確ççåã蟌ã¿ã§èª¬æãããŠããŸãã
è¿œå ã®ãã©ã¡ãŒã¿ãŒãå ¥åããçç±
ããã¯ãªãªãžãã«ãããç°¡åã§è§£éããããã§ããç§ãã¡ã«æãè¿ãè² ã®äŸã¯ãç§ãã¡ããæãé ãæ£ã®äŸãããé ãã«ããããšãæã¿ãŸããããããã®éã«ã®ã£ããããã£ãŠã¯ãªããŸããã è·é¢ãé¢ããŠããããã¯ãŒã¯ã®æŽæ°ãåæ¢ããªããšããäºå®ã®ãã
ããªãã¬ãããæå®ãããäžçåŒãæºãã確çãèšç®ã§ããŸãã
ã§å²ã£ã
確çã®å¯Ÿæ°ãæ倧åãããããæ倱é¢æ°ã¯æ¬¡ã®ããã«ãªããŸãã
ãããŠæ©èœãšããŠ

ã芧ã®ãšããããã®ã¢ãããŒãã¯å ã®ã¢ãããŒããããããŸãæ©èœããå€ãã®å©ç¹ããããŸãã
- å¿ èŠãªããŒã¿ãå°ãªãã
- éåžžã«éãåŠç¿ããŸãã
- æ·±ãããã¢ãŒããã¯ãã£ã¯å¿ èŠãããŸããã
- æ¢åã®ãã¬ãŒãã³ã°æžã¿ã¢ãŒããã¯ãã£ã®äžã§äœ¿çšã§ããŸãã
ãã®ã¢ãããŒãã䜿çšããŠããŸãã ãã®ããã«å¿ èŠãªã³ãŒãã¯20è¡ã ãã§ãã
def triplet_loss(y_true, y_pred): return -K.mean(K.log(K.sigmoid(y_pred))) def triplet_merge(inputs): a, p, n = inputs return K.sum(a * (p - n), axis=1) def triplet_merge_shape(input_shapes): return (input_shapes[0][0], 1) a = Input(shape=(n_in,)) p = Input(shape=(n_in,)) n = Input(shape=(n_in,)) base_model = Sequential() base_model.add(Dense(n_out, input_dim=n_in, bias=False, weights=[W_pca], activation='linear')) base_model.add(Lambda(lambda x: K.l2_normalize(x, axis=1))) a_emb = base_model(a) p_emb = base_model(p) n_emb = base_model(n) e = merge([a_emb, p_emb, n_emb], mode=triplet_merge, output_shape=triplet_merge_shape) model = Model(input=[a, p, n], output=e) predict = Model(input=a, output=a_emb) model.compile(loss=triplet_loss, optimizer='rmsprop')
ãããžã§ã¯ãã§TPEã䜿çšãããå Žåã¯ãããªãã¬ããã䜿çšãããã¬ãŒãã³ã°ã®æãéèŠãªåé¡ïŒãã®éžæã®åé¡ïŒãåãäžããªãã£ããããå ã®äœåãèªãã®ãé¢åã§ã¯ãããŸããã å°ããªã¿ã¹ã¯ã§ã¯ãã©ã³ãã éžæã§ååã§ãããããã¯ã«ãŒã«ãšããããã¯äŸå€ã§ãã
ããã«ããã¯ã«ã€ããŠTPEããã¬ãŒãã³ã°ããä»æ¥ã®æåŸã®DETæ²ç·ãèŠãŠã¿ãŸãããã

12ïŒ ã®EERã¯ãç§ãã¡ãæãã§ãããã®ã«éåžžã«è¿ããã®ã§ãã ããã¯ãCNNã䜿çšããããã2åãã©ã³ãã éžæããã5ååªããŠããŸãã ãã¡ãããããæ·±ãã¢ãŒããã¯ãã£ãšãã倧ããªããŒã¹ã䜿çšããŠçµæãæ¹åã§ããŸããããã®ãããªçµæã¯ååãç解ããã®ã«ååã§ãã
èæ ®ãããŠãããã¹ãŠã®ã¡ãœããã®DET-æ²ç·ã®æ¯èŒïŒ

WebããŒã¹ã®ã€ã³ã¿ãŒãã§ãŒã¹ã§ããããšQtã¢ããªã±ãŒã·ã§ã³ã§ããããšãããããçš®é¡ã®ãšã³ãžãã¢ãªã³ã°ãšã·ã¹ãã ãžã®ã€ã³ã¿ãŒãã§ãŒã¹ãåºå®ããåçã§åäžã®é¡ãæ€çŽ¢ããããã®ããã°ã©ã ãçšæãããŠããŸãã

ãã®ã¢ããªã¯GitHubã§å ¥æã§ããŸã ã
èªãã§ãããŠããããšãïŒ åæ§ã«ããããã£ãŒã«ã賌èªããã³ã¡ã³ããæ®ããè»ãäžæã«æããŠãã ããã è¿œå ã¯å€§æè¿ã§ãã