如何在Keras或TensorFlow 2中将三元组损失应用于基于ResNet50的孪生网络

我有一个基于ResNetsiamese网络,它使用了最小化两张图像之间的l-2距离的想法,然后应用一个sigmoid函数,使其输出{0:'same',1:'different'},并且根据预测的距离,你可以将梯度反馈到网络中,但问题是梯度的更新非常小,因为我们是在改变{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函数?这里需要做哪些调整来实现这一点?一个变化将是我必须计算

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 Loss实现是:Triplet Loss Keras

我应该使用哪个,最重要的是,如何使用?

附注:人们还在model.output之后使用类似于x = Lambda(lambda x: K.l2_normalize(x,axis=1))(x)的东西。这是为什么?这是在做什么?


回答:

根据我这个回答,并考虑到TripletSemiHardLoss的作用,我们可以这样做:

import tensorflow as tfimport tensorflow_addons as tfaimport tensorflow_datasets as tfdsfrom tensorflow.keras import models, layersBATCH_SIZE = 32LATENT_DEM = 128def _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 pipelinestrain_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 layeroutputs = layers.Lambda(lambda x: tf.math.l2_normalize(x, axis=1))(outputs) # L2 normalize embeddingsiamese_model = models.Model(inputs=inputs, outputs=outputs)# Compile the modelsiamese_model.compile(    optimizer=tf.keras.optimizers.Adam(0.001),    loss=tfa.losses.TripletSemiHardLoss())# Train the networkhistory = siamese_model.fit(    train_dataset,    epochs=3)

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注