הפסדי תוספות TensorFlow: TripletSemiHardLoss

הצג באתר TensorFlow.org הפעל בגוגל קולאב צפה במקור ב-GitHub הורד מחברת

סקירה כללית

מחברת זו תדגים כיצד להשתמש בפונקציית TripletSemiHardLoss בתוספות TensorFlow.

אֶמְצָעִי:

TripletLoss

כפי שהוצג לראשונה במאמר FaceNet, TripletLoss היא פונקציית אובדן המאמנת רשת עצבית להטמיע מקרוב תכונות של אותה מחלקה תוך מיקסום המרחק בין הטבעות של מחלקות שונות. לשם כך נבחר עוגן יחד עם מדגם אחד שלילי ואחד חיובי. איור 3

פונקציית ההפסד מתוארת כפונקציית מרחק אוקלידית:

פוּנקצִיָה

כאשר A הוא קלט העוגן שלנו, P הוא קלט הדגימה החיובי, N הוא קלט הדגימה השלילי, ואלפא הוא שוליים שבהם אתה משתמש כדי לציין מתי שלישייה הפכה ל"קלה" מדי ואינך רוצה יותר להתאים את המשקולות ממנו .

למידה מקוונת למחצה

כפי שמוצג במאמר, התוצאות הטובות ביותר הן משלישיות המכונה "חצי-קשה". אלה מוגדרים כשלישיות שבהן השלילי רחוק יותר מהעוגן מהחיובי, אך עדיין מייצר הפסד חיובי. כדי למצוא ביעילות את השלשות האלה, אתה משתמש בלמידה מקוונת ומתאמן רק מהדוגמאות החצי-קשות בכל אצווה.

להכין

pip install -q -U tensorflow-addons
import io
import numpy as np
import tensorflow as tf
import tensorflow_addons as tfa
import tensorflow_datasets as tfds

הכן את הנתונים

def _normalize_img(img, label):
    img = tf.cast(img, tf.float32) / 255.
    return (img, label)

train_dataset, test_dataset = tfds.load(name="mnist", split=['train', 'test'], as_supervised=True)

# Build your input pipelines
train_dataset = train_dataset.shuffle(1024).batch(32)
train_dataset = train_dataset.map(_normalize_img)

test_dataset = test_dataset.batch(32)
test_dataset = test_dataset.map(_normalize_img)
Downloading and preparing dataset 11.06 MiB (download: 11.06 MiB, generated: 21.00 MiB, total: 32.06 MiB) to /home/kbuilder/tensorflow_datasets/mnist/3.0.1...
Dataset mnist downloaded and prepared to /home/kbuilder/tensorflow_datasets/mnist/3.0.1. Subsequent calls will reuse this data.

בנה את המודל

איור 2

model = tf.keras.Sequential([
    tf.keras.layers.Conv2D(filters=64, kernel_size=2, padding='same', activation='relu', input_shape=(28,28,1)),
    tf.keras.layers.MaxPooling2D(pool_size=2),
    tf.keras.layers.Dropout(0.3),
    tf.keras.layers.Conv2D(filters=32, kernel_size=2, padding='same', activation='relu'),
    tf.keras.layers.MaxPooling2D(pool_size=2),
    tf.keras.layers.Dropout(0.3),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(256, activation=None), # No activation on final dense layer
    tf.keras.layers.Lambda(lambda x: tf.math.l2_normalize(x, axis=1)) # L2 normalize embeddings

])

לאמן ולהעריך

# Compile the model
model.compile(
    optimizer=tf.keras.optimizers.Adam(0.001),
    loss=tfa.losses.TripletSemiHardLoss())
# Train the network
history = model.fit(
    train_dataset,
    epochs=5)
Epoch 1/5
1875/1875 [==============================] - 21s 5ms/step - loss: 0.6983
Epoch 2/5
1875/1875 [==============================] - 8s 4ms/step - loss: 0.4723
Epoch 3/5
1875/1875 [==============================] - 8s 4ms/step - loss: 0.4298
Epoch 4/5
1875/1875 [==============================] - 8s 4ms/step - loss: 0.4139
Epoch 5/5
1875/1875 [==============================] - 8s 4ms/step - loss: 0.3938
# Evaluate the network
results = model.predict(test_dataset)
# Save test embeddings for visualization in projector
np.savetxt("vecs.tsv", results, delimiter='\t')

out_m = io.open('meta.tsv', 'w', encoding='utf-8')
for img, labels in tfds.as_numpy(test_dataset):
    [out_m.write(str(x) + "\n") for x in labels]
out_m.close()


try:
  from google.colab import files
  files.download('vecs.tsv')
  files.download('meta.tsv')
except:
  pass

מקרן הטבעה

קבצי הווקטור מטה ניתנים לטעינה מדמיינים כאן: https://projector.tensorflow.org/

אתה יכול לראות את התוצאות של נתוני הבדיקה המוטבעים שלנו כאשר הם מוצגים באמצעות UMAP: הטבעה