Come fa il mio iPhone a sapere che sono io?

Articolo in lingua originale di Eeswarez

Vi siete mai chiesti come fa Face Detection di iPhone a sapere che siete voi senza sbagliare mai, ovvero senza mai confondere qualcun altro per voi?

E’ grazie al Machine Leaarning! Beh c’è molto lavoro dietro ad iPhone per permettere di fargli capire che siete voi e non semplicemente una vostra foto.

In questo articolo parlerò di uno di quegli algoritmi e architetture di ML che è molto efficace per il riconoscimento facciale.

 

Le reti siamesi, ispirate ai gemelli siamesi, sono un tipo di architettura di rete neurale che classifica naturalmente la somiglianza o la dissomiglianza tra gli input. L’architettura prevede l’utilizzo di due o più reti neurali simili, il che significa che hanno la stessa configurazione con gli stessi parametri e pesi, cioè l’addestramento viene eseguito per una sotto-rete e la stessa configurazione viene utilizzata per le altre sotto-reti; queste sotto-reti vengono utilizzate per trovare la somiglianza tra gli input confrontando i loro feature vectors.

Rao, S.J., Wang, Y., & Cottrell, G. (2016), A Deep Siamese Neural Network Learns the Human-Perceived Similarity Structure of Facial Expressions Without Explicit Categories. Cognitive Science.

Per il riconoscimento facciale che sfrutta la rete siamese, a una delle sottoreti viene passato il volto dell’utente dell’iPhone e viene creata una rappresentazione sotto forma di vettore. La volta successiva, quando sarà necessario autenticare l’identità, l’immagine del volto in questione verrà fatta passare attraverso un’altra sottorete che è esattamente uguale alla configurazione della prima sottorete, ottenendo così una rappresentazione vettoriale.

Utilizzando le due codifiche, la rete confronta i risultati sulla distanza o della funzione di perdita di paragone, una distanza maggiore o minore consente il riconoscimento facciale.

 

Possiamo aggiungere un layer in più aumentando la complessità in modo da poter utilizzare una funzione di perdita tripla che identifica anche di quanto simili sono gli input.

Output della rete

Come abbiamo ottenuto questo risultato? Continuate a leggere!

Utilizzerà il pachetto tensorflow per la costruzione del modello, utilizzerò una rete neurale convoluzionale come modello per le sottoreti.

Pre elaborazione delle immagini:

def preprocess_image(filename):
image_string = tf.io.read_file(filename)
image = tf.image.decode_jpeg(image_string, channels=3)
image = tf.image.convert_image_dtype(image, tf.float32)
image = tf.image.resize(image, target_shape)
return image




def preprocess_triplets(base, comp_1, comp_2):
return (
preprocess_image(base),
preprocess_image(comp_1),
preprocess_image(comp_2),
)

base_images = sorted
[str(base_images_path / f) for f in os.listdir(base_images_path)]
)


comp_1_images = sorted(
[str(comp_1_images_path / f) for f in os.listdir(comp_1_images_path)]
)


image_count = len(base_images)


base_dataset = tf.data.Dataset.from_tensor_slices(base_images)
comp_1_dataset = tf.data.Dataset.from_tensor_slices(comp_1_images)


# To generate the list of negative images, let's randomize the list of
# available images and concatenate them together.
rng = np.random.RandomState(seed=42)
rng.shuffle(base_images)
rng.shuffle(comp_1_images)


comp_2_images = base_images + comp_1_images
np.random.RandomState(seed=32).shuffle(comp_2_images)


comp_2_dataset = tf.data.Dataset.from_tensor_slices(comp_2_images)
comp_2_dataset = comp_2_dataset.shuffle(buffer_size=4096)


dataset = tf.data.Dataset.zip((base_dataset, comp_1_dataset, comp_2_dataset))
dataset = dataset.shuffle(buffer_size=1024)
dataset = dataset.map(preprocess_triplets)


# Let's now split our dataset in train and validation.
train = dataset.take(round(image_count * 0.8))
val = dataset.skip(round(image_count * 0.8))


train = train.batch(32, drop_remainder=False)
train = train.prefetch(8)


val = val.batch(32, drop_remainder=False)
val = val.prefetch(8)
Dati di training (Totally Looks Like dataset by Rosenfeld et al., 2018)

Setup del modello:

base_cnn = resnet.ResNet50(

weights="imagenet", input_shape=target_shape + (3,), include_top=False

)





flatten = layers.Flatten()(base_cnn.output)

dense1 = layers.Dense(512, activation="relu")(flatten)

dense1 = layers.BatchNormalization()(dense1)

dense2 = layers.Dense(256, activation="relu")(dense1)

dense2 = layers.BatchNormalization()(dense2)

output = layers.Dense(256)(dense2)





embedding = Model(base_cnn.input, output, name="Embedding")





trainable = False

for layer in base_cnn.layers:

if layer.name == "conv5_block1_out":

     trainable = True

layer.trainable = trainable




Modello di rete Siamese:

snm = Model(

inputs=[base_input, comp_1_input, comp_2_input], outputs=distances

)

Addestramento:

sm = SModel(snm)

sm.compile(optimizer=optimizers.Adam(0.0001))

sm.fit(train, epochs=10, validation_data=val)

 

Pronti a partire!

Share:

Contenuti
Torna in alto