![](/img/trans.png)
[英]Siamese Network with Cosine Similarity in Keras with 'mse' loss (Updated)
[英]Keras. Siamese network and triplet loss
我想建立一個應該能夠驗證圖像(例如人臉)的網絡。 據我了解,最好的解決方案是具有三重損失的連體網絡。 我沒有找到任何現成的實現,所以我決定創建自己的。
但我對 Keras 有疑問。 例如,這里是網絡的結構:
代碼是這樣的:
embedding = Sequential([
Flatten(),
Dense(1024, activation='relu'),
Dense(64),
Lambda(lambda x: K.l2_normalize(x, axis=-1))
])
input_a = Input(shape=shape, name='anchor')
input_p = Input(shape=shape, name='positive')
input_n = Input(shape=shape, name='negative')
emb_a = embedding(input_a)
emb_p = embedding(input_p)
emb_n = embedding(input_n)
out = Concatenate()([emb_a, emb_p, emp_n])
model = Model([input_a, input_p, input_n], out)
model.compile(optimizer='adam', loss=<triplet_loss>)
我只定義了一個嵌入模型。 這是否意味着一旦模型開始訓練,每個輸入的權重都會相同?
如果是,我如何從model
提取嵌入權重?
是的,在三元組損失函數中,權重應該在所有三個網絡之間共享,即Anchor、Positive 和 Negetive 。 在 Tensorflow 1.x 中,您可以在tf.layers
使用reuse=True
來實現權重共享。
但是在 Tensorflow 2.x 中,因為tf.layers
已移至tf.keras.layers
並且reuse
功能已被刪除。 為了實現權重共享,您可以編寫一個自定義層,該層采用父層並重用其權重。
下面是執行相同操作的示例示例。
class SharedConv(tf.keras.layers.Layer):
def __init__(
self,
filters,
kernel_size,
strides=None,
padding=None,
dilation_rates=None,
activation=None,
use_bias=True,
**kwargs
):
self.filters = filters
self.kernel_size = kernel_size
self.strides = strides
self.padding = padding
self.dilation_rates = dilation_rates
self.activation = activation
self.use_bias = use_bias
super().__init__(*args, **kwargs)
def build(self, input_shape):
self.conv = Conv2D(
self.filters,
self.kernel_size,
padding=self.padding,
dilation_rate=self.dilation_rates[0]
)
self.net1 = Activation(self.activation)
self.net2 = Activation(self.activation)
def call(self, inputs, **kwargs):
x1 = self.conv(inputs)
x1 = self.act1(x1)
x2 = tf.nn.conv2d(
inputs,
self.conv.weights[0],
padding=self.padding,
strides=self.strides,
dilations=self.dilation_rates[1]
)
if self.use_bias:
x2 = x2 + self.conv.weights[1]
x2 = self.act2(x2)
return x1, x2
我將回答如何提取嵌入(參考我的 Github 帖子):
我訓練的siamese_model.summary()
模型如下所示: siamese_model.summary()
請注意,我新定義的模型與以黃色突出顯示的模型基本相同
然后我重新定義了我想用於提取嵌入的模型(它應該與您定義的模型相同,但現在它不會有像 siamese 這樣的多個輸入),如下所示:
siamese_embeddings_model = build_siamese_model(input_shape)
siamese_embeddings_model .summary()
然后我只是從我訓練的 siamese 模型中提取權重並將它們設置到我的新模型中
embeddings_weights = siamese_model.layers[-3].get_weights()
siamese_embeddings_model.set_weights(embeddings_weights )
然后您可以提供新圖像以從新模型中提取嵌入
vector = siamese.predict(image)
len(vector[0])
它將打印 150 因為我的細密層(這是輸出向量)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.