Я пытаюсь внедрить некоторые данные, которые у меня есть, используя Keras. У меня есть модель, состоящая только из слоя внедрения, а затем у меня есть своя собственная пользовательская функция потерь, которая использует веса слоя внедрения для вычисления функции потерь, однако сеть вообще не будет обучаться, то есть значение потерь всегда одно и то же.
Моя функция потерь выглядит следующим образом
def custom_loss(a,b):
layer = model.layers[0].get_weights()[0]
distances = [distance(layer[i],layer[j]) for i in range(len(layer)-1) for j in range(i+1, len(layer))]
loss = [-math.log10(sims[i]*distances[i])for i in range(len(sims))]
return K.sum(loss)+0*K.sum(b)
model.compile(optimizer="rmsprop",loss=custom_loss)
Я получаю расстояния между различными n-мерными значениями вложения для всех разных точек, которые я передаю в слой вложения. У меня есть +0*K.sum(b)
, потому что в противном случае я получаю исключение без градиента. sims
- это список значений, на которые я умножаю расстояния. loss
заканчивается списком с плавающей точкой.
Я не получаю никаких исключений, однако потеря просто постоянна. Что может быть не так? Я должен сказать, что я не очень хорошо знаком с созданием пользовательских функций потерь, таких как это, в Keras, поэтому то, что я сделал, может быть совершенно неверным. Опять же, я заинтересован только в получении встраивания с моей пользовательской функцией потерь. Я знаю, что в основном злоупотребляю Keras, чтобы не писать свою собственную функцию оптимизации.
Мой K.sum(loss)
просто не дает градиента? Интуиция подсказывает мне, что layer = model.layers[0].get_weights()[0]
просто не обновляется между партиями, но я не знаю, правильно ли это, или если да, то как это исправить. Есть ли другой способ получить доступ к весам, которые будут работать?
Сводная информация о сети выглядит следующим образом
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
embedding_1 (Embedding) (None, 400, 3) 1200
=================================================================
Total params: 1,200
Trainable params: 1,200
Non-trainable params: 0
Используемая функция расстояния выглядит следующим образом
def distance(a,b):
powers = [(a[i]-b[i])**2 for i in range(len(a))]
return math.sqrt(sum(powers))