Попытка создать пользовательскую функцию потери keras, которая учитывает «расстояние класса» - PullRequest
0 голосов
/ 31 октября 2019

Я пытаюсь написать ResNet, который берет изображение данных и пытается угадать непрерывную переменную из этого события (в данном случае, энергии). Чтобы сделать это, я в некотором роде выдумал определение класса: сеть выводит вектор из 100 «классов», которые на самом деле представляют собой просто равномерно распределенные энергетические бины из 0-1000 единиц энергии (МэВ), поэтому каждый бин имеет ширину10 МэВ. Итак, я хочу написать пользовательскую функцию потерь так, чтобы штраф был более суровым, если сеть выводит высокую вероятность в бине, который дальше от правильного бина энергии, чем если бы бин высокой вероятности был ближе к правильному баку энергии, даже еслимусорная корзина с высокой вероятностью является «неправильной» в обоих случаях. Это первая функция потерь при прохождении, которую я придумал для одного изображения:

Loss

Здесь буква i с шляпой обозначает контейнер истинной энергии. У меня возникли проблемы с реализацией этого в фоновом режиме Keras. В частности, я не могу найти способ реализовать квадрат разницы в корзине, используя только функции keras.backend, особенно когда размер пакета обучения неизвестен. В языке петли / для nupy / for, если бы M было известным размером пакета, а bin - числом энергетических бинов (или классов) в выходных данных сети, я бы записал потерю как:

def customLoss(yTrue,yPred):
    # yTrue and yPred have dimension (M,bins)
    trueBinVec = np.argmax(yTrue,axis=-1) # dimension (M)
    trueBinArr = np.ones((M,bins))
    binsArr = np.ones((M,bins))
    for m in range(M): 
        trueBinArr[m] *= trueBinVec[m]
        binsArr[m] = np.arange(bins)
    binDifTensor = (trueBinsArr - binsArr)**2
    finalTensor = np.multiply((yTrue-yPred)**2,binDifTensor)
    return np.mean(finalTensor,axis=-1) # this would return a tensor of shape (M) containing the loss for each image in the batch

Проблемазаключается в том, что у меня нет доступа к размеру пакета заранее, что затрудняет создание binDifTensor таким образом, чтобы я мог поэлементно производить его с традиционным тензором среднеквадратичной ошибки в бэкэнде keras. Буду признателен за любые предложения о том, как реализовать это с помощью функций keras.backend! Спасибо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...