[英]How to apply Triplet Loss for a ResNet50 based Siamese Network in Keras or Tf 2
我有一個基於ResNet
的siamese
網絡,它使用的想法是,您嘗試最小化 2 個圖像之間的l-2
距離,然后應用 sigmoid,以便它為您提供{0:'same',1:'different'}
output 和基於關於預測有多遠,您只需將梯度流回網絡,但有一個問題是梯度更新太少,因為我們正在改變{0,1}
之間的距離,所以我想使用相同的架構,但基於關於Triplet Loss
。
I1 = Input(shape=image_shape)
I2 = Input(shape=image_shape)
res_m_1 = ResNet50(include_top=False, weights='imagenet', input_tensor=I1, pooling='avg')
res_m_2 = ResNet50(include_top=False, weights='imagenet', input_tensor=I2, pooling='avg')
x1 = res_m_1.output
x2 = res_m_2.output
# x = Flatten()(x) or use this one if not using any pooling layer
distance = Lambda( lambda tensors : K.abs( tensors[0] - tensors[1] )) ([x1,x2] )
final_output = Dense(1,activation='sigmoid')(distance)
siamese_model = Model(inputs=[I1,I2], outputs=final_output)
siamese_model.compile(loss='binary_crossentropy',optimizer=Adam(),metrics['acc'])
siamese_model.fit_generator(train_gen,steps_per_epoch=1000,epochs=10,validation_data=validation_data)
那么如何將其更改為使用Triplet Loss function
呢? 為了完成這項工作,應該在此處進行哪些調整? 一個變化是我必須計算
res_m_3 = ResNet50(include_top=False, weights='imagenet', input_tensor=I2, pooling='avg')
x3 = res_m_3.output
在 tf 文檔中發現的一件事是triplet-semi-hard-loss
,給出如下:
tfa.losses.TripletSemiHardLoss()
如論文所示,最好的結果來自被稱為“半硬”的三元組。 這些被定義為三元組,其中負數比正數離錨點更遠,但仍會產生正損失。 為了有效地找到這些三元組,我們利用在線學習,並且只從每批中的半困難示例中進行訓練。
我在 Kaggle 上找到的 Triplet Triplet Loss
的另一個實現是: Triplet Loss Keras
我應該使用哪一個,最重要的是,如何?
PS:人們還使用類似的東西: x = Lambda(lambda x: K.l2_normalize(x,axis=1))(x)
在model.output
之后。 這是為什么? 這是在做什么?
按照我的這個答案,並考慮到TripletSemiHardLoss
的作用,我們可以執行以下操作:
import tensorflow as tf
import tensorflow_addons as tfa
import tensorflow_datasets as tfds
from tensorflow.keras import models, layers
BATCH_SIZE = 32
LATENT_DEM = 128
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(BATCH_SIZE)
train_dataset = train_dataset.map(_normalize_img)
test_dataset = test_dataset.batch(BATCH_SIZE)
test_dataset = test_dataset.map(_normalize_img)
inputs = layers.Input(shape=(28, 28, 1))
resNet50 = tf.keras.applications.ResNet50(include_top=False, weights=None, input_tensor=inputs, pooling='avg')
outputs = layers.Dense(LATENT_DEM, activation=None)(resNet50.output) # No activation on final dense layer
outputs = layers.Lambda(lambda x: tf.math.l2_normalize(x, axis=1))(outputs) # L2 normalize embedding
siamese_model = models.Model(inputs=inputs, outputs=outputs)
# Compile the model
siamese_model.compile(
optimizer=tf.keras.optimizers.Adam(0.001),
loss=tfa.losses.TripletSemiHardLoss())
# Train the network
history = siamese_model.fit(
train_dataset,
epochs=3)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.