Tensorflow 如何在Keras或Tf 2中为基于ResNet50的暹罗网络应用三重态损耗
我有一个基于Tensorflow 如何在Keras或Tf 2中为基于ResNet50的暹罗网络应用三重态损耗,tensorflow,machine-learning,keras,deep-learning,conv-neural-network,Tensorflow,Machine Learning,Keras,Deep Learning,Conv Neural Network,我有一个基于ResNet的siamese网络,它使用的思想是,你尝试最小化两幅图像之间的l-2距离,然后应用一个sigmoid,这样它会给你{0:'same',1:'different'}输出,并基于预测的距离,您只需将渐变流回到网络,但存在一个问题,即渐变的更新太少,因为我们正在更改{0,1}之间的距离,所以我考虑使用相同的架构,但基于三重态丢失 I1 = Input(shape=image_shape) I2 = Input(shape=image_shape) r
ResNet
的siamese
网络,它使用的思想是,你尝试最小化两幅图像之间的l-2
距离,然后应用一个sigmoid,这样它会给你{0:'same',1:'different'}
输出,并基于预测的距离,您只需将渐变流回到网络,但存在一个问题,即渐变的更新太少,因为我们正在更改{0,1}
之间的距离,所以我考虑使用相同的架构,但基于三重态丢失
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)
那么,如何将其更改为使用三重丢失功能
?为了完成这项工作,这里应该做哪些调整?一个变化是我必须计算
res_m_3 = ResNet50(include_top=False, weights='imagenet', input_tensor=I2, pooling='avg')
x3 = res_m_3.output
tf文档中发现的一件事是三重半硬损耗
,如下所示:
tfa.loss.TripletSemiHardLoss()
如本文所示,最好的结果来自于被称为“半硬”的三胞胎。这些被定义为三联体,其中负片比正片离锚更远,但仍然产生正损耗。为了有效地找到这些三胞胎,我们利用在线学习,只从每个批次的半硬示例中进行训练
我在Kaggle上发现的三重态丢失的另一个实现是:
我应该使用哪一个,最重要的是,如何使用
附言:人们也会在模型输出后使用这样的东西:x=Lambda(Lambda x:K.l2_normalize(x,axis=1))(x)
。为什么呢?这是做什么的?接下来,考虑到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)
我不熟悉三重态损耗,但你能说这些例子中是否有任何一个与“三重态损耗”对应吗?我没有资格说什么是或不是三重态损耗,但如果是,我肯定可以告诉你如何使用它。你能告诉我基于暹罗的网络可以建立吗?使用我现有的或其他一些体系结构?正如我在最近的文章中提到的,是否有一项出色的工作向您展示了如何使用TripletSemiHardLoss
,所以在使用它时是否仍然存在此问题?在使用之前,我问了这个问题。您能告诉我如何制作数据集,以便在model.compile()
中直接使用这些损失,或者手动制作硬/半数据集并传入简单的三重损失
?我会把赏金给你的。我从那里得到了答案。出于好奇,我留下了一些评论。看看这个关于堆栈溢出的答案是否有帮助-PS:我试图向您展示输出,但我无法在短时间内用我的笔记本电脑或在Colab完成训练,使用ResNet50时速度太慢了:(但你只使用了一个网络。对吗?是的,一个网络就足够了,tfa.loss.tripletsimhardloss
注意所有细节