Я реализовал сиамскую сеть на примере Keras.Мой код выглядит следующим образом:
def contrastive_loss(y_true, y_pred):
'''Contrastive loss from Hadsell-et-al.'06
http://yann.lecun.com/exdb/publis/pdf/hadsell-chopra-lecun-06.pdf
'''
margin = 1
return K.mean(y_true * K.square(y_pred) + (1 - y_true) * K.square(K.maximum(margin - y_pred, 0)))
def create_base_network(input_dim):
'''Base network to be shared (eq. to feature extraction).
'''
seq = Sequential()
seq.add(Dense(128, input_shape=(input_dim,), activation='relu'))
seq.add(Dropout(0.1))
seq.add(Dense(128, activation='relu'))
seq.add(Dropout(0.1))
seq.add(Dense(128, activation='relu'))
return seq
def euclidean_distance(vects): #replace this with the code from tensorflow
x, y = vects
return K.sqrt(K.sum(K.square(x - y), axis=1, keepdims=True))
def eucl_dist_output_shape(shapes):
shape1, shape2 = shapes
return (shape1[0], 2)
============================ Основная часть ===============================
input_dim = 9216
nb_epoch = 3
# network definition
base_network = create_base_network(input_dim)
input_a = Input(shape=(input_dim,))
input_b = Input(shape=(input_dim,))
# because we re-use the same instance `base_network`,
# the weights of the network
# will be shared across the two branches
processed_a = base_network(input_a)
processed_b = base_network(input_b)
distance = Lambda(euclidean_distance, output_shape=eucl_dist_output_shape)([processed_a, processed_b])
model = Model(inputs=[input_a, input_b], outputs=distance)
# train
model.compile(loss=contrastive_loss, optimizer='RMSprop', metrics=['accuracy'])
model.fit([tr_pair1_reshaped, tr_pair2_reshaped],y_train_categorical, epochs=nb_epoch, batch_size=64,verbose=1)
=====================================================================
The results I am getting are as follows:
Epoch 1/3
3000/3000 [==============================] - 1s 368us/step - loss: 3.8701 - acc: 0.5000
Epoch 2/3
3000/3000 [==============================] - 1s 169us/step - loss: 0.5310 - acc: 0.5000
Epoch 3/3
3000/3000 [==============================] - 1s 167us/step - loss: 0.4727 - acc: 0.5000
Таким образом, здесь целью является сопоставление изображений, следовательно, двоичная классификация.Точность 50% здесь, вероятно, означает, что не учился вообще.Я использую to_categorical для совпадающих или не совпадающих ярлыков.Я также попробовал contrastive_loss, а также функцию потери categoryor_crossentropy, но результаты остались прежними, оптимизаторы "adam" и "rmsProp" также не имеют значения.Всего данных для обучения около 40к.поэтому я пробовал разные размеры партии тоже без разницы.Так, где я копаюсь, чтобы пойти в корень проблемы?У кого-нибудь есть намеки на меня?Я был бы очень благодарен.:)