Это оказался действительно интересный вопрос - спасибо, что задали его!Во-первых, помните, что вы хотите, чтобы ваши функции потерь были полностью определены как дифференциальные операции, чтобы вы могли распространять их обратно.Это означает, что любая старая произвольная логика не обязательно будет делать.Чтобы переформулировать вашу проблему: вы хотите найти дифференцируемую функцию двух переменных, которая резко увеличивается, когда две переменные принимают значения разных знаков, и медленнее, когда они имеют один и тот же знак.Кроме того, вам нужен некоторый контроль над как резко эти значения увеличиваются относительно друг друга.Таким образом, мы хотим что-то с двумя настраиваемыми константами.Я начал конструировать функцию, которая отвечала бы этим потребностям, но потом вспомнил одну, которую можно найти в любом учебнике по геометрии средней школы: эллиптический параболоид !
Стандартная формулировка не соответствует требованию симметрии соглашения о знаке, поэтому мне пришлось ввести вращение .Сюжет выше является результатом.Обратите внимание, что оно увеличивается более резко, когда знаки не совпадают, и менее резко, когда они согласуются, и что входные константы, управляющие этим поведением, можно настраивать.Код ниже - это все, что было необходимо для определения и построения функции потерь.Я не думаю, что когда-либо использовал геометрическую форму в качестве функции потерь - очень аккуратно.
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
def elliptic_paraboloid_loss(x, y, c_diff_sign, c_same_sign):
# Compute a rotated elliptic parabaloid.
t = np.pi / 4
x_rot = (x * np.cos(t)) + (y * np.sin(t))
y_rot = (x * -np.sin(t)) + (y * np.cos(t))
z = ((x_rot**2) / c_diff_sign) + ((y_rot**2) / c_same_sign)
return(z)
c_diff_sign = 4
c_same_sign = 2
a = np.arange(-5, 5, 0.1)
b = np.arange(-5, 5, 0.1)
loss_map = np.zeros((len(a), len(b)))
for i, a_i in enumerate(a):
for j, b_j in enumerate(b):
loss_map[i, j] = elliptic_paraboloid_loss(a_i, b_j, c_diff_sign, c_same_sign)
fig = plt.figure()
ax = fig.gca(projection='3d')
X, Y = np.meshgrid(a, b)
surf = ax.plot_surface(X, Y, loss_map, cmap=cm.coolwarm,
linewidth=0, antialiased=False)
plt.show()