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

Здесь буква 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! Спасибо