Ответ 1
Model
Вы можете определенно моделировать такую структуру в Keras, уровень слияния, который позволяет комбинировать разные входы. Вот SSCCE, который, мы надеемся, сможет адаптироваться к вашей структуре
import numpy as np
from keras.engine import Merge
from keras.models import Sequential
from keras.layers import Dense
import keras.backend as K
xdim = 4
ydim = 1
gate = Sequential([Dense(2, input_dim=xdim)])
mlp1 = Sequential([Dense(1, input_dim=xdim)])
mlp2 = Sequential([Dense(1, input_dim=xdim)])
def merge_mode(branches):
g, o1, o2 = branches
# I'd have liked to write
# return o1 * K.transpose(g[:, 0]) + o2 * K.transpose(g[:, 1])
# but it doesn't work, and I don't know enough Keras to solve it
return K.transpose(K.transpose(o1) * g[:, 0] + K.transpose(o2) * g[:, 1])
model = Sequential()
model.add(Merge([gate, mlp1, mlp2], output_shape=(ydim,), mode=merge_mode))
model.compile(optimizer='Adam', loss='mean_squared_error')
train_size = 19
nb_inputs = 3 # one input tensor for each branch (g, o1, o2)
x_train = [np.random.random((train_size, xdim)) for _ in range(nb_inputs)]
y_train = np.random.random((train_size, ydim))
model.fit(x_train, y_train)
Пользовательская цель
Вот реализация цели, которую вы описали. Есть несколько математических проблем, чтобы иметь в виду (см. Ниже).
def me_loss(y_true, y_pred):
g = gate.layers[-1].output
o1 = mlp1.layers[-1].output
o2 = mlp2.layers[-1].output
A = g[:, 0] * K.transpose(K.exp(-0.5 * K.square(y_true - o1)))
B = g[:, 1] * K.transpose(K.exp(-0.5 * K.square(y_true - o2)))
return -K.log(K.sum(A+B))
# [...] edit the compile line from above example
model.compile(optimizer='Adam', loss=me_loss)
Некоторая математика
Краткая версия: где-то в вашей модели, я думаю, должно быть хотя бы одно ограничение (возможно, два):
Для любого
x
,sum(g(x)) = 1
Для любого
x
,g0(x) > 0 and g1(x) > 0
# не может быть строго необходимо
Исследование домена
-
Если
o1(x)
иo2(x)
бесконечно далеко отy
:- член exp стремится к +0
-
A -> B -> +-0
в зависимости от знаковg0(x)
иg1(x)
-
cost -> +infinite
илиnan
-
Если
o1(x)
иo2(x)
бесконечно закрыть доy
:- член exp имеет тенденцию к 1
-
A -> g0(x)
иB -> g1(x)
-
cost -> -log(sum(g(x)))
Проблема заключается в том, что log
определяется только на ]0, +inf[
. Это означает, что для того, чтобы цель всегда определялась, должно существовать ограничение где-то обеспечивающее sum(A(x) + B(x)) > 0
для любого x
. Более ограничительная версия этого ограничения будет (g0(x) > 0
и g1(x) > 0
).
Convergence
Еще более важная проблема здесь состоит в том, что эта цель, похоже, не предназначена для сближения к 0. Когда mlp1
и mlp2
начинают правильно предсказать y
(случай 2.), в настоящее время ничего не мешает оптимизатор, чтобы sum(g(x))
имел тенденцию к +infinite
, чтобы сделать loss
тенденцией к -inifinite
.
В идеале нам бы хотелось loss -> 0
, т.е. sum(g(x)) -> 1