Как реализовать потерю триплетов с помощью Connet в Keras
Я пытался реализовать функцию потери триплета в Keras в фиктивном наборе данных, который я создал. Я следил за несколькими источниками, включая похожие проблемы со Stackru, но независимо от того, что я делаю, я не могу заставить его работать. Более конкретно, я попытался повторить это.
Вот мой полный код:
ALPHA = 0.2 # Triplet Loss Parameter
input_shape = Input(shape=(80, 26, 1))
def fake_loss(X):
item, _,_ = X
# item = X
loss = K.sum(ALPHA * item, axis=-1, keepdims=True)
print(loss.shape)
return loss
def triplet_loss_function(x):
anchor, positive, negative = x
pos_dist = K.sum(K.square(anchor-positive), 1)
neg_dist = K.sum(K.square(anchor-negative), 1)
basic_loss = pos_dist-neg_dist + ALPHA
basic_loss = K.sum(pos_dist, neg_dist, ALPHA)
print(basic_loss.shape)
loss = K.mean(K.maximum(basic_loss, 0.0), 0)
return loss
def triplet_loss_f2(x):
anchor, positive, negative = x
pos_dist = tf.reduce_sum(tf.square(tf.subtract(anchor, positive)), 1)
neg_dist = tf.reduce_sum(tf.square(tf.subtract(anchor, negative)), 1)
basic_loss = tf.add(tf.subtract(pos_dist, neg_dist), ALPHA)
loss = tf.reduce_mean(tf.maximum(basic_loss, 0.0), 0)
print(loss.shape)
return loss
def build_model(input_shape):
anchor, positive, negative = Pipeline()
input_shape = Input(shape=(80, 26,1))
conv1 = Conv2D(64, kernel_size=4, activation='relu')(input_shape)
conv2 = MaxPooling2D(pool_size=(3, 3))(conv11)
conv3 = Conv2D(32, kernel_size=4, activation='relu')(conv2)
conv4 = MaxPooling2D(pool_size=(2, 2))(conv3)
flat1 = Flatten()(conv4)
hidden1 = Dense(64, activation='relu')(flat1)
d1 = Dropout(rate=0.4, name="dropout1")(hidden1)
hidden2 = Dense(32, activation='relu')(d1)
# Create Common network to share the weights along different examples (+/-/Anchor)
embedding_network = Model(input_shape, hidden2)
print('done')
positive_example = Input(shape=(80, 26, 1))
negative_example = Input(shape=(80, 26, 1))
anchor_example = Input(shape=(80, 26, 1))
positive_embedding = embedding_network(positive_example)
negative_embedding = embedding_network(negative_example)
anchor_embedding = embedding_network(anchor_example)
#loss = Lambda(triplet_loss_function)([anchor_embedding,positive_embedding,negative_embedding])
loss = merge([anchor_embedding, positive_embedding, negative_embedding],mode=triplet_loss_f2, output_shape=(1,))
print('done')
output = Dense(1, activation='sigmoid')(loss)
model = Model(inputs=[anchor_example, positive_example, negative_example],outputs=output)
model.compile(loss='mean_square_error', optimizer=Adam())
model.fit([anchor, positive, negative], np.ones(100)*0, epochs=10,batch_size=2048)
def toydataset():
X, y = make_blobs(n_samples=80, centers=1, n_features=26)
return X,y
def Pipeline():
X1 = list()
X2 = list()
X3 = list()
Y = list()
for j in range(100):
x1,y1 = toydataset()
X1.append(x1)
x2,y2 = toydataset()
X2.append(x2)
x3,y3 = toydataset()
X3.append(x3)
X1 = np.asarray(X1).reshape(100, 80, 26, 1)
X2 = np.asarray(X2).reshape(100, 80, 26, 1)
X3 = np.asarray(X3).reshape(100, 80, 26, 1)
Y = np.ones(300)*0
return X1,X2, X3
build_model(input_shape)
Я получаю несколько ошибок, когда я возиться с этим кодом. Как вы можете заметить, у меня есть разные способы реализации этого. Один из них - это вызов уровня слияния Keras, а другой - вызов слоя Keras Lambda. Кроме того, у меня есть две разные функции потери триплета, одна использует операции Tensorflow (triplet_loss_f2
) и один, использующий бэкэнд Keras. Когда я запускаю приведенный выше код со слоем слияния и внутренними операциями Keras, я получаю:
TypeError: Expected bool for argument 'keep_dims' not 0.2.
Когда я пытаюсь сделать это с помощью слоя слияния + операций Tensorflow или lambda +Tensorflow, я получаю эту ошибку:
ValueError: Input 0 is incompatible with layer dense_3: expected min_ndim=2, found ndim=0
Когда я запускаю его с Lambda layer + Keras backend, я получаю эту ошибку:
TypeError: Expected bool for argument 'keep_dims' not 0.2.
Я создал 3 массива данных с формой (100,80,26,1)
и попробовал все варианты, которые я мог придумать. Я также создал fake_loss
функции, и я должен сказать, что это единственный, который сделал это на самом деле обучение. Конечно, я хочу, чтобы настоящая вещь работала. Я не полностью понимаю ни Tensorflow, ни бэкэнд Keras, но я следовал инструкциям, и он все еще не работает. Есть идеи, как это сделать?