
рд╕реНрдпрд╛рдо рджреЗрд╢ рдХрд╛ рддрдВрддреНрд░рд┐рдХрд╛ рдиреЗрдЯрд╡рд░реНрдХ рд╕рдмрд╕реЗ рд╕рд░рд▓ рдФрд░ рд╕рдмрд╕реЗ рд▓реЛрдХрдкреНрд░рд┐рдп рдПрдХрд▓ рд╢рд┐рдХреНрд╖рдг рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИред рд╡реЗ рд╡рд┐рдзрд┐рдпрд╛рдБ рдЬрд┐рдирдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдХрдХреНрд╖рд╛ рдХреЗ рд▓рд┐рдП рдХреЗрд╡рд▓ рдПрдХ рдХреЗрд╕ рд╕реНрдЯрдбреА рд▓реА рдЬрд╛рддреА рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╕реНрдпрд╛рдо рджреЗрд╢ рдХрд╛ рдиреЗрдЯрд╡рд░реНрдХ рдЖрдорддреМрд░ рдкрд░ рдЙрди рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рдкреНрд░рддреНрдпреЗрдХ рд╡рд░реНрдЧ рдореЗрдВ рдбреЗрдЯрд╛ рдХреА рдХрдИ рдЗрдХрд╛рдЗрдпрд╛рдВ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИрдВред
рдорд╛рди рд▓реАрдЬрд┐рдП рд╣рдореЗрдВ рд▓рдЧрднрдЧ 500 рд▓реЛрдЧреЛрдВ рдХреЛ рд░реЛрдЬрдЧрд╛рд░ рджреЗрдиреЗ рд╡рд╛рд▓реЗ рд╕рдВрдЧрдарди рдХреЗ рд▓рд┐рдП рдПрдХ рдЪреЗрд╣рд░рд╛ рдкрд╣рдЪрд╛рди рдореЙрдбрд▓ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрджрд┐ рд╣рдо рдХрдиреНрд╡реЗрдиреНрд╢рдирд▓ рдиреНрдпреВрд░рд▓ рдиреЗрдЯрд╡рд░реНрдХ (CNN) рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╕реНрдХреНрд░реИрдЪ рд╕реЗ рдРрд╕рд╛ рдореЙрдбрд▓ рдмрдирд╛рддреЗ рд╣реИрдВ, рддреЛ рдореЙрдбрд▓ рдХреЛ рдкреНрд░рд╢рд┐рдХреНрд╖рд┐рдд рдХрд░рдиреЗ рдФрд░ рдЕрдЪреНрдЫреА рдкрд╣рдЪрд╛рди рд╕рдЯреАрдХрддрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдЗрди 500 рд▓реЛрдЧреЛрдВ рдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдХреА рдХрдИ рдЫрд╡рд┐рдпреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рд▓реЗрдХрд┐рди рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рд╣рдо рдЗрд╕ рддрд░рд╣ рдХреЗ рдбреЗрдЯрд╛рд╕реЗрдЯ рдХреЛ рдПрдХрддреНрд░ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдкрд░реНрдпрд╛рдкреНрдд рдбреЗрдЯрд╛ рдирд╣реАрдВ рд╣реИ рддреЛ рдЖрдкрдХреЛ рд╕реАрдПрдирдПрди рдпрд╛ рдХрд┐рд╕реА рдЕрдиреНрдп
рдЧрд╣рди рд╢рд┐рдХреНрд╖рдг рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдкрд░ рдЖрдзрд╛рд░рд┐рдд рдореЙрдбрд▓ рдирд╣реАрдВ рдмрдирд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдРрд╕реЗ рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдЖрдк рд╕реНрдпрд╛рдо рджреЗрд╢ рдХреЗ рдиреЗрдЯрд╡рд░реНрдХ рдХреА рддрд░рд╣ рдЬрдЯрд┐рд▓ рдПрдХ рдмрд╛рд░ рд╕реАрдЦрдиреЗ рдХреЗ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд┐рд╕реЗ рдХрдо рдбреЗрдЯрд╛ рдкрд░ рдкреНрд░рд╢рд┐рдХреНрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╕реНрдпрд╛рдо рджреЗрд╢ рдХреЗ рдиреЗрдЯрд╡рд░реНрдХ рдореЗрдВ рджреЛ рд╕рдордорд┐рдд рддрдВрддреНрд░рд┐рдХрд╛ рдиреЗрдЯрд╡рд░реНрдХ рд╣реЛрддреЗ рд╣реИрдВ, рдПрдХ рд╣реА рднрд╛рд░ рдФрд░ рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХреЗ рд╕рд╛рде, рдЬреЛ рдЕрдВрдд рдореЗрдВ рд╕рдВрдпреЛрдЬрди рдФрд░ рдКрд░реНрдЬрд╛ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ - рдИред
рдЖрдЗрдП рд╕реНрдпрд╛рдо рджреЗрд╢ рдХреЗ рдиреЗрдЯрд╡рд░реНрдХ рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ, рдЗрд╕рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдПрдХ рдЪреЗрд╣рд░рд╛ рдкрд╣рдЪрд╛рди рдореЙрдбрд▓ рдмрдирд╛рддреЗ рд╣реИрдВред рд╣рдо рдЙрд╕реЗ рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд┐рдЦрд╛рдПрдВрдЧреЗ рдХрд┐ рджреЛ рдЪреЗрд╣рд░реЗ рд╕рдорд╛рди рд╣реИрдВ рдФрд░ рдХрдм рдирд╣реАрдВред рдФрд░ рд╢реБрд░реБрдЖрдд рдХреЗ рд▓рд┐рдП, рд╣рдо Faces рдбреЗрдЯрд╛рд╕реЗрдЯ рдХреЗ AT & T рдбреЗрдЯрд╛рдмреЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ, рдЬрд┐рд╕реЗ
рдХреИрдореНрдмреНрд░рд┐рдЬ рдпреВрдирд┐рд╡рд░реНрд╕рд┐рдЯреА рдХреЗ рдХрдВрдкреНрдпреВрдЯрд░ рд▓реИрдм рд╡реЗрдмрд╕рд╛рдЗрдЯ рд╕реЗ рдбрд╛рдЙрдирд▓реЛрдб рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдбрд╛рдЙрдирд▓реЛрдб рдХрд░реЗрдВ, рдЕрдирдкреИрдХ рдХрд░реЗрдВ рдФрд░ s1 рд╕реЗ s40 рддрдХ рдХреЗ рдлреЛрд▓реНрдбрд░ рджреЗрдЦреЗрдВ:

рдкреНрд░рддреНрдпреЗрдХ рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдХреЛрдгреЛрдВ рд╕реЗ рд▓рд┐рдП рдЧрдП рдПрдХрд▓ рд╡реНрдпрдХреНрддрд┐ рдХреА 10 рдЕрд▓рдЧ-рдЕрд▓рдЧ рддрд╕реНрд╡реАрд░реЗрдВ рд╣реЛрддреА рд╣реИрдВред рдпрд╣рд╛рдБ s1 рдлрд╝реЛрд▓реНрдбрд░ рдХреА рд╕рд╛рдордЧреНрд░реА рд╣реИ:

рдФрд░ рдпрд╣рд╛рдБ s13 рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рдХреНрдпрд╛ рд╣реИ:

Siamese рдиреЗрдЯрд╡рд░реНрдХ рдХреЛ рдЪрд┐рд╣реНрдиреЛрдВ рдХреЗ рд╕рд╛рде рдпреБрдЧреНрдорд┐рдд рдорд╛рдиреЛрдВ рдХреЛ рдЗрдирдкреБрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рддреЛ рдЖрдЗрдП рдРрд╕реЗ рд╕реЗрдЯ рдмрдирд╛рдПрдВред рдПрдХ рд╣реА рдлрд╝реЛрд▓реНрдбрд░ рд╕реЗ рджреЛ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рддрд╕реНрд╡реАрд░реЗрдВ рд▓реЗрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ "рд╡рд╛рд╕реНрддрд╡рд┐рдХ" рдЬреЛрдбрд╝реА рдХреЗ рд░реВрдк рдореЗрдВ рдЪрд┐рд╣реНрдирд┐рдд рдХрд░реЗрдВред рдлрд┐рд░ рд╣рдо рд╡рд┐рднрд┐рдиреНрди рдлрд╝реЛрд▓реНрдбрд░реЛрдВ рд╕реЗ рджреЛ рддрд╕реНрд╡реАрд░реЗрдВ рд▓реЗрддреЗ рд╣реИрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ "рдЭреВрдареА" рдЬреЛрдбрд╝реА рдХреЗ рд░реВрдк рдореЗрдВ рдЪрд┐рд╣реНрдирд┐рдд рдХрд░рддреЗ рд╣реИрдВ:

рд╕рднреА рддрд╕реНрд╡реАрд░реЛрдВ рдХреЛ рдЪрд┐рд╣реНрдирд┐рдд рдЬреЛрдбрд╝реЗ рдореЗрдВ рд╡рд┐рддрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рдиреЗрдЯрд╡рд░реНрдХ рдХрд╛ рдЕрдзреНрдпрдпрди рдХрд░реЗрдВрдЧреЗред рдкреНрд░рддреНрдпреЗрдХ рдЬреЛрдбрд╝реА рд╕реЗ, рд╣рдо рдПрдХ рдлреЛрдЯреЛ рдХреЛ рдиреЗрдЯрд╡рд░реНрдХ рдП рдФрд░ рджреВрд╕рд░реЗ рдХреЛ рдиреЗрдЯрд╡рд░реНрдХ рдмреА рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░реЗрдВрдЧреЗред рджреЛрдиреЛрдВ рдиреЗрдЯрд╡рд░реНрдХ рдХреЗрд╡рд▓ рд╕рдВрдкрддреНрддрд┐ рд╡реИрдХреНрдЯрд░ рдирд┐рдХрд╛рд▓рддреЗ рд╣реИрдВред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рд░реЗрдХреНрдЯрд┐рдлрд╛рдЗрдб рд▓реАрдирд┐рдпрд░ рдпреВрдирд┐рдЯ (ReLU) рдХреЗ рд╕рдХреНрд░рд┐рдпрдг рдХреЗ рд╕рд╛рде рджреЛ рд╕рдВрдХреЗрдВрджреНрд░рд┐рдд рдкрд░рддреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рдЧреБрдгреЛрдВ рдХрд╛ рдЕрдзреНрдпрдпрди рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рджреЛрдиреЛрдВ рдиреЗрдЯрд╡рд░реНрдХ рджреНрд╡рд╛рд░рд╛ рдЙрддреНрдкрдиреНрди рд╡реИрдХреНрдЯрд░ рдХреЛ рдПрдХ рдКрд░реНрдЬрд╛ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рд╕рдорд╛рдирддрд╛ рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рддрд╛ рд╣реИред рд╣рдо рдПрдХ рд╕рдорд╛рд░реЛрд╣ рдХреЗ рд░реВрдк рдореЗрдВ рдпреВрдХреНрд▓рд┐рдбрд┐рдпрди рджреВрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред
рдЕрдм рдЗрди рд╕рднреА рдЪрд░рдгреЛрдВ рдкрд░ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЖрд╡рд╢реНрдпрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреЛ рдЖрдпрд╛рдд рдХрд░реЗрдВ:
import re import numpy as np from PIL import Image from sklearn.model_selection import train_test_split from keras import backend as K from keras.layers import Activation from keras.layers import Input, Lambda, Dense, Dropout, Convolution2D, MaxPooling2D, Flatten from keras.models import Sequential, Model from keras.optimizers import RMSprop
рдЕрдм рд╣рдо рдЗрдирдкреБрдЯ рдЫрд╡рд┐рдпреЛрдВ рдХреЛ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВред
read_image
рдлрд╝рдВрдХреНрд╢рди рдПрдХ рддрд╕реНрд╡реАрд░ рд▓реЗрддрд╛ рд╣реИ рдФрд░ рдПрдХ NumPy рд╕рд░рдгреА рджреЗрддрд╛ рд╣реИ:
def read_image(filename, byteorder='>'):
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрд╕ рдлрд╝реЛрдЯреЛ рдХреЛ рдЦреЛрд▓реЗрдВ:
Image.open("data/orl_faces/s1/1.pgm")

рд╣рдо рдЗрд╕реЗ
read_image
рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ
read_image
рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдПрдХ NumPy рд╕рд░рдгреА рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ:
img = read_image('data/orl_faces/s1/1.pgm') img.shape (112, 92)
рдЕрдм рд╣рдо
get_data
рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рдбреЗрдЯрд╛ рдЙрддреНрдкрдиреНрди рдХрд░реЗрдЧрд╛ред рдЖрдкрдХреЛ рдпрд╛рдж рджрд┐рд▓рд╛ рджреВрдВ рдХрд┐ рд╕реНрдпрд╛рдо рджреЗрд╢ рдХреЗ рдиреЗрдЯрд╡рд░реНрдХ рдХреЛ рдмрд╛рдЗрдирд░реА рдорд╛рд░реНрдХрд┐рдВрдЧ рдХреЗ рд╕рд╛рде рдбреЗрдЯрд╛ рдЬреЛрдбрд╝реЗ (рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдФрд░ рдЗрдВрдкреЛрд╕рд┐рдЯ) рдЬрдорд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдПрдХ рдбрд╛рдпрд░реЗрдХреНрдЯрд░реА рд╕реЗ рдЫрд╡рд┐рдпреЛрдВ (
img1
,
img2
) рдХреЛ рдкрдврд╝реЗрдВ, рдЙрдиреНрд╣реЗрдВ
x_genuine_pair,
array рдореЗрдВ рд╕реЗрд╡ рдХрд░реЗрдВ
x_genuine_pair,
y_genuine
рдХреЛ
1
рд╕реЗрдЯ рдХрд░реЗрдВред рдлрд┐рд░ рд╣рдо рдЕрд▓рдЧ-рдЕрд▓рдЧ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛рдУрдВ рд╕реЗ рдЫрд╡рд┐рдпрд╛рдВ (
img1
,
img2
)
img2
, рдЙрдиреНрд╣реЗрдВ
x_imposite,
рдЬреЛрдбрд╝реА рдореЗрдВ рд╕рд╣реЗрдЬрддреЗ рд╣реИрдВ
x_imposite,
рдФрд░
y_imposite
рдХреЛ
0
рд╕реЗрдЯ
y_imposite
ред
X
рдореЗрдВ
x_imposite
x_genuine_pair
рдФрд░
x_imposite
, рдФрд░
y_genuine
рдФрд░
y_imposite
рдореЗрдВ
Y
:
size = 2 total_sample_size = 10000 def get_data(size, total_sample_size):
рдЕрдм рд╣рдо рдбреЗрдЯрд╛ рдЙрддреНрдкрдиреНрди рдХрд░реЗрдВрдЧреЗ рдФрд░ рдЙрдирдХреЗ рдЖрдХрд╛рд░ рдХреА рдЬрд╛рдБрдЪ рдХрд░реЗрдВрдЧреЗред рд╣рдорд╛рд░реЗ рдкрд╛рд╕ 20,000 рддрд╕реНрд╡реАрд░реЗрдВ рд╣реИрдВ, рдЬрд┐рдирдореЗрдВ рд╕реЗ 10,000 рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдФрд░ 10,000 рдЭреВрдареА рдЬреЛрдбрд╝реЗ рдПрдХрддреНрд░ рдХреА рдЧрдИрдВ:
X, Y = get_data(size, total_sample_size) X.shape (20000, 2, 1, 56, 46) Y.shape (20000, 1)
рд╣рдо рдкреВрд░реА рдЬрд╛рдирдХрд╛рд░реА рд╕рд╛рдЭрд╛ рдХрд░реЗрдВрдЧреЗ: 75% рдЬреЛрдбрд╝реЗ рдкреНрд░рд╢рд┐рдХреНрд╖рдг рдореЗрдВ рдЬрд╛рдПрдВрдЧреЗ, рдФрд░ 25% рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП:
x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=.25)
рдЕрдм рдПрдХ Siamese рдиреЗрдЯрд╡рд░реНрдХ рдмрдирд╛рдПрдВред рдкрд╣рд▓реЗ рд╣рдо рдХреЛрд░ рдиреЗрдЯрд╡рд░реНрдХ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ - рдпрд╣ рдЧреБрдг рдирд┐рдХрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЬрдЯрд┐рд▓ рддрдВрддреНрд░рд┐рдХрд╛ рдиреЗрдЯрд╡рд░реНрдХ рд╣реЛрдЧрд╛ред рдПрдХ рдлреНрд▓реИрдЯ рдкрд░рдд рдХреЗ рдмрд╛рдж рдЕрдзрд┐рдХрддрдо рдкреВрд▓рд┐рдВрдЧ рдХреЗ рд╕рд╛рде ReLU рд╕рдХреНрд░рд┐рдпрдг рдФрд░ рдПрдХ рдкрд░рдд рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рджреЛ рд╕рдВрдХреЗрдВрджреНрд░рд┐рдд рдкрд░рддреЗрдВ рдмрдирд╛рдПрдВ:
def build_base_network(input_shape): seq = Sequential() nb_filter = [6, 12] kernel_size = 3
рдлрд┐рд░ рд╣рдо рдХреЛрд░ рдиреЗрдЯрд╡рд░реНрдХ рдХреА рдЫрд╡рд┐рдпреЛрдВ рдХреА рдПрдХ рдЬреЛрдбрд╝реА рдХреЛ рд╣рд╕реНрддрд╛рдВрддрд░рд┐рдд рдХрд░реЗрдВрдЧреЗ, рдЬреЛ рд╡реЗрдХреНрдЯрд░ рдирд┐рд░реВрдкрдг, рдЕрд░реНрдерд╛рдд рд╕рдВрдкрддреНрддрд┐ рд╡реИрдХреНрдЯрд░ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░ рджреЗрдВрдЧреЗ:
input_dim = x_train.shape[2:] img_a = Input(shape=input_dim) img_b = Input(shape=input_dim) base_network = build_base_network(input_dim) feat_vecs_a = base_network(img_a) feat_vecs_b = base_network(img_b)
feat_vecs_a
рдФрд░
feat_vecs_b
рдЫрд╡рд┐рдпреЛрдВ рдХреА рдПрдХ рдЬреЛрдбрд╝реА рдХреЗ рд╕рдВрдкрддреНрддрд┐ рд╡реИрдХреНрдЯрд░ рд╣реИрдВред рдЖрдЗрдП рдЙрдирдХреЗ рдмреАрдЪ рдХреА рджреВрд░реА рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдирдХреЗ рдКрд░реНрдЬрд╛ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдкрд╛рд╕ рдХрд░реЗрдВред рдФрд░ рдКрд░реНрдЬрд╛ рдХреЗ рдХрд╛рд░реНрдп рдХреЗ рд░реВрдк рдореЗрдВ, рд╣рдо рдпреВрдХреНрд▓рд┐рдбрд┐рдпрди рджреВрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ:
def euclidean_distance(vects): x, y = vects return K.sqrt(K.sum(K.square(x - y), axis=1, keepdims=True)) def eucl_dist_output_shape(shapes): shape1, shape2 = shapes return (shape1[0], 1) distance = Lambda(euclidean_distance, output_shape=eucl_dist_output_shape)([feat_vecs_a, feat_vecs_b])
рд╣рдо рдпреБрдЧреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ 13 рдкрд░ рд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВ, рдЕрдиреБрдХреВрд▓рди рдХреЗ рд▓рд┐рдП RMS рд╕рдВрдкрддреНрддрд┐ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдореЙрдбрд▓ рдШреЛрд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ:
epochs = 13 rms = RMSprop() model = Model(input=[input_a, input_b], output=distance)
рдЕрдм рд╣рдо рд▓реЙрд╕ рдлрдВрдХреНрд╢рди
contrastive_loss
рдлрдВрдХреНрд╢рди рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдореЙрдбрд▓ рдХреЛ рд╕рдВрдХрд▓рд┐рдд рдХрд░рддреЗ рд╣реИрдВ:
def contrastive_loss(y_true, y_pred): margin = 1 return K.mean(y_true * K.square(y_pred) + (1 - y_true) * K.square(K.maximum(margin - y_pred, 0))) model.compile(loss=contrastive_loss, optimizer=rms)
рдЖрдЗрдП рдореЙрдбрд▓ рдХрд╛ рдЕрдзреНрдпрдпрди рдХрд░реЗрдВ:
img_1 = x_train[:, 0] img_2 = x_train[:, 1] model.fit([img_1, img_2], y_train, validation_split=.25, batch_size=128, verbose=2, nb_epoch=epochs)
рдЖрдк рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдПрд░рд╕ рдкрд╛рд╕ рдХреЗ рд░реВрдк рдореЗрдВ рдиреБрдХрд╕рд╛рди рдХреИрд╕реЗ рдХрдо рд╣реЛрддрд╛ рд╣реИ:
Train on 11250 samples, validate on 3750 samples Epoch 1/13 - 60s - loss: 0.2179 - val_loss: 0.2156 Epoch 2/13 - 53s - loss: 0.1520 - val_loss: 0.2102 Epoch 3/13 - 53s - loss: 0.1190 - val_loss: 0.1545 Epoch 4/13 - 55s - loss: 0.0959 - val_loss: 0.1705 Epoch 5/13 - 52s - loss: 0.0801 - val_loss: 0.1181 Epoch 6/13 - 52s - loss: 0.0684 - val_loss: 0.0821 Epoch 7/13 - 52s - loss: 0.0591 - val_loss: 0.0762 Epoch 8/13 - 52s - loss: 0.0526 - val_loss: 0.0655 Epoch 9/13 - 52s - loss: 0.0475 - val_loss: 0.0662 Epoch 10/13 - 52s - loss: 0.0444 - val_loss: 0.0469 Epoch 11/13 - 52s - loss: 0.0408 - val_loss: 0.0478 Epoch 12/13 - 52s - loss: 0.0381 - val_loss: 0.0498 Epoch 13/13 - 54s - loss: 0.0356 - val_loss: 0.0363
рдФрд░ рдЕрдм рдкрд░реАрдХреНрд╖рдг рдбреЗрдЯрд╛ рдкрд░ рдореЙрдбрд▓ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рддреЗ рд╣реИрдВ:
pred = model.predict([x_test[:, 0], x_test[:, 1]])
рд╕рдЯреАрдХрддрд╛ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВ:
def compute_accuracy(predictions, labels): return labels[predictions.ravel()
рд╣рдо рд╕рдЯреАрдХрддрд╛ рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВ:
compute_accuracy(pred, y_test) 0.9779092702169625
рдирд┐рд╖реНрдХрд░реНрд╖
рдЗрд╕ рдЧрд╛рдЗрдб рдореЗрдВ, рд╣рдордиреЗ рд╕реАрдЦрд╛ рдХрд┐ рдХреИрд╕реЗ рд╕реНрдпрд╛рдо рджреЗрд╢ рдиреЗрдЯрд╡рд░реНрдХ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдлреЗрд╕ рд░рд┐рдХрдЧреНрдирд┐рд╢рди рдореЙрдбрд▓ рдмрдирд╛рдпрд╛ рдЬрд╛рдПред рдРрд╕реЗ рдиреЗрдЯрд╡рд░реНрдХ рдХреА рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдореЗрдВ рджреЛ рд╕рдорд╛рди рддрдВрддреНрд░рд┐рдХрд╛ рдиреЗрдЯрд╡рд░реНрдХ рд╣реЛрддреЗ рд╣реИрдВ рдЬрд┐рдирдХрд╛ рд╡рдЬрди рдФрд░ рд╕рдВрд░рдЪрдирд╛ рд╕рдорд╛рди рд╣реЛрддреА рд╣реИ, рдФрд░ рдЙрдирдХреЗ рдХрд╛рдо рдХреЗ рдкрд░рд┐рдгрд╛рдо рдПрдХ рд╣реА рдКрд░реНрдЬрд╛ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рд╣реЛрддреЗ рд╣реИрдВ - рдпрд╣ рдЗрдирдкреБрдЯ рдбреЗрдЯрд╛ рдХреА рдкрд╣рдЪрд╛рди рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИред
рдкрд╛рдпрдерди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдореЗрдЯрд╛-рд▓рд░реНрдирд┐рдВрдЧ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдП
, рдкрд╛рдпрдерди рдХреЗ рд╕рд╛рде рд╣реИрдВрдбреНрд╕-рдСрди рдореЗрдЯрд╛-рд▓рд░реНрдирд┐рдВрдЧ рджреЗрдЦреЗрдВредрдореЗрд░реА рдЯрд┐рдкреНрдкрдгреА
рдЫрд╡рд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╕рдордп рд╡рд░реНрддрдорд╛рди рдореЗрдВ Siamese рдиреЗрдЯрд╡рд░реНрдХ рдХрд╛ рдЬреНрдЮрд╛рди рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдЫреЛрдЯреЗ рдирдореВрдиреЛрдВ, рдирдИ рдбреЗрдЯрд╛ рдкреАрдврд╝реА, рд╡реГрджреНрдзрд┐ рд╡рд┐рдзрд┐рдпреЛрдВ рдореЗрдВ рдкреНрд░рд╢рд┐рдХреНрд╖рдг рдиреЗрдЯрд╡рд░реНрдХ рдХреЗ рдХрдИ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╣реИрдВред рдпрд╣ рд╡рд┐рдзрд┐ рдЕрдкреЗрдХреНрд╖рд╛рдХреГрдд рдЕрдЪреНрдЫреЗ рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП "рд╕рд╕реНрддреЗ" рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИ, рдпрд╣рд╛рдБ рддрдВрддреНрд░рд┐рдХрд╛ рдиреЗрдЯрд╡рд░реНрдХ рдХреЗ рд▓рд┐рдП "рд╣реИрд▓реЛ рд╡рд░реНрд▓реНрдб" рдкрд░ рд╕рд┐рдпрд╛рдореА рдиреЗрдЯрд╡рд░реНрдХ рдХрд╛ рдПрдХ рдФрд░ рдЙрддреНрдХреГрд╖реНрдЯ рдЙрджрд╛рд╣рд░рдг рд╣реИ - рдбрд╛рдЯрд╛рд╕реЗрдЯ MNIST
keras.io/examples/mnist_siamese